summaryrefslogtreecommitdiffstats
path: root/src/bdd/cudd
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
commite54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (patch)
treede3ffe87c3e17950351e3b7d97fa18318bd5ea9a /src/bdd/cudd
parent7d7e60f2dc84393cd4c5db22d2eaf7b1fb1a79b2 (diff)
downloadabc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.gz
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.bz2
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.zip
Version abc70930
Diffstat (limited to 'src/bdd/cudd')
-rw-r--r--src/bdd/cudd/cuBdd.make41
-rw-r--r--src/bdd/cudd/cudd.h959
-rw-r--r--src/bdd/cudd/cudd.make42
-rw-r--r--src/bdd/cudd/cuddAPI.c4409
-rw-r--r--src/bdd/cudd/cuddAddAbs.c566
-rw-r--r--src/bdd/cudd/cuddAddApply.c917
-rw-r--r--src/bdd/cudd/cuddAddFind.c283
-rw-r--r--src/bdd/cudd/cuddAddInv.c172
-rw-r--r--src/bdd/cudd/cuddAddIte.c613
-rw-r--r--src/bdd/cudd/cuddAddNeg.c262
-rw-r--r--src/bdd/cudd/cuddAddWalsh.c364
-rw-r--r--src/bdd/cudd/cuddAndAbs.c306
-rw-r--r--src/bdd/cudd/cuddAnneal.c788
-rw-r--r--src/bdd/cudd/cuddApa.c930
-rw-r--r--src/bdd/cudd/cuddApprox.c2192
-rw-r--r--src/bdd/cudd/cuddBddAbs.c689
-rw-r--r--src/bdd/cudd/cuddBddCorr.c481
-rw-r--r--src/bdd/cudd/cuddBddIte.c1254
-rw-r--r--src/bdd/cudd/cuddBridge.c981
-rw-r--r--src/bdd/cudd/cuddCache.c1023
-rw-r--r--src/bdd/cudd/cuddCheck.c851
-rw-r--r--src/bdd/cudd/cuddClip.c531
-rw-r--r--src/bdd/cudd/cuddCof.c300
-rw-r--r--src/bdd/cudd/cuddCompose.c1722
-rw-r--r--src/bdd/cudd/cuddDecomp.c2150
-rw-r--r--src/bdd/cudd/cuddEssent.c279
-rw-r--r--src/bdd/cudd/cuddExact.c1004
-rw-r--r--src/bdd/cudd/cuddExport.c1289
-rw-r--r--src/bdd/cudd/cuddGenCof.c1968
-rw-r--r--src/bdd/cudd/cuddGenetic.c921
-rw-r--r--src/bdd/cudd/cuddGroup.c2142
-rw-r--r--src/bdd/cudd/cuddHarwell.c541
-rw-r--r--src/bdd/cudd/cuddInit.c283
-rw-r--r--src/bdd/cudd/cuddInt.h1133
-rw-r--r--src/bdd/cudd/cuddInteract.c402
-rw-r--r--src/bdd/cudd/cuddLCache.c1428
-rw-r--r--src/bdd/cudd/cuddLevelQ.c533
-rw-r--r--src/bdd/cudd/cuddLinear.c1333
-rw-r--r--src/bdd/cudd/cuddLiteral.c237
-rw-r--r--src/bdd/cudd/cuddMatMult.c680
-rw-r--r--src/bdd/cudd/cuddPriority.c1475
-rw-r--r--src/bdd/cudd/cuddRead.c490
-rw-r--r--src/bdd/cudd/cuddRef.c781
-rw-r--r--src/bdd/cudd/cuddReorder.c2090
-rw-r--r--src/bdd/cudd/cuddSat.c1305
-rw-r--r--src/bdd/cudd/cuddSign.c292
-rw-r--r--src/bdd/cudd/cuddSolve.c339
-rw-r--r--src/bdd/cudd/cuddSplit.c657
-rw-r--r--src/bdd/cudd/cuddSubsetHB.c1311
-rw-r--r--src/bdd/cudd/cuddSubsetSP.c1624
-rw-r--r--src/bdd/cudd/cuddSymmetry.c1668
-rw-r--r--src/bdd/cudd/cuddTable.c3141
-rw-r--r--src/bdd/cudd/cuddUtil.c3633
-rw-r--r--src/bdd/cudd/cuddWindow.c997
-rw-r--r--src/bdd/cudd/cuddZddCount.c324
-rw-r--r--src/bdd/cudd/cuddZddFuncs.c1603
-rw-r--r--src/bdd/cudd/cuddZddGroup.c1317
-rw-r--r--src/bdd/cudd/cuddZddIsop.c885
-rw-r--r--src/bdd/cudd/cuddZddLin.c939
-rw-r--r--src/bdd/cudd/cuddZddMisc.c252
-rw-r--r--src/bdd/cudd/cuddZddPort.c354
-rw-r--r--src/bdd/cudd/cuddZddReord.c1633
-rw-r--r--src/bdd/cudd/cuddZddSetop.c1137
-rw-r--r--src/bdd/cudd/cuddZddSymm.c1677
-rw-r--r--src/bdd/cudd/cuddZddUtil.c1021
-rw-r--r--src/bdd/cudd/module.make61
-rw-r--r--src/bdd/cudd/r7x8.1.mat53
-rw-r--r--src/bdd/cudd/testcudd.c988
68 files changed, 0 insertions, 69046 deletions
diff --git a/src/bdd/cudd/cuBdd.make b/src/bdd/cudd/cuBdd.make
deleted file mode 100644
index b16a27b3..00000000
--- a/src/bdd/cudd/cuBdd.make
+++ /dev/null
@@ -1,41 +0,0 @@
-CSRC_cu += 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
-HEADERS_cu += cudd.h cuddInt.h
-MISC += testcudd.c r7x8.1.mat doc/cudd.ps doc/cuddAllAbs.html doc/cuddAllDet.html \
- doc/cuddExtAbs.html doc/cuddExtDet.html doc/cuddIntro.css \
- doc/cuddIntro.html doc/footnode.html doc/img1.gif doc/img2.gif \
- doc/img3.gif doc/img4.gif doc/img5.gif doc/index.html \
- doc/node1.html doc/node2.html doc/node3.html doc/node4.html \
- doc/node5.html doc/node6.html doc/node7.html doc/node8.html \
- doc/icons/change_begin.gif \
- doc/icons/change_delete.gif \
- doc/icons/change_end.gif \
- doc/icons/contents_motif.gif \
- doc/icons/cross_ref_motif.gif \
- doc/icons/foot_motif.gif \
- doc/icons/image.gif \
- doc/icons/index_motif.gif \
- doc/icons/next_group_motif.gif \
- doc/icons/next_group_motif_gr.gif \
- doc/icons/next_motif.gif \
- doc/icons/next_motif_gr.gif \
- doc/icons/previous_group_motif.gif \
- doc/icons/previous_group_motif_gr.gif \
- doc/icons/previous_motif.gif \
- doc/icons/previous_motif_gr.gif \
- doc/icons/up_motif.gif \
- doc/icons/up_motif_gr.gif
-
-DEPENDENCYFILES = $(CSRC_cu)
diff --git a/src/bdd/cudd/cudd.h b/src/bdd/cudd/cudd.h
deleted file mode 100644
index a31fcdae..00000000
--- a/src/bdd/cudd/cudd.h
+++ /dev/null
@@ -1,959 +0,0 @@
-/**CHeaderFile*****************************************************************
-
- FileName [cudd.h]
-
- PackageName [cudd]
-
- 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.
- ]
-
- 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.]
-
- Revision [$Id: cudd.h,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $]
-
-******************************************************************************/
-
-#ifndef _CUDD
-#define _CUDD
-
-/*---------------------------------------------------------------------------*/
-/* Nested includes */
-/*---------------------------------------------------------------------------*/
-
-#include "mtr.h"
-#include "epd.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define CUDD_VERSION "2.3.1"
-
-#ifndef SIZEOF_VOID_P
-#define SIZEOF_VOID_P 4
-#endif
-#ifndef SIZEOF_INT
-#define SIZEOF_INT 4
-#endif
-#ifndef SIZEOF_LONG
-#define SIZEOF_LONG 4
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#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 */
-
-/* Constants for residue functions. */
-#define CUDD_RESIDUE_DEFAULT 0
-#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)
-#else
-#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
-
-/* 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
-** 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"
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/**Enum************************************************************************
-
- Synopsis [Type of reordering algorithm.]
-
- Description [Type of reordering algorithm.]
-
-******************************************************************************/
-typedef enum {
- CUDD_REORDER_SAME,
- CUDD_REORDER_NONE,
- CUDD_REORDER_RANDOM,
- CUDD_REORDER_RANDOM_PIVOT,
- CUDD_REORDER_SIFT,
- CUDD_REORDER_SIFT_CONVERGE,
- CUDD_REORDER_SYMM_SIFT,
- CUDD_REORDER_SYMM_SIFT_CONV,
- CUDD_REORDER_WINDOW2,
- CUDD_REORDER_WINDOW3,
- CUDD_REORDER_WINDOW4,
- CUDD_REORDER_WINDOW2_CONV,
- CUDD_REORDER_WINDOW3_CONV,
- CUDD_REORDER_WINDOW4_CONV,
- CUDD_REORDER_GROUP_SIFT,
- CUDD_REORDER_GROUP_SIFT_CONV,
- CUDD_REORDER_ANNEALING,
- CUDD_REORDER_GENETIC,
- CUDD_REORDER_LINEAR,
- CUDD_REORDER_LINEAR_CONVERGE,
- CUDD_REORDER_LAZY_SIFT,
- CUDD_REORDER_EXACT
-} Cudd_ReorderingType;
-
-
-/**Enum************************************************************************
-
- Synopsis [Type of aggregation methods.]
-
- Description [Type of aggregation methods.]
-
-******************************************************************************/
-typedef enum {
- CUDD_NO_CHECK,
- CUDD_GROUP_CHECK,
- CUDD_GROUP_CHECK2,
- CUDD_GROUP_CHECK3,
- CUDD_GROUP_CHECK4,
- CUDD_GROUP_CHECK5,
- CUDD_GROUP_CHECK6,
- CUDD_GROUP_CHECK7,
- CUDD_GROUP_CHECK8,
- CUDD_GROUP_CHECK9
-} Cudd_AggregationType;
-
-
-/**Enum************************************************************************
-
- Synopsis [Type of hooks.]
-
- Description [Type of hooks.]
-
-******************************************************************************/
-typedef enum {
- CUDD_PRE_GC_HOOK,
- CUDD_POST_GC_HOOK,
- CUDD_PRE_REORDERING_HOOK,
- CUDD_POST_REORDERING_HOOK
-} Cudd_HookType;
-
-
-/**Enum************************************************************************
-
- Synopsis [Type of error codes.]
-
- Description [Type of error codes.]
-
-******************************************************************************/
-typedef enum {
- CUDD_NO_ERROR,
- CUDD_MEMORY_OUT,
- CUDD_TOO_MANY_NODES,
- CUDD_MAX_MEM_EXCEEDED,
- CUDD_INVALID_ARG,
- CUDD_INTERNAL_ERROR
-} Cudd_ErrorType;
-
-
-/**Enum************************************************************************
-
- Synopsis [Group type for lazy sifting.]
-
- Description [Group type for lazy sifting.]
-
-******************************************************************************/
-typedef enum {
- CUDD_LAZY_NONE,
- CUDD_LAZY_SOFT_GROUP,
- CUDD_LAZY_HARD_GROUP,
- CUDD_LAZY_UNGROUP
-} Cudd_LazyGroupType;
-
-
-/**Enum************************************************************************
-
- Synopsis [Variable type.]
-
- Description [Variable type. Currently used only in lazy sifting.]
-
-******************************************************************************/
-typedef enum {
- CUDD_VAR_PRIMARY_INPUT,
- CUDD_VAR_PRESENT_STATE,
- CUDD_VAR_NEXT_STATE
-} Cudd_VariableType;
-
-
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
-typedef unsigned int DdHalfWord;
-#else
-typedef unsigned short DdHalfWord;
-#endif
-
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
-
-typedef struct DdNode DdNode;
-
-typedef struct DdChildren {
- struct DdNode *T;
- struct DdNode *E;
-} 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 */
- union {
- CUDD_VALUE_TYPE value; /* for constant nodes */
- DdChildren kids; /* for internal nodes */
- } type;
-};
-
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-
-typedef struct DdManager DdManager;
-
-typedef struct DdGen DdGen;
-
-/* These typedefs for arbitrary precision arithmetic should agree with
-** the corresponding constant definitions above. */
-typedef unsigned short int DdApaDigit;
-typedef unsigned long int DdApaDoubleDigit;
-typedef DdApaDigit * DdApaNumber;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns 1 if the node is a constant node.]
-
- Description [Returns 1 if the node is a constant node (rather than an
- internal node). All constant nodes have the same index
- (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either
- regular or complemented.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-#define Cudd_IsConstant(node) ((Cudd_Regular(node))->index == CUDD_CONST_INDEX)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Complements a DD.]
-
- Description [Complements a DD by flipping the complement attribute of
- the pointer (the least significant bit).]
-
- SideEffects [none]
-
- SeeAlso [Cudd_NotCond]
-
-******************************************************************************/
-#define Cudd_Not(node) ((DdNode *)((long)(node) ^ 01))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Complements a DD if a condition is true.]
-
- Description [Complements a DD if condition c is true; c should be
- either 0 or 1, because it is used directly (for efficiency). If in
- doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".]
-
- SideEffects [none]
-
- SeeAlso [Cudd_Not]
-
-******************************************************************************/
-#define Cudd_NotCond(node,c) ((DdNode *)((long)(node) ^ (c)))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the regular version of a pointer.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [Cudd_Complement Cudd_IsComplement]
-
-******************************************************************************/
-#define Cudd_Regular(node) ((DdNode *)((unsigned long)(node) & ~01))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the complemented version of a pointer.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [Cudd_Regular Cudd_IsComplement]
-
-******************************************************************************/
-#define Cudd_Complement(node) ((DdNode *)((unsigned long)(node) | 01))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns 1 if a pointer is complemented.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [Cudd_Regular Cudd_Complement]
-
-******************************************************************************/
-#define Cudd_IsComplement(node) ((int) ((long) (node) & 01))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the then child of an internal node.]
-
- Description [Returns the then child of an internal node. If
- <code>node</code> is a constant node, the result is unpredictable.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_E Cudd_V]
-
-******************************************************************************/
-#define Cudd_T(node) ((Cudd_Regular(node))->type.kids.T)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the else child of an internal node.]
-
- Description [Returns the else child of an internal node. If
- <code>node</code> is a constant node, the result is unpredictable.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_T Cudd_V]
-
-******************************************************************************/
-#define Cudd_E(node) ((Cudd_Regular(node))->type.kids.E)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the value of a constant node.]
-
- Description [Returns the value of a constant node. If
- <code>node</code> is an internal node, the result is unpredictable.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_T Cudd_E]
-
-******************************************************************************/
-#define Cudd_V(node) ((Cudd_Regular(node))->type.value)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the current position in the order of variable
- index.]
-
- Description [Returns the current position in the order of variable
- index. This macro is obsolete and is kept for compatibility. New
- applications should use Cudd_ReadPerm instead.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ReadPerm]
-
-******************************************************************************/
-#define Cudd_ReadIndex(dd,index) (Cudd_ReadPerm(dd,index))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Iterates over the cubes of a decision diagram.]
-
- Description [Iterates over the cubes of a decision diagram f.
- <ul>
- <li> DdManager *manager;
- <li> DdNode *f;
- <li> DdGen *gen;
- <li> int *cube;
- <li> CUDD_VALUE_TYPE value;
- </ul>
- Cudd_ForeachCube allocates and frees the generator. Therefore the
- application should not try to do that. Also, the cube is freed at the
- end of Cudd_ForeachCube and hence is not available outside of the loop.<p>
- CAUTION: It is assumed that dynamic reordering will not occur while
- there are open generators. It is the user's responsibility to make sure
- that dynamic reordering does not occur. As long as new nodes are not created
- during generation, and dynamic reordering is not called explicitly,
- dynamic reordering will not occur. Alternatively, it is sufficient to
- disable dynamic reordering. It is a mistake to dispose of a diagram
- on which generation is ongoing.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree
- Cudd_IsGenEmpty Cudd_AutodynDisable]
-
-******************************************************************************/
-#define Cudd_ForeachCube(manager, f, gen, cube, value)\
- for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\
- Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
- (void) Cudd_NextCube(gen, &cube, &value))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Iterates over the nodes of a decision diagram.]
-
- Description [Iterates over the nodes of a decision diagram f.
- <ul>
- <li> DdManager *manager;
- <li> DdNode *f;
- <li> DdGen *gen;
- <li> DdNode *node;
- </ul>
- The nodes are returned in a seemingly random order.
- Cudd_ForeachNode allocates and frees the generator. Therefore the
- application should not try to do that.<p>
- CAUTION: It is assumed that dynamic reordering will not occur while
- there are open generators. It is the user's responsibility to make sure
- that dynamic reordering does not occur. As long as new nodes are not created
- during generation, and dynamic reordering is not called explicitly,
- dynamic reordering will not occur. Alternatively, it is sufficient to
- disable dynamic reordering. It is a mistake to dispose of a diagram
- on which generation is ongoing.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree
- Cudd_IsGenEmpty Cudd_AutodynDisable]
-
-******************************************************************************/
-#define Cudd_ForeachNode(manager, f, gen, node)\
- for((gen) = Cudd_FirstNode(manager, f, &node);\
- Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
- (void) Cudd_NextNode(gen, &node))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Iterates over the paths of a ZDD.]
-
- Description [Iterates over the paths of a ZDD f.
- <ul>
- <li> DdManager *manager;
- <li> DdNode *f;
- <li> DdGen *gen;
- <li> int *path;
- </ul>
- Cudd_zddForeachPath allocates and frees the generator. Therefore the
- application should not try to do that. Also, the path is freed at the
- end of Cudd_zddForeachPath and hence is not available outside of the loop.<p>
- CAUTION: It is assumed that dynamic reordering will not occur while
- there are open generators. It is the user's responsibility to make sure
- that dynamic reordering does not occur. As long as new nodes are not created
- during generation, and dynamic reordering is not called explicitly,
- dynamic reordering will not occur. Alternatively, it is sufficient to
- disable dynamic reordering. It is a mistake to dispose of a diagram
- on which generation is ongoing.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree
- Cudd_IsGenEmpty Cudd_AutodynDisable]
-
-******************************************************************************/
-#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
-# define EXTERN extern "C"
-# else
-# define EXTERN extern
-# endif
-#endif
-#ifndef ARGS
-# if defined(__STDC__) || defined(__cplusplus)
-# define ARGS(protos) protos /* ANSI C */
-# else /* !(__STDC__ || __cplusplus) */
-# define ARGS(protos) () /* K&R C */
-# endif /* !(__STDC__ || __cplusplus) */
-#endif
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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 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));
-
-/**AutomaticEnd***************************************************************/
-
-#endif /* _CUDD */
diff --git a/src/bdd/cudd/cudd.make b/src/bdd/cudd/cudd.make
deleted file mode 100644
index 7cb342a2..00000000
--- a/src/bdd/cudd/cudd.make
+++ /dev/null
@@ -1,42 +0,0 @@
-CSRC += 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
-
-HEADERS += cudd.h cuddInt.h
-MISC += testcudd.c r7x8.1.mat doc/cudd.ps doc/cuddAllAbs.html doc/cuddAllDet.html \
- doc/cuddExtAbs.html doc/cuddExtDet.html doc/cuddIntro.css \
- doc/cuddIntro.html doc/footnode.html doc/img1.gif doc/img2.gif \
- doc/img3.gif doc/img4.gif doc/img5.gif doc/index.html \
- doc/node1.html doc/node2.html doc/node3.html doc/node4.html \
- doc/node5.html doc/node6.html doc/node7.html doc/node8.html \
- doc/icons/change_begin.gif \
- doc/icons/change_delete.gif \
- doc/icons/change_end.gif \
- doc/icons/contents_motif.gif \
- doc/icons/cross_ref_motif.gif \
- doc/icons/foot_motif.gif \
- doc/icons/image.gif \
- doc/icons/index_motif.gif \
- doc/icons/next_group_motif.gif \
- doc/icons/next_group_motif_gr.gif \
- doc/icons/next_motif.gif \
- doc/icons/next_motif_gr.gif \
- doc/icons/previous_group_motif.gif \
- doc/icons/previous_group_motif_gr.gif \
- doc/icons/previous_motif.gif \
- doc/icons/previous_motif_gr.gif \
- doc/icons/up_motif.gif \
- doc/icons/up_motif_gr.gif
-
-DEPENDENCYFILES = $(CSRC)
diff --git a/src/bdd/cudd/cuddAPI.c b/src/bdd/cudd/cuddAPI.c
deleted file mode 100644
index a16b82cf..00000000
--- a/src/bdd/cudd/cuddAPI.c
+++ /dev/null
@@ -1,4409 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAPI.c]
-
- PackageName [cudd]
-
- 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()
- <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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Returns a new ADD variable.]
-
- Description [Creates a new ADD variable. The new variable has an
- index equal to the largest previous index plus 1. Returns a
- pointer to the new variable if successful; NULL otherwise.
- An ADD variable differs from a BDD variable because it points to the
- arithmetic zero, instead of having a complement pointer to 1. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst
- Cudd_addNewVarAtLevel]
-
-******************************************************************************/
-DdNode *
-Cudd_addNewVar(
- DdManager * dd)
-{
- DdNode *res;
-
- 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));
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_addNewVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns a new ADD variable at a specified level.]
-
- Description [Creates a new ADD variable. The new variable has an
- index equal to the largest previous index plus 1 and is positioned at
- the specified level in the order. Returns a pointer to the new
- variable if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel]
-
-******************************************************************************/
-DdNode *
-Cudd_addNewVarAtLevel(
- DdManager * dd,
- int level)
-{
- DdNode *res;
-
- if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
- 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));
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_addNewVarAtLevel */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns a new BDD variable.]
-
- Description [Creates a new BDD variable. The new variable has an
- index equal to the largest previous index plus 1. Returns a
- pointer to the new variable if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
-
-******************************************************************************/
-DdNode *
-Cudd_bddNewVar(
- DdManager * dd)
-{
- DdNode *res;
-
- if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
- res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one));
-
- return(res);
-
-} /* end of Cudd_bddNewVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns a new BDD variable at a specified level.]
-
- Description [Creates a new BDD variable. The new variable has an
- index equal to the largest previous index plus 1 and is positioned at
- the specified level in the order. Returns a pointer to the new
- variable if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel]
-
-******************************************************************************/
-DdNode *
-Cudd_bddNewVarAtLevel(
- DdManager * dd,
- int level)
-{
- DdNode *res;
-
- if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
- if (level >= dd->size) return(Cudd_bddIthVar(dd,level));
- if (!cuddInsertSubtables(dd,1,level)) return(NULL);
- res = dd->vars[dd->size - 1];
-
- return(res);
-
-} /* end of Cudd_bddNewVarAtLevel */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the ADD variable with index i.]
-
- Description [Retrieves the ADD variable with index i if it already
- exists, or creates a new ADD variable. Returns a pointer to the
- variable if successful; NULL otherwise. An ADD variable differs from
- a BDD variable because it points to the arithmetic zero, instead of
- having a complement pointer to 1. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst
- Cudd_addNewVarAtLevel]
-
-******************************************************************************/
-DdNode *
-Cudd_addIthVar(
- DdManager * dd,
- int i)
-{
- DdNode *res;
-
- if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
- do {
- dd->reordered = 0;
- res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd));
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_addIthVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the BDD variable with index i.]
-
- Description [Retrieves the BDD variable with index i if it already
- exists, or creates a new BDD variable. Returns a pointer to the
- variable if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel
- Cudd_ReadVars]
-
-******************************************************************************/
-DdNode *
-Cudd_bddIthVar(
- DdManager * dd,
- int i)
-{
- DdNode *res;
-
- if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
- if (i < dd->size) {
- res = dd->vars[i];
- } else {
- res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
- }
-
- return(res);
-
-} /* end of Cudd_bddIthVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the ZDD variable with index i.]
-
- Description [Retrieves the ZDD variable with index i if it already
- exists, or creates a new ZDD variable. Returns a pointer to the
- variable if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIthVar Cudd_addIthVar]
-
-******************************************************************************/
-DdNode *
-Cudd_zddIthVar(
- DdManager * dd,
- int i)
-{
- DdNode *res;
- DdNode *zvar;
- DdNode *lower;
- int j;
-
- if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
-
- /* The i-th variable function has the following structure:
- ** at the level corresponding to index i there is a node whose "then"
- ** child points to the universe, and whose "else" child points to zero.
- ** Above that level there are nodes with identical children.
- */
-
- /* 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));
- } while (dd->reordered == 1);
-
- if (zvar == 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) {
- Cudd_RecursiveDerefZdd(dd,zvar);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDerefZdd(dd,zvar);
- zvar = res;
- }
- cuddDeref(zvar);
- return(zvar);
-
-} /* end of Cudd_zddIthVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Creates one or more ZDD variables for each BDD variable.]
-
- Description [Creates one or more ZDD variables for each BDD
- variable. If some ZDD variables already exist, only the missing
- variables are created. Parameter multiplicity allows the caller to
- control how many variables are created for each BDD variable in
- existence. For instance, if ZDDs are used to represent covers, two
- ZDD variables are required for each BDD variable. The order of the
- BDD variables is transferred to the ZDD variables. If a variable
- group tree exists for the BDD variables, a corresponding ZDD
- variable group tree is created by expanding the BDD variable
- tree. In any case, the ZDD variables derived from the same BDD
- variable are merged in a ZDD variable group. If a ZDD variable group
- tree exists, it is freed. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
-
-******************************************************************************/
-int
-Cudd_zddVarsFromBddVars(
- DdManager * dd /* DD manager */,
- int multiplicity /* how many ZDD variables are created for each BDD variable */)
-{
- int res;
- int i, j;
- int allnew;
- int *permutation;
-
- 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);
- }
- /* 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->sizeZ; i++) {
- dd->univ[i]->index = dd->invpermZ[i];
- }
- } else {
- permutation = 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;
- }
- }
- for (i = dd->size * multiplicity; i < dd->sizeZ; i++) {
- permutation[i] = i;
- }
- res = Cudd_zddShuffleHeap(dd, permutation);
- FREE(permutation);
- if (res == 0) return(0);
- }
- /* Copy and expand the variable group tree if it exists. */
- if (dd->treeZ != NULL) {
- Cudd_FreeZddTree(dd);
- }
- if (dd->tree != NULL) {
- 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];
- }
- /* Create groups for the ZDD variables derived from the same BDD variable.
- */
- if (multiplicity > 1) {
- char *vmask, *lmask;
-
- vmask = ALLOC(char, dd->size);
- if (vmask == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- lmask = 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);
- FREE(vmask);
- FREE(lmask);
- if (res == 0) return(0);
- }
- return(1);
-
-} /* end of Cudd_zddVarsFromBddVars */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the ADD for constant c.]
-
- Description [Retrieves the ADD for constant c if it already
- exists, or creates a new ADD. Returns a pointer to the
- ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNewVar Cudd_addIthVar]
-
-******************************************************************************/
-DdNode *
-Cudd_addConst(
- DdManager * dd,
- CUDD_VALUE_TYPE c)
-{
- return(cuddUniqueConst(dd,c));
-
-} /* end of Cudd_addConst */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if a DD node is not constant.]
-
- Description [Returns 1 if a DD node is not constant. This function is
- useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant,
- Cudd_addEvalConst. These results may be a special value signifying
- non-constant. In the other cases the macro Cudd_IsConstant can be used.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant
- Cudd_addEvalConst]
-
-******************************************************************************/
-int
-Cudd_IsNonConstant(
- DdNode *f)
-{
- return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f));
-
-} /* end of Cudd_IsNonConstant */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.]
-
- Description [Enables automatic dynamic reordering of BDDs and
- ADDs. Parameter method is used to determine the method used for
- reordering. If CUDD_REORDER_SAME is passed, the method is
- unchanged.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus
- Cudd_AutodynEnableZdd]
-
-******************************************************************************/
-void
-Cudd_AutodynEnable(
- DdManager * unique,
- Cudd_ReorderingType method)
-{
- unique->autoDyn = 1;
- if (method != CUDD_REORDER_SAME) {
- unique->autoMethod = method;
- }
-#ifndef DD_NO_DEATH_ROW
- /* If reordering is enabled, using the death row causes too many
- ** invocations. Hence, we shrink the death row to just one entry.
- */
- cuddClearDeathRow(unique);
- unique->deathRowDepth = 1;
- unique->deadMask = unique->deathRowDepth - 1;
- if ((unsigned) unique->nextDead > unique->deadMask) {
- unique->nextDead = 0;
- }
- unique->deathRow = REALLOC(DdNodePtr, unique->deathRow,
- unique->deathRowDepth);
-#endif
- return;
-
-} /* end of Cudd_AutodynEnable */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables automatic dynamic reordering.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus
- Cudd_AutodynDisableZdd]
-
-******************************************************************************/
-void
-Cudd_AutodynDisable(
- DdManager * unique)
-{
- unique->autoDyn = 0;
- return;
-
-} /* end of Cudd_AutodynDisable */
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the status of automatic dynamic reordering of BDDs
- and ADDs.]
-
- Description [Reports the status of automatic dynamic reordering of
- BDDs and ADDs. Parameter method is set to the reordering method
- currently selected. Returns 1 if automatic reordering is enabled; 0
- otherwise.]
-
- SideEffects [Parameter method is set to the reordering method currently
- selected.]
-
- SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable
- Cudd_ReorderingStatusZdd]
-
-******************************************************************************/
-int
-Cudd_ReorderingStatus(
- DdManager * unique,
- Cudd_ReorderingType * method)
-{
- *method = unique->autoMethod;
- return(unique->autoDyn);
-
-} /* end of Cudd_ReorderingStatus */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables automatic dynamic reordering of ZDDs.]
-
- Description [Enables automatic dynamic reordering of ZDDs. Parameter
- method is used to determine the method used for reordering ZDDs. If
- CUDD_REORDER_SAME is passed, the method is unchanged.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd
- Cudd_AutodynEnable]
-
-******************************************************************************/
-void
-Cudd_AutodynEnableZdd(
- DdManager * unique,
- Cudd_ReorderingType method)
-{
- unique->autoDynZ = 1;
- if (method != CUDD_REORDER_SAME) {
- unique->autoMethodZ = method;
- }
- return;
-
-} /* end of Cudd_AutodynEnableZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables automatic dynamic reordering of ZDDs.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd
- Cudd_AutodynDisable]
-
-******************************************************************************/
-void
-Cudd_AutodynDisableZdd(
- DdManager * unique)
-{
- unique->autoDynZ = 0;
- return;
-
-} /* end of Cudd_AutodynDisableZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the status of automatic dynamic reordering of ZDDs.]
-
- Description [Reports the status of automatic dynamic reordering of
- ZDDs. Parameter method is set to the ZDD reordering method currently
- selected. Returns 1 if automatic reordering is enabled; 0
- otherwise.]
-
- SideEffects [Parameter method is set to the ZDD reordering method currently
- selected.]
-
- SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd
- Cudd_ReorderingStatus]
-
-******************************************************************************/
-int
-Cudd_ReorderingStatusZdd(
- DdManager * unique,
- Cudd_ReorderingType * method)
-{
- *method = unique->autoMethodZ;
- return(unique->autoDynZ);
-
-} /* end of Cudd_ReorderingStatusZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether the realignment of ZDD order to BDD order is
- enabled.]
-
- Description [Returns 1 if the realignment of ZDD order to BDD order is
- enabled; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable
- Cudd_bddRealignEnable Cudd_bddRealignDisable]
-
-******************************************************************************/
-int
-Cudd_zddRealignmentEnabled(
- DdManager * unique)
-{
- return(unique->realign);
-
-} /* end of Cudd_zddRealignmentEnabled */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables realignment of ZDD order to BDD order.]
-
- Description [Enables realignment of the ZDD variable order to the
- BDD variable order after the BDDs and ADDs have been reordered. The
- number of ZDD variables must be a multiple of the number of BDD
- variables for realignment to make sense. If this condition is not met,
- Cudd_ReduceHeap will return 0. Let <code>M</code> be the
- ratio of the two numbers. For the purpose of realignment, the ZDD
- variables from <code>M*i</code> to <code>(M+1)*i-1</code> are
- reagarded as corresponding to BDD variable <code>i</code>. Realignment
- is initially disabled.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable
- Cudd_zddRealignmentEnabled Cudd_bddRealignDisable
- Cudd_bddRealignmentEnabled]
-
-******************************************************************************/
-void
-Cudd_zddRealignEnable(
- DdManager * unique)
-{
- unique->realign = 1;
- return;
-
-} /* end of Cudd_zddRealignEnable */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables realignment of ZDD order to BDD order.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled
- Cudd_bddRealignEnable Cudd_bddRealignmentEnabled]
-
-******************************************************************************/
-void
-Cudd_zddRealignDisable(
- DdManager * unique)
-{
- unique->realign = 0;
- return;
-
-} /* end of Cudd_zddRealignDisable */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether the realignment of BDD order to ZDD order is
- enabled.]
-
- Description [Returns 1 if the realignment of BDD order to ZDD order is
- enabled; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable
- Cudd_zddRealignEnable Cudd_zddRealignDisable]
-
-******************************************************************************/
-int
-Cudd_bddRealignmentEnabled(
- DdManager * unique)
-{
- return(unique->realignZ);
-
-} /* end of Cudd_bddRealignmentEnabled */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables realignment of BDD order to ZDD order.]
-
- Description [Enables realignment of the BDD variable order to the
- ZDD variable order after the ZDDs have been reordered. The
- number of ZDD variables must be a multiple of the number of BDD
- variables for realignment to make sense. If this condition is not met,
- Cudd_zddReduceHeap will return 0. Let <code>M</code> be the
- ratio of the two numbers. For the purpose of realignment, the ZDD
- variables from <code>M*i</code> to <code>(M+1)*i-1</code> are
- reagarded as corresponding to BDD variable <code>i</code>. Realignment
- is initially disabled.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable
- Cudd_bddRealignmentEnabled Cudd_zddRealignDisable
- Cudd_zddRealignmentEnabled]
-
-******************************************************************************/
-void
-Cudd_bddRealignEnable(
- DdManager * unique)
-{
- unique->realignZ = 1;
- return;
-
-} /* end of Cudd_bddRealignEnable */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables realignment of ZDD order to BDD order.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled
- Cudd_zddRealignEnable Cudd_zddRealignmentEnabled]
-
-******************************************************************************/
-void
-Cudd_bddRealignDisable(
- DdManager * unique)
-{
- unique->realignZ = 0;
- return;
-
-} /* end of Cudd_bddRealignDisable */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the one constant of the manager.]
-
- Description [Returns the one constant of the manager. The one
- constant is common to ADDs and BDDs.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadOne(
- DdManager * dd)
-{
- return(dd->one);
-
-} /* end of Cudd_ReadOne */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the ZDD for the constant 1 function.]
-
- Description [Returns the ZDD for the constant 1 function.
- The representation of the constant 1 function as a ZDD depends on
- how many variables it (nominally) depends on. The index of the
- topmost variable in the support is given as argument <code>i</code>.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadOne]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadZddOne(
- DdManager * dd,
- int i)
-{
- if (i < 0)
- return(NULL);
- return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd));
-
-} /* end of Cudd_ReadZddOne */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the zero constant of the manager.]
-
- Description [Returns the zero constant of the manager. The zero
- constant is the arithmetic zero, rather than the logic zero. The
- latter is the complement of the one constant.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadZero(
- DdManager * dd)
-{
- return(DD_ZERO(dd));
-
-} /* end of Cudd_ReadZero */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the logic zero constant of the manager.]
-
- Description [Returns the zero constant of the manager. The logic zero
- constant is the complement of the one constant, and is distinct from
- the arithmetic zero.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadOne Cudd_ReadZero]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadLogicZero(
- DdManager * dd)
-{
- return(Cudd_Not(DD_ONE(dd)));
-
-} /* end of Cudd_ReadLogicZero */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the plus-infinity constant from the manager.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadPlusInfinity(
- DdManager * dd)
-{
- return(dd->plusinfinity);
-
-} /* end of Cudd_ReadPlusInfinity */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the minus-infinity constant from the manager.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadMinusInfinity(
- DdManager * dd)
-{
- return(dd->minusinfinity);
-
-} /* end of Cudd_ReadMinusInfinity */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the background constant of the manager.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadBackground(
- DdManager * dd)
-{
- return(dd->background);
-
-} /* end of Cudd_ReadBackground */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the background constant of the manager.]
-
- Description [Sets the background constant of the manager. It assumes
- that the DdNode pointer bck is already referenced.]
-
- SideEffects [None]
-
-******************************************************************************/
-void
-Cudd_SetBackground(
- DdManager * dd,
- DdNode * bck)
-{
- dd->background = bck;
-
-} /* end of Cudd_SetBackground */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the number of slots in the cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadCacheUsedSlots]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadCacheSlots(
- DdManager * dd)
-{
- return(dd->cacheSlots);
-
-} /* end of Cudd_ReadCacheSlots */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the fraction of used slots in the cache.]
-
- Description [Reads the fraction of used slots in the cache. The unused
- slots are those in which no valid data is stored. Garbage collection,
- variable reordering, and cache resizing may cause used slots to become
- unused.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadCacheSlots]
-
-******************************************************************************/
-double
-Cudd_ReadCacheUsedSlots(
- DdManager * dd)
-{
- unsigned long used = 0;
- int slots = dd->cacheSlots;
- DdCache *cache = dd->cache;
- int i;
-
- for (i = 0; i < slots; i++) {
- used += cache[i].h != 0;
- }
-
- return((double)used / (double) dd->cacheSlots);
-
-} /* end of Cudd_ReadCacheUsedSlots */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of cache look-ups.]
-
- Description [Returns the number of cache look-ups.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadCacheHits]
-
-******************************************************************************/
-double
-Cudd_ReadCacheLookUps(
- DdManager * dd)
-{
- return(dd->cacheHits + dd->cacheMisses +
- dd->totCachehits + dd->totCacheMisses);
-
-} /* end of Cudd_ReadCacheLookUps */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of cache hits.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadCacheLookUps]
-
-******************************************************************************/
-double
-Cudd_ReadCacheHits(
- DdManager * dd)
-{
- return(dd->cacheHits + dd->totCachehits);
-
-} /* end of Cudd_ReadCacheHits */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of recursive calls.]
-
- Description [Returns the number of recursive calls if the package is
- compiled with DD_COUNT defined.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-double
-Cudd_ReadRecursiveCalls(
- DdManager * dd)
-{
-#ifdef DD_COUNT
- return(dd->recursiveCalls);
-#else
- return(-1.0);
-#endif
-
-} /* end of Cudd_ReadRecursiveCalls */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the hit rate that causes resizinig of the computed
- table.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetMinHit]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadMinHit(
- DdManager * dd)
-{
- /* Internally, the package manipulates the ratio of hits to
- ** misses instead of the ratio of hits to accesses. */
- return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit)));
-
-} /* end of Cudd_ReadMinHit */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the hit rate that causes resizinig of the computed
- table.]
-
- Description [Sets the minHit parameter of the manager. This
- parameter controls the resizing of the computed table. If the hit
- rate is larger than the specified value, and the cache is not
- already too large, then its size is doubled.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMinHit]
-
-******************************************************************************/
-void
-Cudd_SetMinHit(
- DdManager * dd,
- unsigned int hr)
-{
- /* Internally, the package manipulates the ratio of hits to
- ** misses instead of the ratio of hits to accesses. */
- dd->minHit = (double) hr / (100.0 - (double) hr);
-
-} /* end of Cudd_SetMinHit */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the looseUpTo parameter of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadLooseUpTo(
- DdManager * dd)
-{
- return(dd->looseUpTo);
-
-} /* end of Cudd_ReadLooseUpTo */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the looseUpTo parameter of the manager.]
-
- Description [Sets the looseUpTo parameter of the manager. This
- parameter of the manager controls the threshold beyond which no fast
- growth of the unique table is allowed. The threshold is given as a
- number of slots. If the value passed to this function is 0, the
- function determines a suitable value based on the available memory.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit]
-
-******************************************************************************/
-void
-Cudd_SetLooseUpTo(
- DdManager * dd,
- unsigned int lut)
-{
- if (lut == 0) {
- long datalimit = getSoftDataLimit();
- lut = (unsigned int) (datalimit / (sizeof(DdNode) *
- DD_MAX_LOOSE_FRACTION));
- }
- dd->looseUpTo = lut;
-
-} /* end of Cudd_SetLooseUpTo */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the soft limit for the cache size.]
-
- Description [Returns the soft limit for the cache size. The soft limit]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxCache]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadMaxCache(
- DdManager * dd)
-{
- return(2 * dd->cacheSlots + dd->cacheSlack);
-
-} /* end of Cudd_ReadMaxCache */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the maxCacheHard parameter of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadMaxCacheHard(
- DdManager * dd)
-{
- return(dd->maxCacheHard);
-
-} /* end of Cudd_ReadMaxCache */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the maxCacheHard parameter of the manager.]
-
- Description [Sets the maxCacheHard parameter of the manager. The
- cache cannot grow larger than maxCacheHard entries. This parameter
- allows an application to control the trade-off of memory versus
- speed. If the value passed to this function is 0, the function
- determines a suitable maximum cache size based on the available memory.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache]
-
-******************************************************************************/
-void
-Cudd_SetMaxCacheHard(
- DdManager * dd,
- unsigned int mc)
-{
- if (mc == 0) {
- long datalimit = getSoftDataLimit();
- mc = (unsigned int) (datalimit / (sizeof(DdCache) *
- DD_MAX_CACHE_FRACTION));
- }
- dd->maxCacheHard = mc;
-
-} /* end of Cudd_SetMaxCacheHard */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of BDD variables in existance.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadZddSize]
-
-******************************************************************************/
-int
-Cudd_ReadSize(
- DdManager * dd)
-{
- return(dd->size);
-
-} /* end of Cudd_ReadSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of ZDD variables in existance.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadSize]
-
-******************************************************************************/
-int
-Cudd_ReadZddSize(
- DdManager * dd)
-{
- return(dd->sizeZ);
-
-} /* end of Cudd_ReadZddSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the total number of slots of the unique table.]
-
- Description [Returns the total number of slots of the unique table.
- This number ismainly for diagnostic purposes.]
-
- SideEffects [None]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadSlots(
- DdManager * dd)
-{
- return(dd->slots);
-
-} /* end of Cudd_ReadSlots */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the fraction of used slots in the unique table.]
-
- Description [Reads the fraction of used slots in the unique
- table. The unused slots are those in which no valid data is
- stored. Garbage collection, variable reordering, and subtable
- resizing may cause used slots to become unused.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadSlots]
-
-******************************************************************************/
-double
-Cudd_ReadUsedSlots(
- DdManager * dd)
-{
- unsigned long used = 0;
- int i, j;
- int size = dd->size;
- DdNodePtr *nodelist;
- DdSubtable *subtable;
- DdNode *node;
- DdNode *sentinel = &(dd->sentinel);
-
- /* 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++;
- }
- }
- }
-
- /* 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++;
- }
- }
- }
-
- /* Constant table. */
- subtable = &(dd->constants);
- nodelist = subtable->nodelist;
- for (j = 0; (unsigned) j < subtable->slots; j++) {
- node = nodelist[j];
- if (node != NULL) {
- used++;
- }
- }
-
- return((double)used / (double) dd->slots);
-
-} /* end of Cudd_ReadUsedSlots */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the expected fraction of used slots in the unique
- table.]
-
- Description [Computes the fraction of slots in the unique table that
- should be in use. This expected value is based on the assumption
- that the hash function distributes the keys randomly; it can be
- compared with the result of Cudd_ReadUsedSlots to monitor the
- performance of the unique table hash function.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots]
-
-******************************************************************************/
-double
-Cudd_ExpectedUsedSlots(
- DdManager * dd)
-{
- int i;
- int size = dd->size;
- DdSubtable *subtable;
- double empty = 0.0;
-
- /* 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
- ** 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);
- }
-
- /* 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);
- }
-
- /* Constant table. */
- subtable = &(dd->constants);
- empty += (double) subtable->slots *
- exp(-(double) subtable->keys / (double) subtable->slots);
-
- return(1.0 - empty / (double) dd->slots);
-
-} /* end of Cudd_ExpectedUsedSlots */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of nodes in the unique table.]
-
- Description [Returns the total number of nodes currently in the unique
- table, including the dead nodes.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadDead]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadKeys(
- DdManager * dd)
-{
- return(dd->keys);
-
-} /* end of Cudd_ReadKeys */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of dead nodes in the unique table.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadKeys]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadDead(
- DdManager * dd)
-{
- return(dd->dead);
-
-} /* end of Cudd_ReadDead */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the minDead parameter of the manager.]
-
- Description [Reads the minDead parameter of the manager. The minDead
- parameter is used by the package to decide whether to collect garbage
- or resize a subtable of the unique table when the subtable becomes
- too full. The application can indirectly control the value of minDead
- by setting the looseUpTo parameter.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadMinDead(
- DdManager * dd)
-{
- return(dd->minDead);
-
-} /* end of Cudd_ReadMinDead */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of times reordering has occurred.]
-
- Description [Returns the number of times reordering has occurred in the
- manager. The number includes both the calls to Cudd_ReduceHeap from
- the application program and those automatically performed by the
- package. However, calls that do not even initiate reordering are not
- counted. A call may not initiate reordering if there are fewer than
- minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified
- as reordering method. The calls to Cudd_ShuffleHeap are not counted.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime]
-
-******************************************************************************/
-int
-Cudd_ReadReorderings(
- DdManager * dd)
-{
- return(dd->reorderings);
-
-} /* end of Cudd_ReadReorderings */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the time spent in reordering.]
-
- Description [Returns the number of milliseconds spent reordering
- variables since the manager was initialized. The time spent in collecting
- garbage before reordering is included.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadReorderings]
-
-******************************************************************************/
-long
-Cudd_ReadReorderingTime(
- DdManager * dd)
-{
- return(dd->reordTime);
-
-} /* end of Cudd_ReadReorderingTime */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of times garbage collection has occurred.]
-
- Description [Returns the number of times garbage collection has
- occurred in the manager. The number includes both the calls from
- reordering procedures and those caused by requests to create new
- nodes.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadGarbageCollectionTime]
-
-******************************************************************************/
-int
-Cudd_ReadGarbageCollections(
- DdManager * dd)
-{
- return(dd->garbageCollections);
-
-} /* end of Cudd_ReadGarbageCollections */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the time spent in garbage collection.]
-
- Description [Returns the number of milliseconds spent doing garbage
- collection since the manager was initialized.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadGarbageCollections]
-
-******************************************************************************/
-long
-Cudd_ReadGarbageCollectionTime(
- DdManager * dd)
-{
- return(dd->GCTime);
-
-} /* end of Cudd_ReadGarbageCollectionTime */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of nodes freed.]
-
- Description [Returns the number of nodes returned to the free list if the
- keeping of this statistic is enabled; -1 otherwise. This statistic is
- enabled only if the package is compiled with DD_STATS defined.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNodesDropped]
-
-******************************************************************************/
-double
-Cudd_ReadNodesFreed(
- DdManager * dd)
-{
-#ifdef DD_STATS
- return(dd->nodesFreed);
-#else
- return(-1.0);
-#endif
-
-} /* end of Cudd_ReadNodesFreed */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of nodes dropped.]
-
- Description [Returns the number of nodes killed by dereferencing if the
- keeping of this statistic is enabled; -1 otherwise. This statistic is
- enabled only if the package is compiled with DD_STATS defined.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNodesFreed]
-
-******************************************************************************/
-double
-Cudd_ReadNodesDropped(
- DdManager * dd)
-{
-#ifdef DD_STATS
- return(dd->nodesDropped);
-#else
- return(-1.0);
-#endif
-
-} /* end of Cudd_ReadNodesDropped */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of look-ups in the unique table.]
-
- Description [Returns the number of look-ups in the unique table if the
- keeping of this statistic is enabled; -1 otherwise. This statistic is
- enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadUniqueLinks]
-
-******************************************************************************/
-double
-Cudd_ReadUniqueLookUps(
- DdManager * dd)
-{
-#ifdef DD_UNIQUE_PROFILE
- return(dd->uniqueLookUps);
-#else
- return(-1.0);
-#endif
-
-} /* end of Cudd_ReadUniqueLookUps */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of links followed in the unique table.]
-
- Description [Returns the number of links followed during look-ups in the
- unique table if the keeping of this statistic is enabled; -1 otherwise.
- If an item is found in the first position of its collision list, the
- number of links followed is taken to be 0. If it is in second position,
- the number of links is 1, and so on. This statistic is enabled only if
- the package is compiled with DD_UNIQUE_PROFILE defined.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadUniqueLookUps]
-
-******************************************************************************/
-double
-Cudd_ReadUniqueLinks(
- DdManager * dd)
-{
-#ifdef DD_UNIQUE_PROFILE
- return(dd->uniqueLinks);
-#else
- return(-1.0);
-#endif
-
-} /* end of Cudd_ReadUniqueLinks */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the siftMaxVar parameter of the manager.]
-
- Description [Reads the siftMaxVar parameter of the manager. This
- parameter gives the maximum number of variables that will be sifted
- for each invocation of sifting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar]
-
-******************************************************************************/
-int
-Cudd_ReadSiftMaxVar(
- DdManager * dd)
-{
- return(dd->siftMaxVar);
-
-} /* end of Cudd_ReadSiftMaxVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the siftMaxVar parameter of the manager.]
-
- Description [Sets the siftMaxVar parameter of the manager. This
- parameter gives the maximum number of variables that will be sifted
- for each invocation of sifting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar]
-
-******************************************************************************/
-void
-Cudd_SetSiftMaxVar(
- DdManager * dd,
- int smv)
-{
- dd->siftMaxVar = smv;
-
-} /* end of Cudd_SetSiftMaxVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the siftMaxSwap parameter of the manager.]
-
- Description [Reads the siftMaxSwap parameter of the manager. This
- parameter gives the maximum number of swaps that will be attempted
- for each invocation of sifting. The real number of swaps may exceed
- the set limit because the package will always complete the sifting
- of the variable that causes the limit to be reached.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap]
-
-******************************************************************************/
-int
-Cudd_ReadSiftMaxSwap(
- DdManager * dd)
-{
- return(dd->siftMaxSwap);
-
-} /* end of Cudd_ReadSiftMaxSwap */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the siftMaxSwap parameter of the manager.]
-
- Description [Sets the siftMaxSwap parameter of the manager. This
- parameter gives the maximum number of swaps that will be attempted
- for each invocation of sifting. The real number of swaps may exceed
- the set limit because the package will always complete the sifting
- of the variable that causes the limit to be reached.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap]
-
-******************************************************************************/
-void
-Cudd_SetSiftMaxSwap(
- DdManager * dd,
- int sms)
-{
- dd->siftMaxSwap = sms;
-
-} /* end of Cudd_SetSiftMaxSwap */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the maxGrowth parameter of the manager.]
-
- Description [Reads the maxGrowth parameter of the manager. This
- parameter determines how much the number of nodes can grow during
- sifting of a variable. Overall, sifting never increases the size of
- the decision diagrams. This parameter only refers to intermediate
- results. A lower value will speed up sifting, possibly at the
- expense of quality.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate]
-
-******************************************************************************/
-double
-Cudd_ReadMaxGrowth(
- DdManager * dd)
-{
- return(dd->maxGrowth);
-
-} /* end of Cudd_ReadMaxGrowth */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the maxGrowth parameter of the manager.]
-
- Description [Sets the maxGrowth parameter of the manager. This
- parameter determines how much the number of nodes can grow during
- sifting of a variable. Overall, sifting never increases the size of
- the decision diagrams. This parameter only refers to intermediate
- results. A lower value will speed up sifting, possibly at the
- expense of quality.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate]
-
-******************************************************************************/
-void
-Cudd_SetMaxGrowth(
- DdManager * dd,
- double mg)
-{
- dd->maxGrowth = mg;
-
-} /* end of Cudd_SetMaxGrowth */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the maxGrowthAlt parameter of the manager.]
-
- Description [Reads the maxGrowthAlt parameter of the manager. This
- parameter is analogous to the maxGrowth paramter, and is used every
- given number of reorderings instead of maxGrowth. The number of
- reorderings is set with Cudd_SetReorderingCycle. If the number of
- reorderings is 0 (default) maxGrowthAlt is never used.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate
- Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
-
-******************************************************************************/
-double
-Cudd_ReadMaxGrowthAlternate(
- DdManager * dd)
-{
- return(dd->maxGrowthAlt);
-
-} /* end of Cudd_ReadMaxGrowthAlternate */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the maxGrowthAlt parameter of the manager.]
-
- Description [Sets the maxGrowthAlt parameter of the manager. This
- parameter is analogous to the maxGrowth paramter, and is used every
- given number of reorderings instead of maxGrowth. The number of
- reorderings is set with Cudd_SetReorderingCycle. If the number of
- reorderings is 0 (default) maxGrowthAlt is never used.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth
- Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
-
-******************************************************************************/
-void
-Cudd_SetMaxGrowthAlternate(
- DdManager * dd,
- double mg)
-{
- dd->maxGrowthAlt = mg;
-
-} /* end of Cudd_SetMaxGrowthAlternate */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the reordCycle parameter of the manager.]
-
- Description [Reads the reordCycle parameter of the manager. This
- parameter determines how often the alternate threshold on maximum
- growth is used in reordering.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate
- Cudd_SetReorderingCycle]
-
-******************************************************************************/
-int
-Cudd_ReadReorderingCycle(
- DdManager * dd)
-{
- return(dd->reordCycle);
-
-} /* end of Cudd_ReadReorderingCycle */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the reordCycle parameter of the manager.]
-
- Description [Sets the reordCycle parameter of the manager. This
- parameter determines how often the alternate threshold on maximum
- growth is used in reordering.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate
- Cudd_ReadReorderingCycle]
-
-******************************************************************************/
-void
-Cudd_SetReorderingCycle(
- DdManager * dd,
- int cycle)
-{
- dd->reordCycle = cycle;
-
-} /* end of Cudd_SetReorderingCycle */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree]
-
-******************************************************************************/
-MtrNode *
-Cudd_ReadTree(
- DdManager * dd)
-{
- return(dd->tree);
-
-} /* end of Cudd_ReadTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree]
-
-******************************************************************************/
-void
-Cudd_SetTree(
- DdManager * dd,
- MtrNode * tree)
-{
- if (dd->tree != NULL) {
- Mtr_FreeTree(dd->tree);
- }
- dd->tree = tree;
- if (tree == NULL) return;
-
- fixVarTree(tree, dd->perm, dd->size);
- return;
-
-} /* end of Cudd_SetTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree]
-
-******************************************************************************/
-void
-Cudd_FreeTree(
- DdManager * dd)
-{
- if (dd->tree != NULL) {
- Mtr_FreeTree(dd->tree);
- dd->tree = NULL;
- }
- return;
-
-} /* end of Cudd_FreeTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree]
-
-******************************************************************************/
-MtrNode *
-Cudd_ReadZddTree(
- DdManager * dd)
-{
- return(dd->treeZ);
-
-} /* end of Cudd_ReadZddTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the ZDD variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree]
-
-******************************************************************************/
-void
-Cudd_SetZddTree(
- DdManager * dd,
- MtrNode * tree)
-{
- if (dd->treeZ != NULL) {
- Mtr_FreeTree(dd->treeZ);
- }
- dd->treeZ = tree;
- if (tree == NULL) return;
-
- fixVarTree(tree, dd->permZ, dd->sizeZ);
- return;
-
-} /* end of Cudd_SetZddTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the variable group tree of the manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree]
-
-******************************************************************************/
-void
-Cudd_FreeZddTree(
- DdManager * dd)
-{
- if (dd->treeZ != NULL) {
- Mtr_FreeTree(dd->treeZ);
- dd->treeZ = NULL;
- }
- return;
-
-} /* end of Cudd_FreeZddTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of the node.]
-
- Description [Returns the index of the node. The node pointer can be
- either regular or complemented.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadIndex]
-
-******************************************************************************/
-unsigned int
-Cudd_NodeReadIndex(
- DdNode * node)
-{
- return((unsigned int) Cudd_Regular(node)->index);
-
-} /* end of Cudd_NodeReadIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the current position of the i-th variable in the
- order.]
-
- Description [Returns the current position of the i-th variable in
- the order. If the index is CUDD_CONST_INDEX, returns
- CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns
- -1.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd]
-
-******************************************************************************/
-int
-Cudd_ReadPerm(
- DdManager * dd,
- int i)
-{
- if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
- if (i < 0 || i >= dd->size) return(-1);
- return(dd->perm[i]);
-
-} /* end of Cudd_ReadPerm */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the current position of the i-th ZDD variable in the
- order.]
-
- Description [Returns the current position of the i-th ZDD variable
- in the order. If the index is CUDD_CONST_INDEX, returns
- CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns
- -1.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm]
-
-******************************************************************************/
-int
-Cudd_ReadPermZdd(
- DdManager * dd,
- int i)
-{
- if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
- if (i < 0 || i >= dd->sizeZ) return(-1);
- return(dd->permZ[i]);
-
-} /* end of Cudd_ReadPermZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of the variable currently in the i-th
- position of the order.]
-
- Description [Returns the index of the variable currently in the i-th
- position of the order. If the index is CUDD_CONST_INDEX, returns
- CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]
-
-******************************************************************************/
-int
-Cudd_ReadInvPerm(
- DdManager * dd,
- int i)
-{
- if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
- if (i < 0 || i >= dd->size) return(-1);
- return(dd->invperm[i]);
-
-} /* end of Cudd_ReadInvPerm */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of the ZDD variable currently in the i-th
- position of the order.]
-
- Description [Returns the index of the ZDD variable currently in the
- i-th position of the order. If the index is CUDD_CONST_INDEX, returns
- CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]
-
-******************************************************************************/
-int
-Cudd_ReadInvPermZdd(
- DdManager * dd,
- int i)
-{
- if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
- if (i < 0 || i >= dd->sizeZ) return(-1);
- return(dd->invpermZ[i]);
-
-} /* end of Cudd_ReadInvPermZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the i-th element of the vars array.]
-
- Description [Returns the i-th element of the vars array if it falls
- within the array bounds; NULL otherwise. If i is the index of an
- existing variable, this function produces the same result as
- Cudd_bddIthVar. However, if the i-th var does not exist yet,
- Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIthVar]
-
-******************************************************************************/
-DdNode *
-Cudd_ReadVars(
- DdManager * dd,
- int i)
-{
- if (i < 0 || i > dd->size) return(NULL);
- return(dd->vars[i]);
-
-} /* end of Cudd_ReadVars */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the epsilon parameter of the manager.]
-
- Description [Reads the epsilon parameter of the manager. The epsilon
- parameter control the comparison between floating point numbers.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetEpsilon]
-
-******************************************************************************/
-CUDD_VALUE_TYPE
-Cudd_ReadEpsilon(
- DdManager * dd)
-{
- return(dd->epsilon);
-
-} /* end of Cudd_ReadEpsilon */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the epsilon parameter of the manager to ep.]
-
- Description [Sets the epsilon parameter of the manager to ep. The epsilon
- parameter control the comparison between floating point numbers.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadEpsilon]
-
-******************************************************************************/
-void
-Cudd_SetEpsilon(
- DdManager * dd,
- CUDD_VALUE_TYPE ep)
-{
- dd->epsilon = ep;
-
-} /* end of Cudd_SetEpsilon */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the groupcheck parameter of the manager.]
-
- Description [Reads the groupcheck parameter of the manager. The
- groupcheck parameter determines the aggregation criterion in group
- sifting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetGroupcheck]
-
-******************************************************************************/
-Cudd_AggregationType
-Cudd_ReadGroupcheck(
- DdManager * dd)
-{
- return(dd->groupcheck);
-
-} /* end of Cudd_ReadGroupCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the parameter groupcheck of the manager to gc.]
-
- Description [Sets the parameter groupcheck of the manager to gc. The
- groupcheck parameter determines the aggregation criterion in group
- sifting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadGroupCheck]
-
-******************************************************************************/
-void
-Cudd_SetGroupcheck(
- DdManager * dd,
- Cudd_AggregationType gc)
-{
- dd->groupcheck = gc;
-
-} /* end of Cudd_SetGroupcheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether garbage collection is enabled.]
-
- Description [Returns 1 if garbage collection is enabled; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection]
-
-******************************************************************************/
-int
-Cudd_GarbageCollectionEnabled(
- DdManager * dd)
-{
- return(dd->gcEnabled);
-
-} /* end of Cudd_GarbageCollectionEnabled */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables garbage collection.]
-
- Description [Enables garbage collection. Garbage collection is
- initially enabled. Therefore it is necessary to call this function
- only if garbage collection has been explicitly disabled.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled]
-
-******************************************************************************/
-void
-Cudd_EnableGarbageCollection(
- DdManager * dd)
-{
- dd->gcEnabled = 1;
-
-} /* end of Cudd_EnableGarbageCollection */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables garbage collection.]
-
- Description [Disables garbage collection. Garbage collection is
- initially enabled. This function may be called to disable it.
- However, garbage collection will still occur when a new node must be
- created and no memory is left, or when garbage collection is required
- for correctness. (E.g., before reordering.)]
-
- SideEffects [None]
-
- SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled]
-
-******************************************************************************/
-void
-Cudd_DisableGarbageCollection(
- DdManager * dd)
-{
- dd->gcEnabled = 0;
-
-} /* end of Cudd_DisableGarbageCollection */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether dead nodes are counted towards triggering
- reordering.]
-
- Description [Tells whether dead nodes are counted towards triggering
- reordering. Returns 1 if dead nodes are counted; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead]
-
-******************************************************************************/
-int
-Cudd_DeadAreCounted(
- DdManager * dd)
-{
- return(dd->countDead == 0 ? 1 : 0);
-
-} /* end of Cudd_DeadAreCounted */
-
-
-/**Function********************************************************************
-
- Synopsis [Causes the dead nodes to be counted towards triggering
- reordering.]
-
- Description [Causes the dead nodes to be counted towards triggering
- reordering. This causes more frequent reorderings. By default dead
- nodes are not counted.]
-
- SideEffects [Changes the manager.]
-
- SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted]
-
-******************************************************************************/
-void
-Cudd_TurnOnCountDead(
- DdManager * dd)
-{
- dd->countDead = 0;
-
-} /* end of Cudd_TurnOnCountDead */
-
-
-/**Function********************************************************************
-
- Synopsis [Causes the dead nodes not to be counted towards triggering
- reordering.]
-
- Description [Causes the dead nodes not to be counted towards
- triggering reordering. This causes less frequent reorderings. By
- default dead nodes are not counted. Therefore there is no need to
- call this function unless Cudd_TurnOnCountDead has been previously
- called.]
-
- SideEffects [Changes the manager.]
-
- SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted]
-
-******************************************************************************/
-void
-Cudd_TurnOffCountDead(
- DdManager * dd)
-{
- dd->countDead = ~0;
-
-} /* end of Cudd_TurnOffCountDead */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the current value of the recombination parameter used
- in group sifting.]
-
- Description [Returns the current value of the recombination
- parameter used in group sifting. A larger (positive) value makes the
- aggregation of variables due to the second difference criterion more
- likely. A smaller (negative) value makes aggregation less likely.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetRecomb]
-
-******************************************************************************/
-int
-Cudd_ReadRecomb(
- DdManager * dd)
-{
- return(dd->recomb);
-
-} /* end of Cudd_ReadRecomb */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the value of the recombination parameter used in group
- sifting.]
-
- Description [Sets the value of the recombination parameter used in
- group sifting. A larger (positive) value makes the aggregation of
- variables due to the second difference criterion more likely. A
- smaller (negative) value makes aggregation less likely. The default
- value is 0.]
-
- SideEffects [Changes the manager.]
-
- SeeAlso [Cudd_ReadRecomb]
-
-******************************************************************************/
-void
-Cudd_SetRecomb(
- DdManager * dd,
- int recomb)
-{
- dd->recomb = recomb;
-
-} /* end of Cudd_SetRecomb */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the current value of the symmviolation parameter used
- in group sifting.]
-
- Description [Returns the current value of the symmviolation
- parameter. This parameter is used in group sifting to decide how
- many violations to the symmetry conditions <code>f10 = f01</code> or
- <code>f11 = f00</code> are tolerable when checking for aggregation
- due to extended symmetry. The value should be between 0 and 100. A
- small value causes fewer variables to be aggregated. The default
- value is 0.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetSymmviolation]
-
-******************************************************************************/
-int
-Cudd_ReadSymmviolation(
- DdManager * dd)
-{
- return(dd->symmviolation);
-
-} /* end of Cudd_ReadSymmviolation */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the value of the symmviolation parameter used
- in group sifting.]
-
- Description [Sets the value of the symmviolation
- parameter. This parameter is used in group sifting to decide how
- many violations to the symmetry conditions <code>f10 = f01</code> or
- <code>f11 = f00</code> are tolerable when checking for aggregation
- due to extended symmetry. The value should be between 0 and 100. A
- small value causes fewer variables to be aggregated. The default
- value is 0.]
-
- SideEffects [Changes the manager.]
-
- SeeAlso [Cudd_ReadSymmviolation]
-
-******************************************************************************/
-void
-Cudd_SetSymmviolation(
- DdManager * dd,
- int symmviolation)
-{
- dd->symmviolation = symmviolation;
-
-} /* end of Cudd_SetSymmviolation */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the current value of the arcviolation parameter used
- in group sifting.]
-
- Description [Returns the current value of the arcviolation
- parameter. This parameter is used in group sifting to decide how
- many arcs into <code>y</code> not coming from <code>x</code> are
- tolerable when checking for aggregation due to extended
- symmetry. The value should be between 0 and 100. A small value
- causes fewer variables to be aggregated. The default value is 0.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetArcviolation]
-
-******************************************************************************/
-int
-Cudd_ReadArcviolation(
- DdManager * dd)
-{
- return(dd->arcviolation);
-
-} /* end of Cudd_ReadArcviolation */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the value of the arcviolation parameter used
- in group sifting.]
-
- Description [Sets the value of the arcviolation
- parameter. This parameter is used in group sifting to decide how
- many arcs into <code>y</code> not coming from <code>x</code> are
- tolerable when checking for aggregation due to extended
- symmetry. The value should be between 0 and 100. A small value
- causes fewer variables to be aggregated. The default value is 0.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadArcviolation]
-
-******************************************************************************/
-void
-Cudd_SetArcviolation(
- DdManager * dd,
- int arcviolation)
-{
- dd->arcviolation = arcviolation;
-
-} /* end of Cudd_SetArcviolation */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the current size of the population used by the
- genetic algorithm for reordering.]
-
- Description [Reads the current size of the population used by the
- genetic algorithm for variable reordering. A larger population size will
- cause the genetic algorithm to take more time, but will generally
- produce better results. The default value is 0, in which case the
- package uses three times the number of variables as population size,
- with a maximum of 120.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetPopulationSize]
-
-******************************************************************************/
-int
-Cudd_ReadPopulationSize(
- DdManager * dd)
-{
- return(dd->populationSize);
-
-} /* end of Cudd_ReadPopulationSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the size of the population used by the
- genetic algorithm for reordering.]
-
- Description [Sets the size of the population used by the
- genetic algorithm for variable reordering. A larger population size will
- cause the genetic algorithm to take more time, but will generally
- produce better results. The default value is 0, in which case the
- package uses three times the number of variables as population size,
- with a maximum of 120.]
-
- SideEffects [Changes the manager.]
-
- SeeAlso [Cudd_ReadPopulationSize]
-
-******************************************************************************/
-void
-Cudd_SetPopulationSize(
- DdManager * dd,
- int populationSize)
-{
- dd->populationSize = populationSize;
-
-} /* end of Cudd_SetPopulationSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the current number of crossovers used by the
- genetic algorithm for reordering.]
-
- Description [Reads the current number of crossovers used by the
- genetic algorithm for variable reordering. A larger number of crossovers will
- cause the genetic algorithm to take more time, but will generally
- produce better results. The default value is 0, in which case the
- package uses three times the number of variables as number of crossovers,
- with a maximum of 60.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetNumberXovers]
-
-******************************************************************************/
-int
-Cudd_ReadNumberXovers(
- DdManager * dd)
-{
- return(dd->numberXovers);
-
-} /* end of Cudd_ReadNumberXovers */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the number of crossovers used by the
- genetic algorithm for reordering.]
-
- Description [Sets the number of crossovers used by the genetic
- algorithm for variable reordering. A larger number of crossovers
- will cause the genetic algorithm to take more time, but will
- generally produce better results. The default value is 0, in which
- case the package uses three times the number of variables as number
- of crossovers, with a maximum of 60.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNumberXovers]
-
-******************************************************************************/
-void
-Cudd_SetNumberXovers(
- DdManager * dd,
- int numberXovers)
-{
- dd->numberXovers = numberXovers;
-
-} /* end of Cudd_SetNumberXovers */
-
-/**Function********************************************************************
-
- Synopsis [Returns the memory in use by the manager measured in bytes.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-long
-Cudd_ReadMemoryInUse(
- DdManager * dd)
-{
- return(dd->memused);
-
-} /* end of Cudd_ReadMemoryInUse */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints out statistics and settings for a CUDD manager.]
-
- Description [Prints out statistics and settings for a CUDD manager.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_PrintInfo(
- DdManager * dd,
- FILE * fp)
-{
- int retval;
- Cudd_ReorderingType autoMethod, autoMethodZ;
-
- /* Modifiable parameters. */
- 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));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n",
- Cudd_ReadMinHit(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Garbage collection enabled: %s\n",
- Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no");
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Limit for fast unique table growth: %u\n",
- Cudd_ReadLooseUpTo(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,
- "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));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n",
- Cudd_ReadMaxGrowth(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n",
- Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no");
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Default BDD reordering method: %d\n", autoMethod);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n",
- Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no");
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Default ZDD reordering method: %d\n", autoMethodZ);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n",
- 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");
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n",
- Cudd_DeadAreCounted(dd) ? "yes" : "no");
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Group checking criterion: %d\n",
- 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));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Arc violation threshold: %d\n",
- Cudd_ReadArcviolation(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"GA population size: %d\n",
- Cudd_ReadPopulationSize(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of crossovers for GA: %d\n",
- Cudd_ReadNumberXovers(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Next reordering threshold: %u\n",
- 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));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Peak number of nodes: %ld\n",
- Cudd_ReadPeakNodeCount(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Peak number of live nodes: %d\n",
- Cudd_ReadPeakLiveNodeCount(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ);
- if (retval == EOF) return(0);
- 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));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of cache hits: %.0f\n",
- Cudd_ReadCacheHits(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of cache insertions: %.0f\n",
- dd->cacheinserts);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of cache collisions: %.0f\n",
- dd->cachecollisions);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of cache deletions: %.0f\n",
- 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));
- 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));
- 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);
- if (retval == EOF) return(0);
-#endif
- retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead);
- if (retval == EOF) return(0);
- 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);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n",
- dd->reclaimed);
- if (retval == EOF) return(0);
-#if 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
- retval = fprintf(fp,"Number of recursive calls: %.0f\n",
- Cudd_ReadRecursiveCalls(dd));
- if (retval == EOF) return(0);
-#endif
- retval = fprintf(fp,"Garbage collections so far: %d\n",
- Cudd_ReadGarbageCollections(dd));
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Time for garbage collection: %.2f sec\n",
- ((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));
- if (retval == EOF) return(0);
-#if DD_COUNT
- retval = fprintf(fp,"Node swaps in reordering: %.0f\n",
- Cudd_ReadSwapSteps(dd));
- if (retval == EOF) return(0);
-#endif
-
- return(1);
-
-} /* end of Cudd_PrintInfo */
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the peak number of nodes.]
-
- Description [Reports the peak number of nodes. This number includes
- node on the free list. At the peak, the number of nodes on the free
- list is guaranteed to be less than DD_MEM_CHUNK.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo]
-
-******************************************************************************/
-long
-Cudd_ReadPeakNodeCount(
- DdManager * dd)
-{
- long count = 0;
- DdNodePtr *scan = dd->memoryList;
-
- while (scan != NULL) {
- count += DD_MEM_CHUNK;
- scan = (DdNodePtr *) *scan;
- }
- return(count);
-
-} /* end of Cudd_ReadPeakNodeCount */
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the peak number of live nodes.]
-
- Description [Reports the peak number of live nodes. This count is kept
- only if CUDD is compiled with DD_STATS defined. If DD_STATS is not
- defined, this function returns -1.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount]
-
-******************************************************************************/
-int
-Cudd_ReadPeakLiveNodeCount(
- DdManager * dd)
-{
- unsigned int live = dd->keys - dd->dead;
-
- if (live > dd->peakLiveNodes) {
- dd->peakLiveNodes = live;
- }
- return((int)dd->peakLiveNodes);
-
-} /* end of Cudd_ReadPeakLiveNodeCount */
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the number of nodes in BDDs and ADDs.]
-
- Description [Reports the number of live nodes in BDDs and ADDs. This
- number does not include the isolated projection functions and the
- unused constants. These nodes that are not counted are not part of
- the DDs manipulated by the application.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount]
-
-******************************************************************************/
-long
-Cudd_ReadNodeCount(
- DdManager * dd)
-{
- long count;
- int i;
-
-#ifndef DD_NO_DEATH_ROW
- cuddClearDeathRow(dd);
-#endif
-
- count = 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--;
- }
- /* Subtract from the count the unused constants. */
- if (DD_ZERO(dd)->ref == 1) count--;
- if (DD_PLUS_INFINITY(dd)->ref == 1) count--;
- if (DD_MINUS_INFINITY(dd)->ref == 1) count--;
-
- return(count);
-
-} /* end of Cudd_ReadNodeCount */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Reports the number of nodes in ZDDs.]
-
- Description [Reports the number of nodes in ZDDs. This
- number always includes the two constants 1 and 0.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount]
-
-******************************************************************************/
-long
-Cudd_zddReadNodeCount(
- DdManager * dd)
-{
- return(dd->keysZ - dd->deadZ + 2);
-
-} /* end of Cudd_zddReadNodeCount */
-
-
-/**Function********************************************************************
-
- Synopsis [Adds a function to a hook.]
-
- Description [Adds a function to a hook. A hook is a list of
- application-provided functions called on certain occasions by the
- package. Returns 1 if the function is successfully added; 2 if the
- function was already in the list; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_RemoveHook]
-
-******************************************************************************/
-int
-Cudd_AddHook(
- DdManager * dd,
- int (*f)(DdManager *, char *, void *) ,
- Cudd_HookType where)
-{
- DdHook **hook, *nextHook, *newHook;
-
- switch (where) {
- case CUDD_PRE_GC_HOOK:
- hook = &(dd->preGCHook);
- break;
- case CUDD_POST_GC_HOOK:
- hook = &(dd->postGCHook);
- break;
- case CUDD_PRE_REORDERING_HOOK:
- hook = &(dd->preReorderingHook);
- break;
- case CUDD_POST_REORDERING_HOOK:
- hook = &(dd->postReorderingHook);
- break;
- default:
- 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;
- }
- /* The function was not in the list. Create a new item and append it
- ** to the end of the list. */
- newHook = ALLOC(DdHook,1);
- if (newHook == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newHook->next = NULL;
- newHook->f = f;
- *hook = newHook;
- return(1);
-
-} /* end of Cudd_AddHook */
-
-
-/**Function********************************************************************
-
- Synopsis [Removes a function from a hook.]
-
- Description [Removes a function from a hook. A hook is a list of
- application-provided functions called on certain occasions by the
- package. Returns 1 if successful; 0 the function was not in the list.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_AddHook]
-
-******************************************************************************/
-int
-Cudd_RemoveHook(
- DdManager * dd,
- int (*f)(DdManager *, char *, void *) ,
- Cudd_HookType where)
-{
- DdHook **hook, *nextHook;
-
- switch (where) {
- case CUDD_PRE_GC_HOOK:
- hook = &(dd->preGCHook);
- break;
- case CUDD_POST_GC_HOOK:
- hook = &(dd->postGCHook);
- break;
- case CUDD_PRE_REORDERING_HOOK:
- hook = &(dd->preReorderingHook);
- break;
- case CUDD_POST_REORDERING_HOOK:
- hook = &(dd->postReorderingHook);
- break;
- default:
- return(0);
- }
- nextHook = *hook;
- while (nextHook != NULL) {
- if (nextHook->f == f) {
- *hook = nextHook->next;
- FREE(nextHook);
- return(1);
- }
- hook = &(nextHook->next);
- nextHook = nextHook->next;
- }
-
- return(0);
-
-} /* end of Cudd_RemoveHook */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a function is in a hook.]
-
- Description [Checks whether a function is in a hook. A hook is a list of
- application-provided functions called on certain occasions by the
- package. Returns 1 if the function is found; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_AddHook Cudd_RemoveHook]
-
-******************************************************************************/
-int
-Cudd_IsInHook(
- DdManager * dd,
- int (*f)(DdManager *, char *, void *) ,
- Cudd_HookType where)
-{
- DdHook *hook;
-
- switch (where) {
- case CUDD_PRE_GC_HOOK:
- hook = dd->preGCHook;
- break;
- case CUDD_POST_GC_HOOK:
- hook = dd->postGCHook;
- break;
- case CUDD_PRE_REORDERING_HOOK:
- hook = dd->preReorderingHook;
- break;
- case CUDD_POST_REORDERING_HOOK:
- hook = dd->postReorderingHook;
- break;
- default:
- 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;
- }
- return(0);
-
-} /* end of Cudd_IsInHook */
-
-
-/**Function********************************************************************
-
- Synopsis [Sample hook function to call before reordering.]
-
- Description [Sample hook function to call before reordering.
- Prints on the manager's stdout reordering method and initial size.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_StdPostReordHook]
-
-******************************************************************************/
-int
-Cudd_StdPreReordHook(
- DdManager *dd,
- char *str,
- void *data)
-{
- Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data;
- int retval;
-
- retval = fprintf(dd->out,"%s reordering with ", str);
- if (retval == EOF) return(0);
- switch (method) {
- case CUDD_REORDER_SIFT_CONVERGE:
- case CUDD_REORDER_SYMM_SIFT_CONV:
- case CUDD_REORDER_GROUP_SIFT_CONV:
- case CUDD_REORDER_WINDOW2_CONV:
- 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;
- default:
- break;
- }
- switch (method) {
- case CUDD_REORDER_RANDOM:
- case CUDD_REORDER_RANDOM_PIVOT:
- retval = fprintf(dd->out,"random");
- break;
- case CUDD_REORDER_SIFT:
- case CUDD_REORDER_SIFT_CONVERGE:
- retval = fprintf(dd->out,"sifting");
- break;
- case CUDD_REORDER_SYMM_SIFT:
- case CUDD_REORDER_SYMM_SIFT_CONV:
- retval = fprintf(dd->out,"symmetric sifting");
- break;
- case CUDD_REORDER_LAZY_SIFT:
- 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;
- 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;
- case CUDD_REORDER_ANNEALING:
- retval = fprintf(dd->out,"annealing");
- break;
- case CUDD_REORDER_GENETIC:
- retval = fprintf(dd->out,"genetic");
- break;
- case CUDD_REORDER_LINEAR:
- case CUDD_REORDER_LINEAR_CONVERGE:
- retval = fprintf(dd->out,"linear sifting");
- break;
- case CUDD_REORDER_EXACT:
- retval = fprintf(dd->out,"exact");
- break;
- default:
- return(0);
- }
- if (retval == EOF) return(0);
-
- retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ?
- Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd));
- if (retval == EOF) return(0);
- fflush(dd->out);
- return(1);
-
-} /* end of Cudd_StdPreReordHook */
-
-
-/**Function********************************************************************
-
- Synopsis [Sample hook function to call after reordering.]
-
- Description [Sample hook function to call after reordering.
- Prints on the manager's stdout final size and reordering time.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_StdPreReordHook]
-
-******************************************************************************/
-int
-Cudd_StdPostReordHook(
- DdManager *dd,
- char *str,
- void *data)
-{
- long initialTime = (long) data;
- int retval;
- long finalTime = util_cpu_time();
- 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);
- if (retval == EOF) return(0);
- retval = fflush(dd->out);
- if (retval == EOF) return(0);
- return(1);
-
-} /* end of Cudd_StdPostReordHook */
-
-
-/**Function********************************************************************
-
- Synopsis [Enables reporting of reordering stats.]
-
- Description [Enables reporting of reordering stats.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [Installs functions in the pre-reordering and post-reordering
- hooks.]
-
- SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting]
-
-******************************************************************************/
-int
-Cudd_EnableReorderingReporting(
- DdManager *dd)
-{
- if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
- return(0);
- }
- if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
- return(0);
- }
- return(1);
-
-} /* end of Cudd_EnableReorderingReporting */
-
-
-/**Function********************************************************************
-
- Synopsis [Disables reporting of reordering stats.]
-
- Description [Disables reporting of reordering stats.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [Removes functions from the pre-reordering and post-reordering
- hooks.]
-
- SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting]
-
-******************************************************************************/
-int
-Cudd_DisableReorderingReporting(
- DdManager *dd)
-{
- if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
- return(0);
- }
- if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
- return(0);
- }
- return(1);
-
-} /* end of Cudd_DisableReorderingReporting */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if reporting of reordering stats is enabled.]
-
- Description [Returns 1 if reporting of reordering stats is enabled;
- 0 otherwise.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting]
-
-******************************************************************************/
-int
-Cudd_ReorderingReporting(
- DdManager *dd)
-{
- return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK));
-
-} /* end of Cudd_ReorderingReporting */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the code of the last error.]
-
- Description [Returns the code of the last error. The error codes are
- defined in cudd.h.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ClearErrorCode]
-
-******************************************************************************/
-Cudd_ErrorType
-Cudd_ReadErrorCode(
- DdManager *dd)
-{
- return(dd->errorCode);
-
-} /* end of Cudd_ReadErrorCode */
-
-
-/**Function********************************************************************
-
- Synopsis [Clear the error code of a manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadErrorCode]
-
-******************************************************************************/
-void
-Cudd_ClearErrorCode(
- DdManager *dd)
-{
- dd->errorCode = CUDD_NO_ERROR;
-
-} /* end of Cudd_ClearErrorCode */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the stdout of a manager.]
-
- Description [Reads the stdout of a manager. This is the file pointer to
- which messages normally going to stdout are written. It is initialized
- to stdout. Cudd_SetStdout allows the application to redirect it.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetStdout Cudd_ReadStderr]
-
-******************************************************************************/
-FILE *
-Cudd_ReadStdout(
- DdManager *dd)
-{
- return(dd->out);
-
-} /* end of Cudd_ReadStdout */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the stdout of a manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadStdout Cudd_SetStderr]
-
-******************************************************************************/
-void
-Cudd_SetStdout(
- DdManager *dd,
- FILE *fp)
-{
- dd->out = fp;
-
-} /* end of Cudd_SetStdout */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the stderr of a manager.]
-
- Description [Reads the stderr of a manager. This is the file pointer to
- which messages normally going to stderr are written. It is initialized
- to stderr. Cudd_SetStderr allows the application to redirect it.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetStderr Cudd_ReadStdout]
-
-******************************************************************************/
-FILE *
-Cudd_ReadStderr(
- DdManager *dd)
-{
- return(dd->err);
-
-} /* end of Cudd_ReadStderr */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the stderr of a manager.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadStderr Cudd_SetStdout]
-
-******************************************************************************/
-void
-Cudd_SetStderr(
- DdManager *dd,
- FILE *fp)
-{
- dd->err = fp;
-
-} /* end of Cudd_SetStderr */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the threshold for the next dynamic reordering.]
-
- Description [Returns the threshold for the next dynamic reordering.
- The threshold is in terms of number of nodes and is in effect only
- if reordering is enabled. The count does not include the dead nodes,
- unless the countDead parameter of the manager has been changed from
- its default setting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SetNextReordering]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadNextReordering(
- DdManager *dd)
-{
- return(dd->nextDyn);
-
-} /* end of Cudd_ReadNextReordering */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the threshold for the next dynamic reordering.]
-
- Description [Sets the threshold for the next dynamic reordering.
- The threshold is in terms of number of nodes and is in effect only
- if reordering is enabled. The count does not include the dead nodes,
- unless the countDead parameter of the manager has been changed from
- its default setting.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ReadNextReordering]
-
-******************************************************************************/
-void
-Cudd_SetNextReordering(
- DdManager *dd,
- unsigned int next)
-{
- dd->nextDyn = next;
-
-} /* end of Cudd_SetNextReordering */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the number of elementary reordering steps.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-double
-Cudd_ReadSwapSteps(
- DdManager *dd)
-{
-#ifdef DD_COUNT
- return(dd->swapSteps);
-#else
- return(-1);
-#endif
-
-} /* end of Cudd_ReadSwapSteps */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the maximum allowed number of live nodes.]
-
- Description [Reads the maximum allowed number of live nodes. When this
- number is exceeded, the package returns NULL.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_SetMaxLive]
-
-******************************************************************************/
-unsigned int
-Cudd_ReadMaxLive(
- DdManager *dd)
-{
- return(dd->maxLive);
-
-} /* end of Cudd_ReadMaxLive */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the maximum allowed number of live nodes.]
-
- Description [Sets the maximum allowed number of live nodes. When this
- number is exceeded, the package returns NULL.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ReadMaxLive]
-
-******************************************************************************/
-void
-Cudd_SetMaxLive(
- DdManager *dd,
- unsigned int maxLive)
-{
- dd->maxLive = maxLive;
-
-} /* end of Cudd_SetMaxLive */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads the maximum allowed memory.]
-
- Description [Reads the maximum allowed memory. When this
- number is exceeded, the package returns NULL.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_SetMaxMemory]
-
-******************************************************************************/
-long
-Cudd_ReadMaxMemory(
- DdManager *dd)
-{
- return(dd->maxmemhard);
-
-} /* end of Cudd_ReadMaxMemory */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets the maximum allowed memory.]
-
- Description [Sets the maximum allowed memory. When this
- number is exceeded, the package returns NULL.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ReadMaxMemory]
-
-******************************************************************************/
-void
-Cudd_SetMaxMemory(
- DdManager *dd,
- long maxMemory)
-{
- dd->maxmemhard = maxMemory;
-
-} /* end of Cudd_SetMaxMemory */
-
-
-/**Function********************************************************************
-
- Synopsis [Prevents sifting of a variable.]
-
- Description [This function sets a flag to prevent sifting of a
- variable. Returns 1 if successful; 0 otherwise (i.e., invalid
- variable index).]
-
- SideEffects [Changes the "bindVar" flag in DdSubtable.]
-
- SeeAlso [Cudd_bddUnbindVar]
-
-******************************************************************************/
-int
-Cudd_bddBindVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].bindVar = 1;
- return(1);
-
-} /* end of Cudd_bddBindVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Allows the sifting of a variable.]
-
- Description [This function resets the flag that prevents the sifting
- of a variable. In successive variable reorderings, the variable will
- NOT be skipped, that is, sifted. Initially all variables can be
- sifted. It is necessary to call this function only to re-enable
- sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0
- otherwise (i.e., invalid variable index).]
-
- SideEffects [Changes the "bindVar" flag in DdSubtable.]
-
- SeeAlso [Cudd_bddBindVar]
-
-******************************************************************************/
-int
-Cudd_bddUnbindVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].bindVar = 0;
- return(1);
-
-} /* end of Cudd_bddUnbindVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether a variable can be sifted.]
-
- Description [This function returns 1 if a variable is enabled for
- sifting. Initially all variables can be sifted. This function returns
- 0 only if there has been a previous call to Cudd_bddBindVar for that
- variable not followed by a call to Cudd_bddUnbindVar. The function returns
- 0 also in the case in which the index of the variable is out of bounds.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar]
-
-******************************************************************************/
-int
-Cudd_bddVarIsBound(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return(0);
- return(dd->subtables[dd->perm[index]].bindVar);
-
-} /* end of Cudd_bddVarIsBound */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable type to primary input.]
-
- Description [Sets a variable type to primary input. The variable type is
- used by lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar]
-
-******************************************************************************/
-int
-Cudd_bddSetPiVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return (0);
- dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT;
- return(1);
-
-} /* end of Cudd_bddSetPiVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable type to present state.]
-
- Description [Sets a variable type to present state. The variable type is
- used by lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar]
-
-******************************************************************************/
-int
-Cudd_bddSetPsVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return (0);
- dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE;
- return(1);
-
-} /* end of Cudd_bddSetPsVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable type to next state.]
-
- Description [Sets a variable type to next state. The variable type is
- used by lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar]
-
-******************************************************************************/
-int
-Cudd_bddSetNsVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return (0);
- dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE;
- return(1);
-
-} /* end of Cudd_bddSetNsVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is primary input.]
-
- Description [Checks whether a variable is primary input. Returns 1 if
- the variable's type is primary input; 0 if the variable exists but is
- not a primary input; -1 if the variable does not exist.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar]
-
-******************************************************************************/
-int
-Cudd_bddIsPiVar(
- DdManager *dd /* manager */,
- int index /* variable index */)
-{
- if (index >= dd->size || index < 0) return -1;
- return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT);
-
-} /* end of Cudd_bddIsPiVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is present state.]
-
- Description [Checks whether a variable is present state. Returns 1 if
- the variable's type is present state; 0 if the variable exists but is
- not a present state; -1 if the variable does not exist.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar]
-
-******************************************************************************/
-int
-Cudd_bddIsPsVar(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return -1;
- return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE);
-
-} /* end of Cudd_bddIsPsVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is next state.]
-
- Description [Checks whether a variable is next state. Returns 1 if
- the variable's type is present state; 0 if the variable exists but is
- not a present state; -1 if the variable does not exist.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar]
-
-******************************************************************************/
-int
-Cudd_bddIsNsVar(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return -1;
- return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE);
-
-} /* end of Cudd_bddIsNsVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a corresponding pair index for a given index.]
-
- Description [Sets a corresponding pair index for a given index.
- These pair indices are present and next state variable. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddReadPairIndex]
-
-******************************************************************************/
-int
-Cudd_bddSetPairIndex(
- DdManager *dd /* manager */,
- int index /* variable index */,
- int pairIndex /* corresponding variable index */)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].pairIndex = pairIndex;
- return(1);
-
-} /* end of Cudd_bddSetPairIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads a corresponding pair index for a given index.]
-
- Description [Reads a corresponding pair index for a given index.
- These pair indices are present and next state variable. Returns the
- corresponding variable index if the variable exists; -1 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetPairIndex]
-
-******************************************************************************/
-int
-Cudd_bddReadPairIndex(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return -1;
- return dd->subtables[dd->perm[index]].pairIndex;
-
-} /* end of Cudd_bddReadPairIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable to be grouped.]
-
- Description [Sets a variable to be grouped. This function is used for
- lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped]
-
-******************************************************************************/
-int
-Cudd_bddSetVarToBeGrouped(
- DdManager *dd,
- int index)
-{
- 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;
- }
- return(1);
-
-} /* end of Cudd_bddSetVarToBeGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable to be a hard group.]
-
- Description [Sets a variable to be a hard group. This function is used
- for lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped
- Cudd_bddIsVarHardGroup]
-
-******************************************************************************/
-int
-Cudd_bddSetVarHardGroup(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP;
- return(1);
-
-} /* end of Cudd_bddSetVarHardGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Resets a variable not to be grouped.]
-
- Description [Resets a variable not to be grouped. This function is
- used for lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup]
-
-******************************************************************************/
-int
-Cudd_bddResetVarToBeGrouped(
- DdManager *dd,
- int index)
-{
- 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;
- }
- return(1);
-
-} /* end of Cudd_bddResetVarToBeGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is set to be grouped.]
-
- Description [Checks whether a variable is set to be grouped. This
- function is used for lazy sifting.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_bddIsVarToBeGrouped(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(-1);
- if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP)
- return(0);
- else
- return(dd->subtables[dd->perm[index]].varToBeGrouped);
-
-} /* end of Cudd_bddIsVarToBeGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable to be ungrouped.]
-
- Description [Sets a variable to be ungrouped. This function is used
- for lazy sifting. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [modifies the manager]
-
- SeeAlso [Cudd_bddIsVarToBeUngrouped]
-
-******************************************************************************/
-int
-Cudd_bddSetVarToBeUngrouped(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP;
- return(1);
-
-} /* end of Cudd_bddSetVarToBeGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is set to be ungrouped.]
-
- Description [Checks whether a variable is set to be ungrouped. This
- function is used for lazy sifting. Returns 1 if the variable is marked
- to be ungrouped; 0 if the variable exists, but it is not marked to be
- ungrouped; -1 if the variable does not exist.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddSetVarToBeUngrouped]
-
-******************************************************************************/
-int
-Cudd_bddIsVarToBeUngrouped(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(-1);
- return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP;
-
-} /* end of Cudd_bddIsVarToBeGrouped */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is set to be in a hard group.]
-
- Description [Checks whether a variable is set to be in a hard group. This
- function is used for lazy sifting. Returns 1 if the variable is marked
- to be in a hard group; 0 if the variable exists, but it is not marked to be
- in a hard group; -1 if the variable does not exist.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddSetVarHardGroup]
-
-******************************************************************************/
-int
-Cudd_bddIsVarHardGroup(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(-1);
- if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP)
- return(1);
- return(0);
-
-} /* end of Cudd_bddIsVarToBeGrouped */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Fixes a variable group tree.]
-
- Description []
-
- SideEffects [Changes the variable group tree.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-fixVarTree(
- MtrNode * treenode,
- int * perm,
- int size)
-{
- treenode->index = treenode->low;
- treenode->low = ((int) treenode->index < size) ?
- perm[treenode->index] : treenode->index;
- if (treenode->child != NULL)
- fixVarTree(treenode->child, perm, size);
- if (treenode->younger != NULL)
- fixVarTree(treenode->younger, perm, size);
- return;
-
-} /* end of fixVarTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Adds multiplicity groups to a ZDD variable group tree.]
-
- Description [Adds multiplicity groups to a ZDD variable group tree.
- Returns 1 if successful; 0 otherwise. This function creates the groups
- for set of ZDD variables (whose cardinality is given by parameter
- multiplicity) that are created for each BDD variable in
- Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index
- each new group. (The index of the first variable in the group.)
- We first build all the groups for the children of a node, and then deal
- with the ZDD variables that are directly attached to the node. The problem
- for these is that the tree itself does not provide information on their
- position inside the group. While we deal with the children of the node,
- therefore, we keep track of all the positions they occupy. The remaining
- positions in the tree can be freely used. Also, we keep track of all the
- variables placed in the children. All the remaining variables are directly
- attached to the group. We can then place any pair of variables not yet
- grouped in any pair of available positions in the node.]
-
- SideEffects [Changes the variable group tree.]
-
- SeeAlso [Cudd_zddVarsFromBddVars]
-
-******************************************************************************/
-static int
-addMultiplicityGroups(
- DdManager *dd /* manager */,
- MtrNode *treenode /* current tree node */,
- int multiplicity /* how many ZDD vars per BDD var */,
- char *vmask /* variable pairs for which a group has been already built */,
- char *lmask /* levels for which a group has already been built*/)
-{
- int startV, stopV, startL;
- int i, j;
- 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);
- }
- node->index = dd->invpermZ[i * multiplicity];
- vmask[i] = 1;
- lmask[j] = 1;
- }
- }
- auxnode = auxnode->younger;
- }
- return(1);
-
-} /* end of addMultiplicityGroups */
-
diff --git a/src/bdd/cudd/cuddAddAbs.c b/src/bdd/cudd/cuddAddAbs.c
deleted file mode 100644
index b256ad0f..00000000
--- a/src/bdd/cudd/cuddAddAbs.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddAbs.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-static DdNode *two;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int addCheckPositiveCube ARGS((DdManager *manager, DdNode *cube));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Existentially Abstracts all the variables in cube from f.]
-
- Description [Abstracts all the variables in cube from f by summing
- over all possible values taken by the variables. Returns the
- abstracted ADD.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract
- Cudd_addOrAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_addExistAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- DdNode *res;
-
- two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2);
- if (two == NULL) return(NULL);
- cuddRef(two);
-
- if (addCheckPositiveCube(manager, cube) == 0) {
- (void) fprintf(manager->err,"Error: Can only abstract cubes");
- return(NULL);
- }
-
- do {
- manager->reordered = 0;
- res = cuddAddExistAbstractRecur(manager, f, cube);
- } while (manager->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(manager,two);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(manager,two);
- cuddDeref(res);
-
- return(res);
-
-} /* end of Cudd_addExistAbstract */
-
-
-/**Function********************************************************************
-
- Synopsis [Universally Abstracts all the variables in cube from f.]
-
- Description [Abstracts all the variables in cube from f by taking
- the product over all possible values taken by the variable. Returns
- the abstracted ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract
- Cudd_addOrAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_addUnivAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- DdNode *res;
-
- if (addCheckPositiveCube(manager, cube) == 0) {
- (void) fprintf(manager->err,"Error: Can only abstract cubes");
- return(NULL);
- }
-
- do {
- manager->reordered = 0;
- res = cuddAddUnivAbstractRecur(manager, f, cube);
- } while (manager->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_addUnivAbstract */
-
-
-/**Function********************************************************************
-
- Synopsis [Disjunctively abstracts all the variables in cube from the
- 0-1 ADD f.]
-
- Description [Abstracts all the variables in cube from the 0-1 ADD f
- by taking the disjunction over all possible values taken by the
- variables. Returns the abstracted ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_addOrAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- DdNode *res;
-
- if (addCheckPositiveCube(manager, cube) == 0) {
- (void) fprintf(manager->err,"Error: Can only abstract cubes");
- return(NULL);
- }
-
- do {
- manager->reordered = 0;
- res = cuddAddOrAbstractRecur(manager, f, cube);
- } while (manager->reordered == 1);
- return(res);
-
-} /* end of Cudd_addOrAbstract */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addExistAbstract.]
-
- Description [Performs the recursive step of Cudd_addExistAbstract.
- Returns the ADD obtained by abstracting the variables of cube from f,
- if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddAddExistAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- DdNode *T, *E, *res, *res1, *res2, *zero;
-
- statLine(manager);
- zero = DD_ZERO(manager);
-
- /* 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) {
- Cudd_RecursiveDeref(manager,res1);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(manager,res1);
- cuddDeref(res);
- return(res);
- }
-
- if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) {
- return(res);
- }
-
- T = cuddT(f);
- E = cuddE(f);
-
- /* 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);
- cuddRef(res1);
- 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) {
- 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);
- return(res);
- } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
- 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);
- }
- 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);
- return(res);
- }
-
-} /* end of cuddAddExistAbstractRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addUnivAbstract.]
-
- Description [Performs the recursive step of Cudd_addUnivAbstract.
- Returns the ADD obtained by abstracting the variables of cube from f,
- if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddAddUnivAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- DdNode *T, *E, *res, *res1, *res2, *one, *zero;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = DD_ZERO(manager);
-
- /* Cube is guaranteed to be a cube at this point.
- ** zero and one are the only constatnts c such that c*c=c.
- */
- if (f == zero || f == one || cube == one) {
- 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) {
- Cudd_RecursiveDeref(manager,res1);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(manager,res1);
- cuddDeref(res);
- return(res);
- }
-
- if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
- return(res);
- }
-
- T = cuddT(f);
- E = cuddE(f);
-
- /* 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);
- cuddRef(res1);
- 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) {
- 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);
- return(res);
- } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
- 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);
- }
- 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);
- return(res);
- }
-
-} /* end of cuddAddUnivAbstractRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addOrAbstract.]
-
- Description [Performs the recursive step of Cudd_addOrAbstract.
- Returns the ADD obtained by abstracting the variables of cube from f,
- if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddAddOrAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- 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);
- }
-
- /* 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);
- }
-
- if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
- return(res);
- }
-
- T = cuddT(f);
- E = cuddE(f);
-
- /* 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);
- 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);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(manager,res1);
- Cudd_RecursiveDeref(manager,res2);
- } else {
- res = res1;
- }
- 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);
- cuddRef(res1);
- 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);
- return(res);
- }
-
-} /* end of cuddAddOrAbstractRecur */
-
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether cube is an ADD representing the product
- of positive literals.]
-
- Description [Checks whether cube is an ADD representing the product of
- positive literals. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-addCheckPositiveCube(
- DdManager * manager,
- DdNode * cube)
-{
- if (Cudd_IsComplement(cube)) return(0);
- if (cube == DD_ONE(manager)) return(1);
- if (cuddIsConstant(cube)) return(0);
- if (cuddE(cube) == DD_ZERO(manager)) {
- return(addCheckPositiveCube(manager, cuddT(cube)));
- }
- return(0);
-
-} /* end of addCheckPositiveCube */
-
diff --git a/src/bdd/cudd/cuddAddApply.c b/src/bdd/cudd/cuddAddApply.c
deleted file mode 100644
index 60c06de6..00000000
--- a/src/bdd/cudd/cuddAddApply.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddApply.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Applies op to the corresponding discriminants of f and g.]
-
- Description [Applies op to the corresponding discriminants of f and g.
- Returns a pointer to the result if succssful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes
- Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum
- Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement
- Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_addApply(
- DdManager * dd,
- DdNode * (*op)(DdManager *, DdNode **, DdNode **),
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddApplyRecur(dd,op,f,g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addApply */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point addition.]
-
- Description [Integer and floating point addition. Returns NULL if not
- a terminal case; f+g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addPlus(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *res;
- DdNode *F, *G;
- CUDD_VALUE_TYPE value;
-
- F = *f; G = *g;
- 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);
- }
- if (F > G) { /* swap f and g */
- *f = G;
- *g = F;
- }
- return(NULL);
-
-} /* end of Cudd_addPlus */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point multiplication.]
-
- Description [Integer and floating point multiplication. Returns NULL
- if not a terminal case; f * g otherwise. This function can be used also
- to take the AND of two 0-1 ADDs.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addTimes(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *res;
- DdNode *F, *G;
- CUDD_VALUE_TYPE value;
-
- F = *f; G = *g;
- if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd));
- 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);
- }
- if (F > G) { /* swap f and g */
- *f = G;
- *g = F;
- }
- return(NULL);
-
-} /* end of Cudd_addTimes */
-
-
-/**Function********************************************************************
-
- Synopsis [f if f&gt;=g; 0 if f&lt;g.]
-
- Description [Threshold operator for Apply (f if f &gt;=g; 0 if f&lt;g).
- Returns NULL if not a terminal case; f op g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addThreshold(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- 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));
- }
- }
- return(NULL);
-
-} /* end of Cudd_addThreshold */
-
-
-/**Function********************************************************************
-
- Synopsis [This operator sets f to the value of g wherever g != 0.]
-
- Description [This operator sets f to the value of g wherever g != 0.
- Returns NULL if not a terminal case; f op g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addSetNZ(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(F);
- if (F == DD_ZERO(dd)) return(G);
- if (G == DD_ZERO(dd)) return(F);
- if (cuddIsConstant(G)) return(G);
- return(NULL);
-
-} /* end of Cudd_addSetNZ */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point division.]
-
- Description [Integer and floating point division. Returns NULL if not
- a terminal case; f / g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addDivide(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *res;
- DdNode *F, *G;
- CUDD_VALUE_TYPE value;
-
- F = *f; G = *g;
- /* We would like to use F == G -> F/G == 1, but F and G may
- ** contain zeroes. */
- 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);
- }
- return(NULL);
-
-} /* end of Cudd_addDivide */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point subtraction.]
-
- Description [Integer and floating point subtraction. Returns NULL if
- not a terminal case; f - g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addMinus(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *res;
- DdNode *F, *G;
- CUDD_VALUE_TYPE value;
-
- F = *f; G = *g;
- if (F == G) return(DD_ZERO(dd));
- 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);
- }
- return(NULL);
-
-} /* end of Cudd_addMinus */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point min.]
-
- Description [Integer and floating point min for Cudd_addApply.
- Returns NULL if not a terminal case; min(f,g) otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addMinimum(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == DD_PLUS_INFINITY(dd)) return(G);
- if (G == DD_PLUS_INFINITY(dd)) return(F);
- if (F == G) return(F);
-#if 0
- /* These special cases probably do not pay off. */
- if (F == DD_MINUS_INFINITY(dd)) return(F);
- 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 (F > G) { /* swap f and g */
- *f = G;
- *g = F;
- }
- return(NULL);
-
-} /* end of Cudd_addMinimum */
-
-
-/**Function********************************************************************
-
- Synopsis [Integer and floating point max.]
-
- Description [Integer and floating point max for Cudd_addApply.
- Returns NULL if not a terminal case; max(f,g) otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addMaximum(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(F);
- if (F == DD_MINUS_INFINITY(dd)) return(G);
- if (G == DD_MINUS_INFINITY(dd)) return(F);
-#if 0
- /* These special cases probably do not pay off. */
- if (F == DD_PLUS_INFINITY(dd)) return(F);
- 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 (F > G) { /* swap f and g */
- *f = G;
- *g = F;
- }
- return(NULL);
-
-} /* end of Cudd_addMaximum */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if f &gt; g and 0 otherwise.]
-
- Description [Returns 1 if f &gt; g and 0 otherwise. Used in
- conjunction with Cudd_addApply. Returns NULL if not a terminal
- case.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addOneZeroMaximum(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
-
- if (*f == *g) return(DD_ZERO(dd));
- if (*g == DD_PLUS_INFINITY(dd))
- return DD_ZERO(dd);
- if (cuddIsConstant(*f) && cuddIsConstant(*g)) {
- if (cuddV(*f) > cuddV(*g)) {
- return(DD_ONE(dd));
- } else {
- return(DD_ZERO(dd));
- }
- }
-
- return(NULL);
-
-} /* end of Cudd_addOneZeroMaximum */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.]
-
- Description [Returns NULL if not a terminal case; f op g otherwise,
- where f op g is plusinfinity if f=g; min(f,g) if f!=g.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addDiff(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(DD_PLUS_INFINITY(dd));
- 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)) {
- return(F);
- } else {
- return(G);
- }
- } else {
- return(DD_PLUS_INFINITY(dd));
- }
- }
- return(NULL);
-
-} /* end of Cudd_addDiff */
-
-
-/**Function********************************************************************
-
- Synopsis [f if f==g; background if f!=g.]
-
- Description [Returns NULL if not a terminal case; f op g otherwise,
- where f op g is f if f==g; background if f!=g.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addAgreement(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(F);
- if (F == dd->background) return(F);
- if (G == dd->background) return(G);
- if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background);
- return(NULL);
-
-} /* end of Cudd_addAgreement */
-
-
-/**Function********************************************************************
-
- Synopsis [Disjunction of two 0-1 ADDs.]
-
- Description [Disjunction of two 0-1 ADDs. Returns NULL
- if not a terminal case; f OR g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addOr(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd));
- if (cuddIsConstant(F)) return(G);
- if (cuddIsConstant(G)) return(F);
- if (F == G) return(F);
- if (F > G) { /* swap f and g */
- *f = G;
- *g = F;
- }
- return(NULL);
-
-} /* end of Cudd_addOr */
-
-
-/**Function********************************************************************
-
- Synopsis [NAND of two 0-1 ADDs.]
-
- Description [NAND of two 0-1 ADDs. Returns NULL
- if not a terminal case; f NAND g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addNand(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- 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;
- }
- return(NULL);
-
-} /* end of Cudd_addNand */
-
-
-/**Function********************************************************************
-
- Synopsis [NOR of two 0-1 ADDs.]
-
- Description [NOR of two 0-1 ADDs. Returns NULL
- if not a terminal case; f NOR g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addNor(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- 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;
- }
- return(NULL);
-
-} /* end of Cudd_addNor */
-
-
-/**Function********************************************************************
-
- Synopsis [XOR of two 0-1 ADDs.]
-
- Description [XOR of two 0-1 ADDs. Returns NULL
- if not a terminal case; f XOR g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addXor(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(DD_ZERO(dd));
- if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd));
- 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;
- }
- return(NULL);
-
-} /* end of Cudd_addXor */
-
-
-/**Function********************************************************************
-
- Synopsis [XNOR of two 0-1 ADDs.]
-
- Description [XNOR of two 0-1 ADDs. Returns NULL
- if not a terminal case; f XNOR g otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addXnor(
- DdManager * dd,
- DdNode ** f,
- DdNode ** g)
-{
- DdNode *F, *G;
-
- F = *f; G = *g;
- if (F == G) return(DD_ONE(dd));
- if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd));
- 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;
- }
- return(NULL);
-
-} /* end of Cudd_addXnor */
-
-
-/**Function********************************************************************
-
- Synopsis [Applies op to the discriminants of f.]
-
- Description [Applies op to the discriminants of f.
- Returns a pointer to the result if succssful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addApply Cudd_addLog]
-
-******************************************************************************/
-DdNode *
-Cudd_addMonadicApply(
- DdManager * dd,
- DdNode * (*op)(DdManager *, DdNode *),
- DdNode * f)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddMonadicApplyRecur(dd,op,f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addMonadicApply */
-
-
-/**Function********************************************************************
-
- Synopsis [Natural logarithm of an ADD.]
-
- Description [Natural logarithm of an ADDs. Returns NULL
- if not a terminal case; log(f) otherwise. The discriminants of f must
- be positive double's.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addMonadicApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addLog(
- DdManager * dd,
- DdNode * f)
-{
- if (cuddIsConstant(f)) {
- CUDD_VALUE_TYPE value = log(cuddV(f));
- DdNode *res = cuddUniqueConst(dd,value);
- return(res);
- }
- return(NULL);
-
-} /* end of Cudd_addLog */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addApply.]
-
- Description [Performs the recursive step of Cudd_addApply. Returns a
- pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddAddMonadicApplyRecur]
-
-******************************************************************************/
-DdNode *
-cuddAddApplyRecur(
- DdManager * dd,
- DdNode * (*op)(DdManager *, DdNode **, DdNode **),
- DdNode * f,
- DdNode * g)
-{
- DdNode *res,
- *fv, *fvn, *gv, *gvn,
- *T, *E;
- unsigned int ford, gord;
- unsigned int index;
- DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
-
- /* Check terminal cases. Op may swap f and g to increase the
- * cache hit rate.
- */
- statLine(dd);
- res = (*op)(dd,&f,&g);
- if (res != NULL) return(res);
-
- /* Check cache. */
- cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) op;
- res = cuddCacheLookup2(dd,cacheOp,f,g);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- ford = cuddI(dd,f->index);
- gord = cuddI(dd,g->index);
- if (ford <= gord) {
- index = f->index;
- fv = cuddT(f);
- fvn = cuddE(f);
- } else {
- index = g->index;
- fv = fvn = f;
- }
- if (gord <= ford) {
- gv = cuddT(g);
- gvn = cuddE(g);
- } else {
- gv = gvn = g;
- }
-
- T = cuddAddApplyRecur(dd,op,fv,gv);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- E = cuddAddApplyRecur(dd,op,fvn,gvn);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- /* Store result. */
- cuddCacheInsert2(dd,cacheOp,f,g,res);
-
- return(res);
-
-} /* end of cuddAddApplyRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addMonadicApply.]
-
- Description [Performs the recursive step of Cudd_addMonadicApply. Returns a
- pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddAddApplyRecur]
-
-******************************************************************************/
-DdNode *
-cuddAddMonadicApplyRecur(
- DdManager * dd,
- DdNode * (*op)(DdManager *, DdNode *),
- DdNode * f)
-{
- DdNode *res, *ft, *fe, *T, *E;
- unsigned int ford;
- unsigned int index;
-
- /* Check terminal cases. */
- statLine(dd);
- res = (*op)(dd,f);
- if (res != NULL) return(res);
-
- /* Check cache. */
- res = cuddCacheLookup1(dd,op,f);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- ford = cuddI(dd,f->index);
- index = f->index;
- ft = cuddT(f);
- fe = cuddE(f);
-
- T = cuddAddMonadicApplyRecur(dd,op,ft);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- E = cuddAddMonadicApplyRecur(dd,op,fe);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- /* Store result. */
- cuddCacheInsert1(dd,op,f,res);
-
- return(res);
-
-} /* end of cuddAddMonadicApplyRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddAddFind.c b/src/bdd/cudd/cuddAddFind.c
deleted file mode 100644
index 0469b014..00000000
--- a/src/bdd/cudd/cuddAddFind.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddFind.c]
-
- PackageName [cudd]
-
- Synopsis [Functions to find maximum and minimum in an ADD and to
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * addDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Finds the maximum discriminant of f.]
-
- Description [Returns a pointer to a constant ADD.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_addFindMax(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *t, *e, *res;
-
- statLine(dd);
- if (cuddIsConstant(f)) {
- return(f);
- }
-
- res = cuddCacheLookup1(dd,Cudd_addFindMax,f);
- if (res != NULL) {
- return(res);
- }
-
- t = Cudd_addFindMax(dd,cuddT(f));
- if (t == DD_PLUS_INFINITY(dd)) return(t);
-
- e = Cudd_addFindMax(dd,cuddE(f));
-
- res = (cuddV(t) >= cuddV(e)) ? t : e;
-
- cuddCacheInsert1(dd,Cudd_addFindMax,f,res);
-
- return(res);
-
-} /* end of Cudd_addFindMax */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the minimum discriminant of f.]
-
- Description [Returns a pointer to a constant ADD.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_addFindMin(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *t, *e, *res;
-
- statLine(dd);
- if (cuddIsConstant(f)) {
- return(f);
- }
-
- res = cuddCacheLookup1(dd,Cudd_addFindMin,f);
- if (res != NULL) {
- return(res);
- }
-
- t = Cudd_addFindMin(dd,cuddT(f));
- if (t == DD_MINUS_INFINITY(dd)) return(t);
-
- e = Cudd_addFindMin(dd,cuddE(f));
-
- res = (cuddV(t) <= cuddV(e)) ? t : e;
-
- cuddCacheInsert1(dd,Cudd_addFindMin,f,res);
-
- return(res);
-
-} /* end of Cudd_addFindMin */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts the i-th bit from an ADD.]
-
- Description [Produces an ADD from another ADD by replacing all
- discriminants whose i-th bit is equal to 1 with 1, and all other
- discriminants with 0. The i-th bit refers to the integer
- representation of the leaf value. If the value is has a fractional
- part, it is ignored. Repeated calls to this procedure allow one to
- transform an integer-valued ADD into an array of ADDs, one for each
- bit of the leaf values. Returns a pointer to the resulting ADD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddIthBit]
-
-******************************************************************************/
-DdNode *
-Cudd_addIthBit(
- DdManager * dd,
- DdNode * f,
- int bit)
-{
- DdNode *res;
- DdNode *index;
-
- /* Use a constant node to remember the bit, so that we can use the
- ** global cache.
- */
- index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit);
- if (index == NULL) return(NULL);
- cuddRef(index);
-
- do {
- dd->reordered = 0;
- res = addDoIthBit(dd, f, index);
- } while (dd->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(dd, index);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, index);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addIthBit */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addIthBit.]
-
- Description [Performs the recursive step for Cudd_addIthBit.
- Returns a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-addDoIthBit(
- DdManager * dd,
- DdNode * f,
- DdNode * index)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int mask, value;
- int v;
-
- 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));
- }
-
- /* Check cache. */
- res = cuddCacheLookup2(dd,addDoIthBit,f,index);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = addDoIthBit(dd,fv,index);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- E = addDoIthBit(dd,fvn,index);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- /* Store result. */
- cuddCacheInsert2(dd,addDoIthBit,f,index,res);
-
- return(res);
-
-} /* end of addDoIthBit */
-
diff --git a/src/bdd/cudd/cuddAddInv.c b/src/bdd/cudd/cuddAddInv.c
deleted file mode 100644
index fc4a340b..00000000
--- a/src/bdd/cudd/cuddAddInv.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddInv.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the scalar inverse of an ADD.]
-
- Description [Computes an n ADD where the discriminants are the
- multiplicative inverses of the corresponding discriminants of the
- argument ADD. Returns a pointer to the resulting ADD in case of
- success. Returns NULL if any discriminants smaller than epsilon is
- encountered.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_addScalarInverse(
- DdManager * dd,
- DdNode * f,
- DdNode * epsilon)
-{
- DdNode *res;
-
- if (!cuddIsConstant(epsilon)) {
- (void) fprintf(dd->err,"Invalid epsilon\n");
- return(NULL);
- }
- do {
- dd->reordered = 0;
- res = cuddAddScalarInverseRecur(dd,f,epsilon);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addScalarInverse */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of addScalarInverse.]
-
- Description [Returns a pointer to the resulting ADD in case of
- success. Returns NULL if any discriminants smaller than epsilon is
- encountered.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-cuddAddScalarInverseRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * epsilon)
-{
- DdNode *t, *e, *res;
- CUDD_VALUE_TYPE value;
-
- statLine(dd);
- if (cuddIsConstant(f)) {
- 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);
- if (res != NULL) return(res);
-
- t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon);
- if (e == 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);
- }
-
- cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res);
-
- return(res);
-
-} /* end of cuddAddScalarInverseRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddAddIte.c b/src/bdd/cudd/cuddAddIte.c
deleted file mode 100644
index 71f8070f..00000000
--- a/src/bdd/cudd/cuddAddIte.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddIte.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static void addVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements ITE(f,g,h).]
-
- Description [Implements ITE(f,g,h). This procedure assumes that f is
- a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply]
-
-******************************************************************************/
-DdNode *
-Cudd_addIte(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddIteRecur(dd,f,g,h);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addIte */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements ITEconstant for ADDs.]
-
- Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD.
- Returns a pointer to the resulting ADD (which may or may not be
- constant) or DD_NON_CONSTANT. No new nodes are created. This function
- can be used, for instance, to check that g has a constant value
- (specified by h) whenever f is 1. If the constant value is unknown,
- then one should use Cudd_addEvalConst.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant]
-
-******************************************************************************/
-DdNode *
-Cudd_addIteConstant(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *one,*zero;
- DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e;
- unsigned int topf,topg,toph,v;
-
- statLine(dd);
- /* Trivial cases. */
- if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
- return(g);
- }
- if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
- return(h);
- }
-
- /* From now on, f is known not to be a constant. */
- addVarToConst(f,&g,&h,one,zero);
-
- /* Check remaining one variable cases. */
- if (g == h) { /* ITE(F,G,G) = G */
- return(g);
- }
- if (cuddIsConstant(g) && cuddIsConstant(h)) {
- return(DD_NON_CONSTANT);
- }
-
- topf = cuddI(dd,f->index);
- topg = cuddI(dd,g->index);
- toph = cuddI(dd,h->index);
- v = ddMin(topg,toph);
-
- /* 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);
- }
-
- /* Check cache. */
- r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h);
- if (r != NULL) {
- return(r);
- }
-
- /* Compute cofactors. */
- if (topf <= v) {
- v = ddMin(topf,v); /* v = top_var(F,G,H) */
- Fv = cuddT(f); Fnv = cuddE(f);
- } else {
- Fv = Fnv = f;
- }
- if (topg == v) {
- Gv = cuddT(g); Gnv = cuddE(g);
- } else {
- Gv = Gnv = g;
- }
- if (toph == v) {
- Hv = cuddT(h); Hnv = cuddE(h);
- } else {
- Hv = Hnv = h;
- }
-
- /* 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);
- }
- 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, t);
- return(t);
-
-} /* end of Cudd_addIteConstant */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether ADD g is constant whenever ADD f is 1.]
-
- Description [Checks whether ADD g is constant whenever ADD f is 1. f
- must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may
- or may not be constant) or DD_NON_CONSTANT. If f is identically 0,
- the check is assumed to be successful, and the background value is
- returned. No new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addIteConstant Cudd_addLeq]
-
-******************************************************************************/
-DdNode *
-Cudd_addEvalConst(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *zero;
- DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e;
- unsigned int topf,topg;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- statLine(dd);
- /* Terminal cases. */
- if (f == DD_ONE(dd) || cuddIsConstant(g)) {
- return(g);
- }
- if (f == (zero = DD_ZERO(dd))) {
- return(dd->background);
- }
-
-#ifdef DD_DEBUG
- assert(!cuddIsConstant(f));
-#endif
- /* From now on, f and g are known not to be constants. */
-
- topf = cuddI(dd,f->index);
- topg = cuddI(dd,g->index);
-
- /* Check cache. */
- r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g);
- if (r != NULL) {
- return(r);
- }
-
- /* Compute cofactors. */
- if (topf <= topg) {
- Fv = cuddT(f); Fnv = cuddE(f);
- } else {
- Fv = Fnv = f;
- }
- if (topg <= topf) {
- Gv = cuddT(g); Gnv = cuddE(g);
- } else {
- Gv = Gnv = g;
- }
-
- /* 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);
- }
- }
- 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);
- }
-
-} /* end of Cudd_addEvalConst */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the complement of an ADD a la C language.]
-
- Description [Computes the complement of an ADD a la C language: The
- complement of 0 is 1 and the complement of everything else is 0.
- Returns a pointer to the resulting ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNegate]
-
-******************************************************************************/
-DdNode *
-Cudd_addCmpl(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddCmplRecur(dd,f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addCmpl */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines whether f is less than or equal to g.]
-
- Description [Returns 1 if f is less than or equal to g; 0 otherwise.
- No new nodes are created. This procedure works for arbitrary ADDs.
- For 0-1 ADDs Cudd_addEvalConst is more efficient.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq]
-
-******************************************************************************/
-int
-Cudd_addLeq(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *tmp, *fv, *fvn, *gv, *gvn;
- unsigned int topf, topg, res;
-
- /* Terminal cases. */
- if (f == g) return(1);
-
- 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 (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);
- if (tmp != NULL) {
- 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);
- } else {
- fv = fvn = f;
- }
- if (topg <= topf) {
- gv = cuddT(g); gvn = cuddE(g);
- } else {
- 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));
- return(res);
-
-} /* end of Cudd_addLeq */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).]
-
- Description [Implements the recursive step of Cudd_addIte(f,g,h).
- Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addIte]
-
-******************************************************************************/
-DdNode *
-cuddAddIteRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *one,*zero;
- DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
- unsigned int topf,topg,toph,v;
- int index;
-
- statLine(dd);
- /* Trivial cases. */
-
- /* One variable cases. */
- if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
- return(g);
- }
- if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
- return(h);
- }
-
- /* From now on, f is known to not be a constant. */
- addVarToConst(f,&g,&h,one,zero);
-
- /* Check remaining one variable cases. */
- if (g == h) { /* ITE(F,G,G) = G */
- return(g);
- }
-
- if (g == one) { /* ITE(F,1,0) = F */
- if (h == zero) return(f);
- }
-
- topf = cuddI(dd,f->index);
- topg = cuddI(dd,g->index);
- toph = cuddI(dd,h->index);
- v = ddMin(topg,toph);
-
- /* 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);
- }
- if (topf < v && cuddT(f) == zero && cuddE(f) == one) {
- r = cuddUniqueInter(dd,(int)f->index,h,g);
- return(r);
- }
-
- /* Check cache. */
- r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h);
- if (r != NULL) {
- return(r);
- }
-
- /* Compute cofactors. */
- if (topf <= v) {
- 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;
- Gv = cuddT(g); Gnv = cuddE(g);
- } else {
- Gv = Gnv = g;
- }
- if (toph == v) {
- index = h->index;
- Hv = cuddT(h); Hnv = cuddE(h);
- } else {
- Hv = Hnv = h;
- }
-
- /* Recursive step. */
- t = cuddAddIteRecur(dd,Fv,Gv,Hv);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
- if (e == 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);
- }
- cuddDeref(t);
- cuddDeref(e);
-
- cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r);
-
- return(r);
-
-} /* end of cuddAddIteRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addCmpl.]
-
- Description [Performs the recursive step of Cudd_addCmpl. Returns a
- pointer to the resulting ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addCmpl]
-
-******************************************************************************/
-DdNode *
-cuddAddCmplRecur(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *one,*zero;
- DdNode *r,*Fv,*Fnv,*t,*e;
-
- statLine(dd);
- one = DD_ONE(dd);
- zero = DD_ZERO(dd);
-
- if (cuddIsConstant(f)) {
- if (f == zero) {
- return(one);
- } else {
- return(zero);
- }
- }
- r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
- if (r != NULL) {
- return(r);
- }
- Fv = cuddT(f);
- Fnv = cuddE(f);
- t = cuddAddCmplRecur(dd,Fv);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = cuddAddCmplRecur(dd,Fnv);
- if (e == 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);
- }
- cuddDeref(t);
- cuddDeref(e);
- cuddCacheInsert1(dd,Cudd_addCmpl,f,r);
- return(r);
-
-} /* end of cuddAddCmplRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Replaces variables with constants if possible (part of
- canonical form).]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-addVarToConst(
- DdNode * f,
- DdNode ** gp,
- DdNode ** hp,
- DdNode * one,
- DdNode * zero)
-{
- DdNode *g = *gp;
- DdNode *h = *hp;
-
- if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
- *gp = one;
- }
-
- if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
- *hp = zero;
- }
-
-} /* end of addVarToConst */
diff --git a/src/bdd/cudd/cuddAddNeg.c b/src/bdd/cudd/cuddAddNeg.c
deleted file mode 100644
index bdb08ddc..00000000
--- a/src/bdd/cudd/cuddAddNeg.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddNeg.c]
-
- PackageName [cudd]
-
- 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> ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Computes the additive inverse of an ADD.]
-
- Description [Computes the additive inverse of an ADD. Returns a pointer
- to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addCmpl]
-
-******************************************************************************/
-DdNode *
-Cudd_addNegate(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res;
-
- do {
- res = cuddAddNegateRecur(dd,f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addNegate */
-
-
-/**Function********************************************************************
-
- Synopsis [Rounds off the discriminants of an ADD.]
-
- Description [Rounds off the discriminants of an ADD. The discriminants are
- rounded off to N digits after the decimal. Returns a pointer to the result
- ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_addRoundOff(
- DdManager * dd,
- DdNode * f,
- int N)
-{
- DdNode *res;
- double trunc = pow(10.0,(double)N);
-
- do {
- res = cuddAddRoundOffRecur(dd,f,trunc);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addRoundOff */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_addNegate.]
-
- Description [Implements the recursive step of Cudd_addNegate.
- Returns a pointer to the result.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-cuddAddNegateRecur(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res,
- *fv, *fvn,
- *T, *E;
-
- statLine(dd);
- /* Check terminal cases. */
- if (cuddIsConstant(f)) {
- res = cuddUniqueConst(dd,-cuddV(f));
- return(res);
- }
-
- /* Check cache */
- res = cuddCacheLookup1(dd,Cudd_addNegate,f);
- if (res != NULL) return(res);
-
- /* Recursive Step */
- fv = cuddT(f);
- fvn = cuddE(f);
- T = cuddAddNegateRecur(dd,fv);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- E = cuddAddNegateRecur(dd,fvn);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- /* Store result. */
- cuddCacheInsert1(dd,Cudd_addNegate,f,res);
-
- return(res);
-
-} /* end of cuddAddNegateRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_addRoundOff.]
-
- Description [Implements the recursive step of Cudd_addRoundOff.
- Returns a pointer to the result.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-cuddAddRoundOffRecur(
- DdManager * dd,
- DdNode * f,
- double trunc)
-{
-
- DdNode *res, *fv, *fvn, *T, *E;
- double n;
- DdNode *(*cacheOp)(DdManager *, DdNode *);
-
- statLine(dd);
- if (cuddIsConstant(f)) {
- n = ceil(cuddV(f)*trunc)/trunc;
- res = cuddUniqueConst(dd,n);
- return(res);
- }
- cacheOp = (DdNode *(*)(DdManager *, DdNode *)) Cudd_addRoundOff;
- res = cuddCacheLookup1(dd,cacheOp,f);
- if (res != NULL) {
- return(res);
- }
- /* Recursive Step */
- fv = cuddT(f);
- fvn = cuddE(f);
- T = cuddAddRoundOffRecur(dd,fv,trunc);
- if (T == NULL) {
- return(NULL);
- }
- cuddRef(T);
- E = cuddAddRoundOffRecur(dd,fvn,trunc);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- /* Store result. */
- cuddCacheInsert1(dd,cacheOp,f,res);
- return(res);
-
-} /* end of cuddAddRoundOffRecur */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddAddWalsh.c b/src/bdd/cudd/cuddAddWalsh.c
deleted file mode 100644
index c6a67e34..00000000
--- a/src/bdd/cudd/cuddAddWalsh.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAddWalsh.c]
-
- PackageName [cudd]
-
- Synopsis [Functions that generate Walsh matrices and residue
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * addWalshInt ARGS((DdManager *dd, DdNode **x, DdNode **y, int n));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a Walsh matrix in ADD form.]
-
- Description [Generates a Walsh matrix in ADD form. Returns a pointer
- to the matrixi if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_addWalsh(
- DdManager * dd,
- DdNode ** x,
- DdNode ** y,
- int n)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = addWalshInt(dd, x, y, n);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addWalsh */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds an ADD for the residue modulo m of an n-bit
- number.]
-
- Description [Builds an ADD for the residue modulo m of an n-bit
- number. The modulus must be at least 2, and the number of bits at
- least 1. Parameter options specifies whether the MSB should be on top
- or the LSB; and whther the number whose residue is computed is in
- two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT
- specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB
- specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's
- complement residue. To request MSB on top and two's complement residue
- simultaneously, one can OR the two macros:
- CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC.
- Cudd_addResidue returns a pointer to the resulting ADD if successful;
- NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_addResidue(
- DdManager * dd /* manager */,
- int n /* number of bits */,
- int m /* modulus */,
- 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 i, j, k, t, residue, thisOne, previous, index;
- DdNode **array[2], *var, *tmp, *res;
-
- /* Sanity check. */
- if (n < 1 && m < 2) return(NULL);
-
- msbLsb = options & CUDD_RESIDUE_MSB;
- tc = options & CUDD_RESIDUE_TC;
-
- /* Allocate and initialize working arrays. */
- array[0] = ALLOC(DdNode *,m);
- if (array[0] == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- array[1] = ALLOC(DdNode *,m);
- if (array[1] == NULL) {
- FREE(array[0]);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < m; i++) {
- 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]);
- }
- FREE(array[0]);
- FREE(array[1]);
- return(NULL);
- }
- cuddRef(tmp);
- array[1][i] = tmp;
- }
-
- /* Main iteration. */
- 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]);
- }
- FREE(array[0]);
- 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]);
- }
- for (j = 0; j < m; j++) {
- Cudd_RecursiveDeref(dd,array[previous][j]);
- }
- FREE(array[0]);
- FREE(array[1]);
- return(NULL);
- }
- 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]);
- }
- res = array[(n - 1) & 1][0];
-
- FREE(array[0]);
- FREE(array[1]);
-
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addResidue */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_addWalsh.]
-
- Description [Generates a Walsh matrix in ADD form. Returns a pointer
- to the matrixi if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-addWalshInt(
- DdManager * dd,
- DdNode ** x,
- DdNode ** y,
- int n)
-{
- DdNode *one, *minusone;
- DdNode *t, *u, *t1, *u1, *v, *w;
- int i;
-
- one = DD_ONE(dd);
- if (n == 0) return(one);
-
- /* Build bottom part of ADD outside loop */
- minusone = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) -1);
- if (minusone == NULL) return(NULL);
- cuddRef(minusone);
- v = Cudd_addIte(dd, y[n-1], minusone, one);
- if (v == 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);
- }
- 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);
- 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);
- }
- 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);
- }
-
- cuddDeref(u);
- return(u);
-
-} /* end of addWalshInt */
diff --git a/src/bdd/cudd/cuddAndAbs.c b/src/bdd/cudd/cuddAndAbs.c
deleted file mode 100644
index 5ec47beb..00000000
--- a/src/bdd/cudd/cuddAndAbs.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAndAbs.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
- variables in cube.]
-
- Description [Takes the AND of two BDDs and simultaneously abstracts
- the variables in cube. The variables are existentially abstracted.
- Returns a pointer to the result is successful; NULL otherwise.
- Cudd_bddAndAbstract implements the semiring matrix multiplication
- algorithm for the boolean semiring.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]
-
-******************************************************************************/
-DdNode *
-Cudd_bddAndAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube)
-{
- DdNode *res;
-
- do {
- manager->reordered = 0;
- res = cuddBddAndAbstractRecur(manager, f, g, cube);
- } while (manager->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddAndAbstract */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
- variables in cube.]
-
- Description [Takes the AND of two BDDs and simultaneously abstracts
- the variables in cube. The variables are existentially abstracted.
- Returns a pointer to the result is successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddAndAbstract]
-
-******************************************************************************/
-DdNode *
-cuddBddAndAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube)
-{
- DdNode *F, *ft, *fe, *G, *gt, *ge;
- DdNode *one, *zero, *r, *t, *e;
- unsigned int topf, topg, topcube, top, index;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
- if (f == one && g == one) return(one);
-
- if (cube == one) {
- return(cuddBddAndRecur(manager, f, g));
- }
- if (f == one || f == g) {
- return(cuddBddExistAbstractRecur(manager, g, cube));
- }
- if (g == one) {
- 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;
- }
-
- /* Here we can skip the use of cuddI, because the operands are known
- ** to be non-constant.
- */
- F = Cudd_Regular(f);
- G = Cudd_Regular(g);
- topf = manager->perm[F->index];
- topg = manager->perm[G->index];
- top = ddMin(topf, topg);
- topcube = manager->perm[cube->index];
-
- while (topcube < top) {
- 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);
- }
- }
-
- if (topf == top) {
- 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;
- }
-
- if (topg == top) {
- gt = cuddT(G);
- ge = cuddE(G);
- if (Cudd_IsComplement(g)) {
- gt = Cudd_Not(gt);
- ge = Cudd_Not(ge);
- }
- } else {
- 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);
- }
- 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) {
- 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)
- cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
- return (r);
-
-} /* end of cuddBddAndAbstractRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddAnneal.c b/src/bdd/cudd/cuddAnneal.c
deleted file mode 100644
index 3d8b56b9..00000000
--- a/src/bdd/cudd/cuddAnneal.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddAnneal.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Annealing parameters */
-#define BETA 0.6
-#define ALPHA 0.90
-#define EXC_PROB 0.4
-#define JUMP_UP_PROB 0.36
-#define MAXGEN_RATIO 15.0
-#define STOP_TEMP 1.0
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-#ifdef DD_STATS
-extern int ddTotalNumberSwapping;
-extern int ddTotalNISwaps;
-static int tosses;
-static int acceptances;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Get new variable-order by simulated annealing algorithm.]
-
- Description [Get x, y by random selection. Choose either
- exchange or jump randomly. In case of jump, choose between jump_up
- and jump_down randomly. Do exchange or jump and get optimal case.
- Loop until there is no improvement or temperature reaches
- minimum. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddAnnealing(
- DdManager * table,
- int lower,
- int upper)
-{
- int nvars;
- int size;
- int x,y;
- int result;
- int c1, c2, c3, c4;
- int BestCost;
- int *BestOrder;
- double NewTemp, temp;
- double rand1;
- int innerloop, maxGen;
- int ecount, ucount, dcount;
-
- nvars = upper - lower + 1;
-
- result = cuddSifting(table,lower,upper);
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
-#endif
- if (result == 0) return(0);
-
- size = table->keys - table->isolated;
-
- /* Keep track of the best order. */
- BestCost = size;
- BestOrder = ALLOC(int,nvars);
- if (BestOrder == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- copyOrder(table,BestOrder,lower,upper);
-
- temp = BETA * size;
- maxGen = (int) (MAXGEN_RATIO * nvars);
-
- c1 = size + 10;
- c2 = c1 + 10;
- c3 = size;
- c4 = c2 + 10;
- ecount = ucount = dcount = 0;
-
- 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;
-#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++;
-#if 0
- (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++;
-#if 0
- (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++;
-#if 0
- (void) fprintf(table->out,
- "Jump down of %d to %d: size = %d\n",
- x,y,table->keys - table->isolated);
-#endif
- }
-
- if (!result) {
- 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);
- }
- temp = NewTemp; /* control variable */
-#ifdef DD_STATS
- (void) fprintf(table->out,"uphill = %d\taccepted = %d\n",
- tosses,acceptances);
- fflush(table->out);
-#endif
- }
-
- result = restoreOrder(table,BestOrder,lower,upper);
- FREE(BestOrder);
- if (!result) return(0);
-#ifdef DD_STATS
- fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount);
- fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount);
- fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount);
-#endif
- return(1);
-
-} /* end of cuddAnnealing */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Checks termination condition.]
-
- Description [If temperature is STOP_TEMP or there is no improvement
- then terminates. Returns 1 if the termination criterion is met; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-stopping_criterion(
- int c1,
- int c2,
- int c3,
- int c4,
- double temp)
-{
- if (STOP_TEMP < temp) {
- return(0);
- } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) {
- return(1);
- } else {
- return(0);
- }
-
-} /* end of stopping_criterion */
-
-
-/**Function********************************************************************
-
- Synopsis [Random number generator.]
-
- Description [Returns a double precision value between 0.0 and 1.0.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double
-random_generator(
- )
-{
- return((double)(Cudd_Random() / 2147483561.0));
-
-} /* end of random_generator */
-
-
-/**Function********************************************************************
-
- Synopsis [This function is for exchanging two variables, x and y.]
-
- Description [This is the same funcion as ddSwapping except for
- comparison expression. Use probability function, exp(-size_change/temp).]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddExchange(
- DdManager * table,
- int x,
- int y,
- double temp)
-{
- Move *move,*moves;
- int tmp;
- int x_ref,y_ref;
- int x_next,y_next;
- int size, result;
- int initial_size, limit_size;
-
- x_ref = x;
- y_ref = y;
-
- x_next = cuddNextHigh(table,x);
- y_next = cuddNextLow(table,y);
- moves = NULL;
- 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;
- }
-
- 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 (y_next>=x_ref) {
- 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;
- }
-
- /* move backward and stop at best position or accept uphill move */
- result = siftBackwardProb(table,moves,initial_size,temp);
- if (!result) goto ddExchangeOutOfMem;
-
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(1);
-
-ddExchangeOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table,(DdNode *) moves);
- moves = move;
- }
- return(0);
-
-} /* end of ddExchange */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves a variable to a specified position.]
-
- Description [If x==x_low, it executes jumping_down. If x==x_high, it
- executes jumping_up. This funcion is similar to ddSiftingAux. Returns
- 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddJumpingAux(
- DdManager * table,
- int x,
- int x_low,
- int x_high,
- double temp)
-{
- Move *move;
- Move *moves; /* list of moves */
- int initial_size;
- int result;
-
- initial_size = table->keys - table->isolated;
-
-#ifdef DD_DEBUG
- assert(table->subtables[x].keys > 0);
-#endif
-
- 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;
- } 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;
- } else {
- (void) fprintf(table->err,"Unexpected condition in ddJumping\n");
- goto ddJumpingAuxOutOfMem;
- }
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(1);
-
-ddJumpingAuxOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(0);
-
-} /* end of ddJumpingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [This function is for jumping up.]
-
- Description [This is a simplified version of ddSiftingUp. It does not
- use lower bounding. Returns the set of moves in case of success; NULL
- if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-ddJumpingUp(
- DdManager * table,
- int x,
- int x_low,
- int initial_size)
-{
- Move *moves;
- Move *move;
- int y;
- int size;
- int limit_size = initial_size;
-
- 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);
- }
- return(moves);
-
-ddJumpingUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(NULL);
-
-} /* end of ddJumpingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [This function is for jumping down.]
-
- Description [This is a simplified version of ddSiftingDown. It does not
- use lower bounding. Returns the set of moves in case of success; NULL
- if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-ddJumpingDown(
- DdManager * table,
- int x,
- int x_high,
- int initial_size)
-{
- Move *moves;
- Move *move;
- int y;
- int size;
- int limit_size = initial_size;
-
- 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);
- }
- return(moves);
-
-ddJumpingDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(NULL);
-
-} /* end of ddJumpingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the DD to the best position encountered during
- sifting if there was improvement.]
-
- Description [Otherwise, "tosses a coin" to decide whether to keep
- the current configuration or return the DD to the original
- one. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-siftBackwardProb(
- DdManager * table,
- Move * moves,
- int size,
- double temp)
-{
- Move *move;
- int res;
- int best_size = size;
- double coin, threshold;
-
- /* 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 best_size equals size, the last sifting did not produce any
- ** improvement. We now toss a coin to decide whether to retain
- ** this change or not.
- */
- if (best_size == size) {
- coin = random_generator();
-#ifdef DD_STATS
- tosses++;
-#endif
- threshold = exp(-((double)(table->keys - table->isolated - size))/temp);
- if (coin < threshold) {
-#ifdef DD_STATS
- acceptances++;
-#endif
- return(1);
- }
- }
-
- /* Either there was improvement, or we have decided not to
- ** accept the uphill move. Go to best position.
- */
- 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);
- }
-
- return(1);
-
-} /* end of sift_backward_prob */
-
-
-/**Function********************************************************************
-
- Synopsis [Copies the current variable order to array.]
-
- Description [Copies the current variable order to array.
- At the same time inverts the permutation.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-copyOrder(
- DdManager * table,
- int * array,
- int lower,
- int upper)
-{
- int i;
- int nvars;
-
- nvars = upper - lower + 1;
- for (i = 0; i < nvars; i++) {
- array[i] = table->invperm[i+lower];
- }
-
-} /* end of copyOrder */
-
-
-/**Function********************************************************************
-
- Synopsis [Restores the variable order in array by a series of sifts up.]
-
- Description [Restores the variable order in array by a series of sifts up.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-restoreOrder(
- DdManager * table,
- int * array,
- int lower,
- int upper)
-{
- int i, x, y, size;
- int nvars = upper - lower + 1;
-
- for (i = 0; i < nvars; 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);
- }
- }
-
- return(1);
-
-} /* end of restoreOrder */
-
diff --git a/src/bdd/cudd/cuddApa.c b/src/bdd/cudd/cuddApa.c
deleted file mode 100644
index 47ab51e8..00000000
--- a/src/bdd/cudd/cuddApa.c
+++ /dev/null
@@ -1,930 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddApa.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-static DdNode *background, *zero;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the number of digits for an arbitrary precision
- integer.]
-
- Description [Finds the number of digits for an arbitrary precision
- integer given the maximum number of binary digits. The number of
- binary digits should be positive. Returns the number of digits if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_ApaNumberOfDigits(
- int binaryDigits)
-{
- int digits;
-
- digits = binaryDigits / DD_APA_BITS;
- if ((digits * DD_APA_BITS) != binaryDigits)
- digits++;
- return(digits);
-
-} /* end of Cudd_ApaNumberOfDigits */
-
-
-/**Function********************************************************************
-
- Synopsis [Allocates memory for an arbitrary precision integer.]
-
- Description [Allocates memory for an arbitrary precision
- integer. Returns a pointer to the allocated memory if successful;
- NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdApaNumber
-Cudd_NewApaNumber(
- int digits)
-{
- return(ALLOC(DdApaDigit, digits));
-
-} /* end of Cudd_NewApaNumber */
-
-
-/**Function********************************************************************
-
- Synopsis [Makes a copy of an arbitrary precision integer.]
-
- Description [Makes a copy of an arbitrary precision integer.]
-
- SideEffects [Changes parameter <code>dest</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_ApaCopy(
- int digits,
- DdApaNumber source,
- DdApaNumber dest)
-{
- int i;
-
- for (i = 0; i < digits; i++) {
- dest[i] = source[i];
- }
-
-} /* end of Cudd_ApaCopy */
-
-
-/**Function********************************************************************
-
- Synopsis [Adds two arbitrary precision integers.]
-
- Description [Adds two arbitrary precision integers. Returns the
- carry out of the most significant digit.]
-
- SideEffects [The result of the sum is stored in parameter <code>sum</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-DdApaDigit
-Cudd_ApaAdd(
- int digits,
- DdApaNumber a,
- DdApaNumber b,
- DdApaNumber sum)
-{
- int i;
- DdApaDoubleDigit partial = 0;
-
- for (i = digits - 1; i >= 0; i--) {
- partial = a[i] + b[i] + DD_MSDIGIT(partial);
- sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
- }
- return(DD_MSDIGIT(partial));
-
-} /* end of Cudd_ApaAdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Subtracts two arbitrary precision integers.]
-
- Description [Subtracts two arbitrary precision integers. Returns the
- borrow out of the most significant digit.]
-
- SideEffects [The result of the subtraction is stored in parameter
- <code>diff</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-DdApaDigit
-Cudd_ApaSubtract(
- int digits,
- DdApaNumber a,
- DdApaNumber b,
- DdApaNumber diff)
-{
- int i;
- 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);
- }
- return(DD_MSDIGIT(partial) - 1);
-
-} /* end of Cudd_ApaSubtract */
-
-
-/**Function********************************************************************
-
- Synopsis [Divides an arbitrary precision integer by a digit.]
-
- Description [Divides an arbitrary precision integer by a digit.]
-
- SideEffects [The quotient is returned in parameter <code>quotient</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-DdApaDigit
-Cudd_ApaShortDivision(
- int digits,
- DdApaNumber dividend,
- DdApaDigit divisor,
- DdApaNumber quotient)
-{
- int i;
- DdApaDigit remainder;
- DdApaDoubleDigit partial;
-
- 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);
- }
-
- return(remainder);
-
-} /* end of Cudd_ApaShortDivision */
-
-
-/**Function********************************************************************
-
- Synopsis [Divides an arbitrary precision integer by an integer.]
-
- Description [Divides an arbitrary precision integer by a 32-bit
- unsigned integer. Returns the remainder of the division. This
- procedure relies on the assumption that the number of bits of a
- DdApaDigit plus the number of bits of an unsigned int is less the
- number of bits of the mantissa of a double. This guarantees that the
- product of a DdApaDigit and an unsigned int can be represented
- without loss of precision by a double. On machines where this
- assumption is not satisfied, this procedure will malfunction.]
-
- SideEffects [The quotient is returned in parameter <code>quotient</code>.]
-
- SeeAlso [Cudd_ApaShortDivision]
-
-******************************************************************************/
-unsigned int
-Cudd_ApaIntDivision(
- int digits,
- DdApaNumber dividend,
- unsigned int divisor,
- DdApaNumber quotient)
-{
- int i;
- double partial;
- unsigned int remainder = 0;
- 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));
- }
-
- return(remainder);
-
-} /* end of Cudd_ApaIntDivision */
-
-
-/**Function********************************************************************
-
- Synopsis [Shifts right an arbitrary precision integer by one binary
- place.]
-
- Description [Shifts right an arbitrary precision integer by one
- binary place. The most significant binary digit of the result is
- taken from parameter <code>in</code>.]
-
- SideEffects [The result is returned in parameter <code>b</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_ApaShiftRight(
- int digits,
- DdApaDigit in,
- DdApaNumber a,
- DdApaNumber b)
-{
- int i;
-
- for (i = digits - 1; i > 0; i--) {
- b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
- }
- b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));
-
-} /* end of Cudd_ApaShiftRight */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets an arbitrary precision integer to a one-digit literal.]
-
- Description [Sets an arbitrary precision integer to a one-digit literal.]
-
- SideEffects [The result is returned in parameter <code>number</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_ApaSetToLiteral(
- int digits,
- DdApaNumber number,
- DdApaDigit literal)
-{
- int i;
-
- for (i = 0; i < digits - 1; i++)
- number[i] = 0;
- number[digits - 1] = literal;
-
-} /* end of Cudd_ApaSetToLiteral */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets an arbitrary precision integer to a power of two.]
-
- Description [Sets an arbitrary precision integer to a power of
- two. If the power of two is too large to be represented, the number
- is set to 0.]
-
- SideEffects [The result is returned in parameter <code>number</code>.]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_ApaPowerOfTwo(
- int digits,
- DdApaNumber number,
- int power)
-{
- int i;
- int index;
-
- for (i = 0; i < digits; i++)
- number[i] = 0;
- i = digits - 1 - power / DD_APA_BITS;
- if (i < 0) return;
- index = power & (DD_APA_BITS - 1);
- number[i] = 1 << index;
-
-} /* end of Cudd_ApaPowerOfTwo */
-
-
-/**Function********************************************************************
-
- Synopsis [Compares two arbitrary precision integers.]
-
- Description [Compares two arbitrary precision integers. Returns 1 if
- the first number is larger; 0 if they are equal; -1 if the second
- number is larger.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_ApaCompare(
- int digitsFirst,
- DdApaNumber first,
- int digitsSecond,
- DdApaNumber second)
-{
- int i;
- int firstNZ, secondNZ;
-
- /* Find first non-zero in both numbers. */
- for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++)
- if (first[firstNZ] != 0) break;
- for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++)
- 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);
- }
- return(0);
-
-} /* end of Cudd_ApaCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Compares the ratios of two arbitrary precision integers to two
- unsigned ints.]
-
- Description [Compares the ratios of two arbitrary precision integers
- to two unsigned ints. Returns 1 if the first number is larger; 0 if
- they are equal; -1 if the second number is larger.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_ApaCompareRatios(
- int digitsFirst,
- DdApaNumber firstNum,
- unsigned int firstDen,
- int digitsSecond,
- DdApaNumber secondNum,
- unsigned int secondDen)
-{
- int result;
- DdApaNumber first, second;
- unsigned int firstRem, secondRem;
-
- first = Cudd_NewApaNumber(digitsFirst);
- firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first);
- second = Cudd_NewApaNumber(digitsSecond);
- secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second);
- result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second);
- if (result == 0) {
- if ((double)firstRem/firstDen > (double)secondRem/secondDen)
- return(1);
- else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
- return(-1);
- }
- return(result);
-
-} /* end of Cudd_ApaCompareRatios */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints an arbitrary precision integer in hexadecimal format.]
-
- Description [Prints an arbitrary precision integer in hexadecimal format.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential]
-
-******************************************************************************/
-int
-Cudd_ApaPrintHex(
- FILE * fp,
- int digits,
- DdApaNumber number)
-{
- int i, result;
-
- for (i = 0; i < digits; i++) {
- result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
- if (result == EOF)
- return(0);
- }
- return(1);
-
-} /* end of Cudd_ApaPrintHex */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints an arbitrary precision integer in decimal format.]
-
- Description [Prints an arbitrary precision integer in decimal format.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential]
-
-******************************************************************************/
-int
-Cudd_ApaPrintDecimal(
- FILE * fp,
- int digits,
- DdApaNumber number)
-{
- int i, result;
- DdApaDigit remainder;
- DdApaNumber work;
- unsigned char *decimal;
- int leadingzero;
- int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
-
- work = Cudd_NewApaNumber(digits);
- if (work == NULL)
- return(0);
- decimal = ALLOC(unsigned char, decimalDigits);
- if (decimal == NULL) {
- 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;
- }
- 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) {
- FREE(decimal);
- return(0);
- }
- }
- }
- FREE(decimal);
- return(1);
-
-} /* end of Cudd_ApaPrintDecimal */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints an arbitrary precision integer in exponential format.]
-
- Description [Prints an arbitrary precision integer in exponential format.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal]
-
-******************************************************************************/
-int
-Cudd_ApaPrintExponential(
- FILE * fp,
- int digits,
- DdApaNumber number,
- int precision)
-{
- int i, first, last, result;
- DdApaDigit remainder;
- DdApaNumber work;
- unsigned char *decimal;
- int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
-
- work = Cudd_NewApaNumber(digits);
- if (work == NULL)
- return(0);
- decimal = ALLOC(unsigned char, decimalDigits);
- if (decimal == NULL) {
- 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 */
- }
- 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) {
- FREE(decimal);
- return(0);
- }
- }
- FREE(decimal);
- result = fprintf(fp,"e+%d",decimalDigits - first - 1);
- if (result == EOF) {
- return(0);
- }
- return(1);
-
-} /* end of Cudd_ApaPrintExponential */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms of a DD.]
-
- Description [Counts the number of minterms of a DD. The function is
- assumed to depend on nvars variables. The minterm count is
- represented as an arbitrary precision unsigned integer, to allow for
- any number of variables CUDD supports. Returns a pointer to the
- array representing the number of minterms of the function rooted at
- node if successful; NULL otherwise.]
-
- SideEffects [The number of digits of the result is returned in
- parameter <code>digits</code>.]
-
- SeeAlso [Cudd_CountMinterm]
-
-******************************************************************************/
-DdApaNumber
-Cudd_ApaCountMinterm(
- DdManager * manager,
- DdNode * node,
- int nvars,
- int * digits)
-{
- DdApaNumber max, min;
- st_table *table;
- DdApaNumber i,count;
-
- background = manager->background;
- zero = Cudd_Not(manager->one);
-
- *digits = Cudd_ApaNumberOfDigits(nvars+1);
- max = Cudd_NewApaNumber(*digits);
- if (max == NULL) {
- return(NULL);
- }
- Cudd_ApaPowerOfTwo(*digits,max,nvars);
- min = Cudd_NewApaNumber(*digits);
- if (min == NULL) {
- FREE(max);
- return(NULL);
- }
- Cudd_ApaSetToLiteral(*digits,min,0);
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) {
- FREE(max);
- FREE(min);
- return(NULL);
- }
- i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table);
- if (i == NULL) {
- FREE(max);
- FREE(min);
- st_foreach(table, cuddApaStCountfree, NULL);
- st_free_table(table);
- return(NULL);
- }
- count = Cudd_NewApaNumber(*digits);
- if (count == NULL) {
- FREE(max);
- FREE(min);
- st_foreach(table, cuddApaStCountfree, NULL);
- st_free_table(table);
- if (Cudd_Regular(node)->ref == 1) FREE(i);
- return(NULL);
- }
- if (Cudd_IsComplement(node)) {
- (void) Cudd_ApaSubtract(*digits,max,i,count);
- } else {
- Cudd_ApaCopy(*digits,i,count);
- }
- FREE(max);
- FREE(min);
- st_foreach(table, cuddApaStCountfree, NULL);
- st_free_table(table);
- if (Cudd_Regular(node)->ref == 1) FREE(i);
- return(count);
-
-} /* end of Cudd_ApaCountMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the number of minterms of a BDD or ADD using
- arbitrary precision arithmetic.]
-
- Description [Prints the number of minterms of a BDD or ADD using
- arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ApaPrintMintermExp]
-
-******************************************************************************/
-int
-Cudd_ApaPrintMinterm(
- FILE * fp,
- DdManager * dd,
- DdNode * node,
- int nvars)
-{
- int digits;
- int result;
- DdApaNumber count;
-
- count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
- if (count == NULL)
- return(0);
- result = Cudd_ApaPrintDecimal(fp,digits,count);
- FREE(count);
- if (fprintf(fp,"\n") == EOF) {
- return(0);
- }
- return(result);
-
-} /* end of Cudd_ApaPrintMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the number of minterms of a BDD or ADD in exponential
- format using arbitrary precision arithmetic.]
-
- Description [Prints the number of minterms of a BDD or ADD in
- exponential format using arbitrary precision arithmetic. Parameter
- precision controls the number of signficant digits printed. Returns
- 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ApaPrintMinterm]
-
-******************************************************************************/
-int
-Cudd_ApaPrintMintermExp(
- FILE * fp,
- DdManager * dd,
- DdNode * node,
- int nvars,
- int precision)
-{
- int digits;
- int result;
- DdApaNumber count;
-
- count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
- if (count == NULL)
- return(0);
- result = Cudd_ApaPrintExponential(fp,digits,count,precision);
- FREE(count);
- if (fprintf(fp,"\n") == EOF) {
- return(0);
- }
- return(result);
-
-} /* end of Cudd_ApaPrintMintermExp */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the density of a BDD or ADD using
- arbitrary precision arithmetic.]
-
- Description [Prints the density of a BDD or ADD using
- arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_ApaPrintDensity(
- FILE * fp,
- DdManager * dd,
- DdNode * node,
- int nvars)
-{
- int digits;
- int result;
- DdApaNumber count,density;
- unsigned int size, remainder, fractional;
-
- count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
- if (count == NULL)
- return(0);
- size = Cudd_DagSize(node);
- density = Cudd_NewApaNumber(digits);
- remainder = Cudd_ApaIntDivision(digits,count,size,density);
- result = Cudd_ApaPrintDecimal(fp,digits,density);
- FREE(count);
- FREE(density);
- fractional = (unsigned int)((double)remainder / size * 1000000);
- if (fprintf(fp,".%u\n", fractional) == EOF) {
- return(0);
- }
- return(result);
-
-} /* end of Cudd_ApaPrintDensity */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.]
-
- Description [Performs the recursive step of Cudd_ApaCountMinterm.
- It is based on the following identity. Let |f| be the
- number of minterms of f. Then:
- <xmp>
- |f| = (|f0|+|f1|)/2
- </xmp>
- where f0 and f1 are the two cofactors of f.
- Uses the identity <code>|f'| = max - |f|</code>.
- The procedure expects the argument "node" to be a regular pointer, and
- guarantees this condition is met in the recursive calls.
- For efficiency, the result of a call is cached only if the node has
- a reference count greater than 1.
- Returns the number of minterms of the function rooted at node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdApaNumber
-cuddApaCountMintermAux(
- DdNode * node,
- int digits,
- DdApaNumber max,
- DdApaNumber min,
- st_table * table)
-{
- DdNode *Nt, *Ne;
- DdApaNumber mint, mint1, mint2;
- DdApaDigit carryout;
-
- if (cuddIsConstant(node)) {
- if (node == background || node == zero) {
- return(min);
- } else {
- return(max);
- }
- }
- if (node->ref > 1 && st_lookup(table, (char *)node, (char **)&mint)) {
- return(mint);
- }
-
- Nt = cuddT(node); Ne = cuddE(node);
-
- mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table);
- if (mint1 == NULL) return(NULL);
- mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table);
- if (mint2 == NULL) {
- if (Nt->ref == 1) FREE(mint1);
- return(NULL);
- }
- mint = Cudd_NewApaNumber(digits);
- if (mint == NULL) {
- if (Nt->ref == 1) FREE(mint1);
- if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
- return(NULL);
- }
- if (Cudd_IsComplement(Ne)) {
- (void) Cudd_ApaSubtract(digits,max,mint2,mint);
- carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
- } else {
- 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
- ** hasn't been stored in table. Therefore, it must be explicitly
- ** freed here. */
- if (Nt->ref == 1) FREE(mint1);
- if (Cudd_Regular(Ne)->ref == 1) FREE(mint2);
-
- if (node->ref > 1) {
- if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) {
- FREE(mint);
- return(NULL);
- }
- }
- return(mint);
-
-} /* end of cuddApaCountMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the memory used to store the minterm counts recorded
- in the visited table.]
-
- Description [Frees the memory used to store the minterm counts
- recorded in the visited table. Returns ST_CONTINUE.]
-
- SideEffects [None]
-
-******************************************************************************/
-static enum st_retval
-cuddApaStCountfree(
- char * key,
- char * value,
- char * arg)
-{
- DdApaNumber d;
-
- d = (DdApaNumber) value;
- FREE(d);
- return(ST_CONTINUE);
-
-} /* end of cuddApaStCountfree */
-
-
diff --git a/src/bdd/cudd/cuddApprox.c b/src/bdd/cudd/cuddApprox.c
deleted file mode 100644
index debcf48b..00000000
--- a/src/bdd/cudd/cuddApprox.c
+++ /dev/null
@@ -1,2192 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddApprox.c]
-
- PackageName [cudd]
-
- Synopsis [Procedures to approximate a given BDD.]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#ifdef __STDC__
-#include <float.h>
-#else
-#define DBL_MAX_EXP 1024
-#endif
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* 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 DONT_CARE 0
-#define CARE 1
-#define TOTAL_CARE 2
-#define CARE_ERROR 3
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Data structure to store the information on each node. It keeps the
-** number of minterms of the function rooted at this node in terms of
-** the number of variables specified by the user; the number of
-** minterms of the complement; the impact of the number of minterms of
-** this function on the number of minterms of the root function; the
-** reference count of the node from within the root function; the
-** 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 */
-} 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 */
-} ApproxInfo;
-
-/* Item of the queue used in the levelized traversal of the BDD. */
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
-typedef struct GlobalQueueItem {
- struct GlobalQueueItem *next;
- struct GlobalQueueItem *cnext;
- DdNode *node;
- double impactP;
- double impactN;
-} GlobalQueueItem;
-
-typedef struct LocalQueueItem {
- struct LocalQueueItem *next;
- struct LocalQueueItem *cnext;
- DdNode *node;
- int localRef;
-} LocalQueueItem;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense subset from a BDD with Shiple's
- underapproximation method.]
-
- Description [Extracts a dense subset from a BDD. This procedure uses
- a variant of Tom Shiple's underapproximation method. The main
- difference from the original method is that density is used as cost
- function. Returns a pointer to the BDD of the subset if
- successful. NULL if the procedure runs out of memory. The parameter
- numVars is the maximum number of variables to be used in minterm
- calculation. The optimal number should be as close as possible to
- the size of the support of f. However, it is safe to pass the value
- returned by Cudd_ReadSize for numVars when the number of variables
- is under 1023. If numVars is larger than 1023, it will cause
- overflow. If a 0 parameter is passed then the procedure will compute
- a value which will avoid overflow but will cause underflow with 2046
- variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_UnderApprox(
- DdManager * dd /* manager */,
- DdNode * f /* function to be subset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- int safe /* enforce safe approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdNode *subset;
-
- do {
- dd->reordered = 0;
- subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality);
- } while (dd->reordered == 1);
-
- return(subset);
-
-} /* end of Cudd_UnderApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense superset from a BDD with Shiple's
- underapproximation method.]
-
- Description [Extracts a dense superset from a BDD. The procedure is
- identical to the underapproximation procedure except for the fact that it
- works on the complement of the given function. Extracting the subset
- of the complement function is equivalent to extracting the superset
- of the function.
- Returns a pointer to the BDD of the superset if successful. NULL if
- intermediate result causes the procedure to run out of memory. The
- parameter numVars is the maximum number of variables to be used in
- minterm calculation. The optimal number
- should be as close as possible to the size of the support of f.
- However, it is safe to pass the value returned by Cudd_ReadSize for
- numVars when the number of variables is under 1023. If numVars is
- larger than 1023, it will overflow. If a 0 parameter is passed then
- the procedure will compute a value which will avoid overflow but
- will cause underflow with 2046 variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_OverApprox(
- DdManager * dd /* manager */,
- DdNode * f /* function to be superset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- int safe /* enforce safe approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdNode *subset, *g;
-
- g = Cudd_Not(f);
- do {
- dd->reordered = 0;
- subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality);
- } while (dd->reordered == 1);
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_OverApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense subset from a BDD with the remapping
- underapproximation method.]
-
- Description [Extracts a dense subset from a BDD. This procedure uses
- a remapping technique and density as the cost function.
- Returns a pointer to the BDD of the subset if
- successful. NULL if the procedure runs out of memory. The parameter
- numVars is the maximum number of variables to be used in minterm
- calculation. The optimal number should be as close as possible to
- the size of the support of f. However, it is safe to pass the value
- returned by Cudd_ReadSize for numVars when the number of variables
- is under 1023. If numVars is larger than 1023, it will cause
- overflow. If a 0 parameter is passed then the procedure will compute
- a value which will avoid overflow but will cause underflow with 2046
- variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_RemapUnderApprox(
- DdManager * dd /* manager */,
- DdNode * f /* function to be subset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdNode *subset;
-
- do {
- dd->reordered = 0;
- subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality);
- } while (dd->reordered == 1);
-
- return(subset);
-
-} /* end of Cudd_RemapUnderApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense superset from a BDD with the remapping
- underapproximation method.]
-
- Description [Extracts a dense superset from a BDD. The procedure is
- identical to the underapproximation procedure except for the fact that it
- works on the complement of the given function. Extracting the subset
- of the complement function is equivalent to extracting the superset
- of the function.
- Returns a pointer to the BDD of the superset if successful. NULL if
- intermediate result causes the procedure to run out of memory. The
- parameter numVars is the maximum number of variables to be used in
- minterm calculation. The optimal number
- should be as close as possible to the size of the support of f.
- However, it is safe to pass the value returned by Cudd_ReadSize for
- numVars when the number of variables is under 1023. If numVars is
- larger than 1023, it will overflow. If a 0 parameter is passed then
- the procedure will compute a value which will avoid overflow but
- will cause underflow with 2046 variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_RemapOverApprox(
- DdManager * dd /* manager */,
- DdNode * f /* function to be superset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdNode *subset, *g;
-
- g = Cudd_Not(f);
- do {
- dd->reordered = 0;
- subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality);
- } while (dd->reordered == 1);
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_RemapOverApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense subset from a BDD with the biased
- underapproximation method.]
-
- Description [Extracts a dense subset from a BDD. This procedure uses
- a biased remapping technique and density as the cost function. The bias
- is a function. This procedure tries to approximate where the bias is 0
- and preserve the given function where the bias is 1.
- Returns a pointer to the BDD of the subset if
- successful. NULL if the procedure runs out of memory. The parameter
- numVars is the maximum number of variables to be used in minterm
- calculation. The optimal number should be as close as possible to
- the size of the support of f. However, it is safe to pass the value
- returned by Cudd_ReadSize for numVars when the number of variables
- is under 1023. If numVars is larger than 1023, it will cause
- overflow. If a 0 parameter is passed then the procedure will compute
- a value which will avoid overflow but will cause underflow with 2046
- variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox
- Cudd_RemapUnderApprox Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_BiasedUnderApprox(
- DdManager *dd /* manager */,
- DdNode *f /* function to be subset */,
- DdNode *b /* bias function */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- double quality1 /* minimum improvement for accepted changes when b=1 */,
- double quality0 /* minimum improvement for accepted changes when b=0 */)
-{
- DdNode *subset;
-
- do {
- dd->reordered = 0;
- subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1,
- quality0);
- } while (dd->reordered == 1);
-
- return(subset);
-
-} /* end of Cudd_BiasedUnderApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense superset from a BDD with the biased
- underapproximation method.]
-
- Description [Extracts a dense superset from a BDD. The procedure is
- identical to the underapproximation procedure except for the fact that it
- works on the complement of the given function. Extracting the subset
- of the complement function is equivalent to extracting the superset
- of the function.
- Returns a pointer to the BDD of the superset if successful. NULL if
- intermediate result causes the procedure to run out of memory. The
- parameter numVars is the maximum number of variables to be used in
- minterm calculation. The optimal number
- should be as close as possible to the size of the support of f.
- However, it is safe to pass the value returned by Cudd_ReadSize for
- numVars when the number of variables is under 1023. If numVars is
- larger than 1023, it will overflow. If a 0 parameter is passed then
- the procedure will compute a value which will avoid overflow but
- will cause underflow with 2046 variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths
- Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_BiasedOverApprox(
- DdManager *dd /* manager */,
- DdNode *f /* function to be superset */,
- DdNode *b /* bias function */,
- int numVars /* number of variables in the support of f */,
- int threshold /* when to stop approximation */,
- double quality1 /* minimum improvement for accepted changes when b=1*/,
- double quality0 /* minimum improvement for accepted changes when b=0 */)
-{
- DdNode *subset, *g;
-
- g = Cudd_Not(f);
- do {
- dd->reordered = 0;
- subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1,
- quality0);
- } while (dd->reordered == 1);
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_BiasedOverApprox */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Applies Tom Shiple's underappoximation algorithm.]
-
- Description [Applies Tom Shiple's underappoximation algorithm. Proceeds
- in three phases:
- <ul>
- <li> collect information on each node in the BDD; this is done via DFS.
- <li> traverse the BDD in top-down fashion and compute for each node
- whether its elimination increases density.
- <li> traverse the BDD via DFS and actually perform the elimination.
- </ul>
- Returns the approximated BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_UnderApprox]
-
-******************************************************************************/
-DdNode *
-cuddUnderApprox(
- DdManager * dd /* DD manager */,
- DdNode * f /* current DD */,
- int numVars /* maximum number of variables */,
- int threshold /* threshold under which approximation stops */,
- int safe /* enforce safe approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- ApproxInfo *info;
- DdNode *subset;
- int result;
-
- if (f == NULL) {
- fprintf(dd->err, "Cannot subset, nil object\n");
- return(NULL);
- }
-
- if (Cudd_IsConstant(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);
- }
-
- /* 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");
- FREE(info->page);
- st_free_table(info->table);
- 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));
-#endif
- FREE(info->page);
- st_free_table(info->table);
- FREE(info);
-
-#ifdef DD_DEBUG
- if (subset != NULL) {
- cuddRef(subset);
-#if 0
- (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);
- }
-#endif
- return(subset);
-
-} /* end of cuddUnderApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Applies the remapping underappoximation algorithm.]
-
- Description [Applies the remapping underappoximation algorithm.
- Proceeds in three phases:
- <ul>
- <li> collect information on each node in the BDD; this is done via DFS.
- <li> traverse the BDD in top-down fashion and compute for each node
- whether remapping increases density.
- <li> traverse the BDD via DFS and actually perform the elimination.
- </ul>
- Returns the approximated BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_RemapUnderApprox]
-
-******************************************************************************/
-DdNode *
-cuddRemapUnderApprox(
- DdManager * dd /* DD manager */,
- DdNode * f /* current DD */,
- int numVars /* maximum number of variables */,
- int threshold /* threshold under which approximation stops */,
- double quality /* minimum improvement for accepted changes */)
-{
- ApproxInfo *info;
- DdNode *subset;
- int result;
-
- if (f == NULL) {
- fprintf(dd->err, "Cannot subset, nil object\n");
- dd->errorCode = CUDD_INVALID_ARG;
- return(NULL);
- }
-
- if (Cudd_IsConstant(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);
- }
-
- /* 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");
- FREE(info->page);
- st_free_table(info->table);
- 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));
-#endif
- FREE(info->page);
- st_free_table(info->table);
- FREE(info);
-
-#ifdef DD_DEBUG
- if (subset != NULL) {
- cuddRef(subset);
-#if 0
- (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;
- }
-#endif
- return(subset);
-
-} /* end of cuddRemapUnderApprox */
-
-
-/**Function********************************************************************
-
- Synopsis [Applies the biased remapping underappoximation algorithm.]
-
- Description [Applies the biased remapping underappoximation algorithm.
- Proceeds in three phases:
- <ul>
- <li> collect information on each node in the BDD; this is done via DFS.
- <li> traverse the BDD in top-down fashion and compute for each node
- whether remapping increases density.
- <li> traverse the BDD via DFS and actually perform the elimination.
- </ul>
- Returns the approximated BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_BiasedUnderApprox]
-
-******************************************************************************/
-DdNode *
-cuddBiasedUnderApprox(
- DdManager *dd /* DD manager */,
- DdNode *f /* current DD */,
- DdNode *b /* bias function */,
- 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 */)
-{
- ApproxInfo *info;
- DdNode *subset;
- int result;
- DdHashTable *cache;
-
- if (f == NULL) {
- fprintf(dd->err, "Cannot subset, nil object\n");
- dd->errorCode = CUDD_INVALID_ARG;
- return(NULL);
- }
-
- if (Cudd_IsConstant(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);
- }
-
- 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);
- FREE(info->page);
- st_free_table(info->table);
- 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");
- FREE(info->page);
- st_free_table(info->table);
- 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));
-#endif
- FREE(info->page);
- st_free_table(info->table);
- FREE(info);
-
-#ifdef DD_DEBUG
- if (subset != NULL) {
- cuddRef(subset);
-#if 0
- (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;
- }
-#endif
- return(subset);
-
-} /* end of cuddBiasedUnderApprox */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Recursively update the parity of the paths reaching a node.]
-
- Description [Recursively update the parity of the paths reaching a node.
- Assumes that node is regular and propagates the invariant.]
-
- SideEffects [None]
-
- SeeAlso [gatherInfoAux]
-
-******************************************************************************/
-static void
-updateParity(
- DdNode * node /* function to analyze */,
- ApproxInfo * info /* info on BDD */,
- int newparity /* new parity for node */)
-{
- NodeData *infoN;
- DdNode *E;
-
- if (!st_lookup(info->table, (char *)node, (char **)&infoN)) return;
- if ((infoN->parity & newparity) != 0) return;
- infoN->parity |= 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);
- } else {
- updateParity(E,info,newparity);
- }
- return;
-
-} /* end of updateParity */
-
-
-/**Function********************************************************************
-
- Synopsis [Recursively counts minterms and computes reference counts
- of each node in the BDD.]
-
- Description [Recursively counts minterms and computes reference
- counts of each node in the BDD. Similar to the cuddCountMintermAux
- which recursively counts the number of minterms for the dag rooted
- at each node in terms of the total number of variables (max). It assumes
- that the node pointer passed to it is regular and it maintains the
- invariant.]
-
- SideEffects [None]
-
- SeeAlso [gatherInfo]
-
-******************************************************************************/
-static NodeData *
-gatherInfoAux(
- DdNode * node /* function to analyze */,
- ApproxInfo * info /* info on BDD */,
- int parity /* gather parity information */)
-{
- 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);
- }
-
- /* Compute the cofactors. */
- Nt = Cudd_NotCond(cuddT(N), N != node);
- Ne = Cudd_NotCond(cuddE(N), N != node);
-
- infoT = gatherInfoAux(Nt, info, parity);
- if (infoT == NULL) return(NULL);
- infoE = gatherInfoAux(Ne, info, parity);
- if (infoE == NULL) return(NULL);
-
- infoT->functionRef++;
- infoE->functionRef++;
-
- /* Point to the correct location in the page. */
- infoN = &(info->page[info->index++]);
- infoN->parity |= 1 + (short) 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;
- } else {
- 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(infoN);
-
-} /* end of gatherInfoAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Gathers information about each node.]
-
- Description [Counts minterms and computes reference counts of each
- node in the BDD . The minterm count is separately computed for the
- node and its complement. This is to avoid cancellation
- errors. Returns a pointer to the data structure holding the
- information gathered if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddUnderApprox gatherInfoAux]
-
-******************************************************************************/
-static ApproxInfo *
-gatherInfo(
- DdManager * dd /* manager */,
- DdNode * node /* function to be analyzed */,
- int numVars /* number of variables node depends on */,
- int parity /* gather parity information */)
-{
- ApproxInfo *info;
- NodeData *infoTop;
-
- /* If user did not give numVars value, set it to the maximum
- ** exponent that the pow function can take. The -1 is due to the
- ** discrepancy in the value that pow takes and the value that
- ** log gives.
- */
- if (numVars == 0) {
- numVars = DBL_MAX_EXP - 1;
- }
-
- info = ALLOC(ApproxInfo,1);
- if (info == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- info->max = pow(2.0,(double) numVars);
- info->one = DD_ONE(dd);
- info->zero = Cudd_Not(info->one);
- info->size = Cudd_DagSize(node);
- /* All the information gathered will be stored in a contiguous
- ** piece of memory, which is allocated here. This can be done
- ** efficiently because we have counted the number of nodes of the
- ** BDD. info->index points to the next available entry in the array
- ** that stores the per-node information. */
- info->page = ALLOC(NodeData,info->size);
- if (info->page == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(info);
- return(NULL);
- }
- memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */
- info->table = st_init_table(st_ptrcmp,st_ptrhash);
- if (info->table == NULL) {
- FREE(info->page);
- 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) {
- FREE(info->page);
- 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) {
- FREE(info->page);
- st_free_table(info->table);
- FREE(info);
- return(NULL);
- }
- if (Cudd_IsComplement(node)) {
- info->minterms = infoTop->mintermsN;
- } else {
- info->minterms = infoTop->mintermsP;
- }
-
- infoTop->functionRef = 1;
- return(info);
-
-} /* end of gatherInfo */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the nodes that would be eliminated if a given node
- were replaced by zero.]
-
- Description [Counts the nodes that would be eliminated if a given
- node were replaced by zero. This procedure uses a queue passed by
- the caller for efficiency: since the queue is left empty at the
- endof the search, it can be reused as is by the next search. Returns
- the count (always striclty positive) if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddUnderApprox]
-
-******************************************************************************/
-static int
-computeSavings(
- DdManager * dd,
- DdNode * f,
- DdNode * skip,
- ApproxInfo * info,
- DdLevelQueue * queue)
-{
- NodeData *infoN;
- LocalQueueItem *item;
- DdNode *node;
- int savings = 0;
-
- node = Cudd_Regular(f);
- skip = Cudd_Regular(skip);
- /* Insert the given node in the level queue. Its local reference
- ** 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));
- if (item == NULL)
- return(0);
- (void) st_lookup(info->table, (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++;
- }
- }
-
-#ifdef DD_DEBUG
- /* At the end of a local search the queue should be empty. */
- assert(queue->size == 0);
-#endif
- return(savings);
-
-} /* end of computeSavings */
-
-
-/**Function********************************************************************
-
- Synopsis [Update function reference counts.]
-
- Description [Update function reference counts to account for replacement.
- Returns the number of nodes saved if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [UAmarkNodes RAmarkNodes]
-
-******************************************************************************/
-static int
-updateRefs(
- DdManager * dd,
- DdNode * f,
- DdNode * skip,
- ApproxInfo * info,
- DdLevelQueue * queue)
-{
- NodeData *infoN;
- LocalQueueItem *item;
- DdNode *node;
- int savings = 0;
-
- node = Cudd_Regular(f);
- /* Insert the given node in the level queue. Its function reference
- ** count is set equal to 0 so that the search will continue from it
- ** 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);
- 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++;
- }
-
- /* 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--;
- }
- }
-
-#ifdef DD_DEBUG
- /* At the end of a local search the queue should be empty. */
- assert(queue->size == 0);
-#endif
- return(savings);
-
-} /* end of updateRefs */
-
-
-/**Function********************************************************************
-
- Synopsis [Marks nodes for replacement by zero.]
-
- Description [Marks nodes for replacement by zero. Returns 1 if successful;
- 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddUnderApprox]
-
-******************************************************************************/
-static int
-UAmarkNodes(
- DdManager * dd /* manager */,
- DdNode * f /* function to be analyzed */,
- ApproxInfo * info /* info on BDD */,
- int threshold /* when to stop approximating */,
- int safe /* enforce safe approximation */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdLevelQueue *queue;
- DdLevelQueue *localQueue;
- NodeData *infoN;
- GlobalQueueItem *item;
- DdNode *node;
- double numOnset;
- double impactP, impactN;
- int savings;
-
-#if 0
- (void) printf("initial size = %d initial minterms = %g\n",
- info->size, info->minterms);
-#endif
- queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
- if (queue == NULL) {
- return(0);
- }
- localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
- dd->initSlots);
- if (localQueue == NULL) {
- 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);
- }
- if (Cudd_IsComplement(f)) {
- item->impactP = 0.0;
- item->impactN = 1.0;
- } else {
- 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) {
- 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);
-#endif
- 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);
-#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;
- }
- }
- }
-
- cuddLevelQueueQuit(queue);
- cuddLevelQueueQuit(localQueue);
- return(1);
-
-} /* end of UAmarkNodes */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the subset BDD.]
-
- Description [Builds the subset BDD. Based on the info table,
- replaces selected nodes by zero. Returns a pointer to the result if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddUnderApprox]
-
-******************************************************************************/
-static DdNode *
-UAbuildSubset(
- DdManager * dd /* DD manager */,
- DdNode * node /* current node */,
- ApproxInfo * info /* node info */)
-{
-
- DdNode *Nt, *Ne, *N, *t, *e, *r;
- NodeData *infoN;
-
- if (Cudd_IsConstant(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);
- }
- } 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);
- }
-
- Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node));
- Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node));
-
- t = UAbuildSubset(dd, Nt, info);
- if (t == NULL) {
- return(NULL);
- }
- cuddRef(t);
-
- e = UAbuildSubset(dd, Ne, info);
- if (e == 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);
- } else {
- 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;
- } else {
- infoN->resultN = r;
- }
-
- return(r);
-
-} /* end of UAbuildSubset */
-
-
-/**Function********************************************************************
-
- Synopsis [Marks nodes for remapping.]
-
- Description [Marks nodes for remapping. Returns 1 if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddRemapUnderApprox]
-
-******************************************************************************/
-static int
-RAmarkNodes(
- DdManager * dd /* manager */,
- DdNode * f /* function to be analyzed */,
- ApproxInfo * info /* info on BDD */,
- int threshold /* when to stop approximating */,
- double quality /* minimum improvement for accepted changes */)
-{
- DdLevelQueue *queue;
- DdLevelQueue *localQueue;
- NodeData *infoN, *infoT, *infoE;
- GlobalQueueItem *item;
- DdNode *node, *T, *E;
- DdNode *shared; /* grandchild shared by the two children of node */
- double numOnset;
- double impact, impactP, impactN;
- double minterms;
- int savings;
- int replace;
-
-#if 0
- (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n",
- info->size, info->minterms);
-#endif
- queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
- if (queue == NULL) {
- return(0);
- }
- localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
- dd->initSlots);
- if (localQueue == NULL) {
- 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));
- if (item == NULL) {
- cuddLevelQueueQuit(queue);
- cuddLevelQueueQuit(localQueue);
- return(0);
- }
- if (Cudd_IsComplement(f)) {
- item->impactP = 0.0;
- item->impactN = 1.0;
- } else {
- 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);
- }
-#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) {
- 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;
- }
- 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);
- }
- } else {
- savings = 1;
- }
- replace = REPLACE_T;
- } else {
-#ifdef DD_DEBUG
- 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);
- }
- } 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--;
- }
- }
-
- 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);
-#endif
- if ((1 - numOnset / info->minterms) >
- quality * (1 - (double) savings / info->size)) {
- infoN->replace = 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);
-#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 {
-#ifdef DD_DEBUG
- 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;
- } 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);
- return(1);
-
-} /* end of RAmarkNodes */
-
-
-/**Function********************************************************************
-
- Synopsis [Marks nodes for remapping.]
-
- Description [Marks nodes for remapping. Returns 1 if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddRemapUnderApprox]
-
-******************************************************************************/
-static int
-BAmarkNodes(
- DdManager *dd /* manager */,
- DdNode *f /* function to be analyzed */,
- ApproxInfo *info /* info on BDD */,
- int threshold /* when to stop approximating */,
- double quality1 /* minimum improvement for accepted changes when b=1 */,
- double quality0 /* minimum improvement for accepted changes when b=0 */)
-{
- DdLevelQueue *queue;
- DdLevelQueue *localQueue;
- NodeData *infoN, *infoT, *infoE;
- GlobalQueueItem *item;
- DdNode *node, *T, *E;
- DdNode *shared; /* grandchild shared by the two children of node */
- double numOnset;
- double impact, impactP, impactN;
- double minterms;
- double quality;
- int savings;
- int replace;
-
-#if 0
- (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n",
- info->size, info->minterms);
-#endif
- queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
- if (queue == NULL) {
- return(0);
- }
- localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
- dd->initSlots);
- if (localQueue == NULL) {
- 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));
- if (item == NULL) {
- cuddLevelQueueQuit(queue);
- cuddLevelQueueQuit(localQueue);
- return(0);
- }
- if (Cudd_IsComplement(f)) {
- item->impactP = 0.0;
- item->impactN = 1.0;
- } else {
- 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);
- }
- 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) {
- 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;
- }
- 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);
- }
- } else {
- savings = 1;
- }
- replace = REPLACE_T;
- } else {
-#ifdef DD_DEBUG
- 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);
- }
- } 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--;
- }
- }
-
- 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);
-#endif
- if ((1 - numOnset / info->minterms) >
- quality * (1 - (double) savings / info->size)) {
- infoN->replace = 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);
-#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 {
-#ifdef DD_DEBUG
- 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;
- } 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);
- return(1);
-
-} /* end of BAmarkNodes */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the subset BDD for cuddRemapUnderApprox.]
-
- Description [Builds the subset BDDfor cuddRemapUnderApprox. Based
- on the info table, performs remapping or replacement at selected
- nodes. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddRemapUnderApprox]
-
-******************************************************************************/
-static DdNode *
-RAbuildSubset(
- DdManager * dd /* DD manager */,
- DdNode * node /* current node */,
- ApproxInfo * info /* node info */)
-{
- DdNode *Nt, *Ne, *N, *t, *e, *r;
- NodeData *infoN;
-
- if (Cudd_IsConstant(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);
- } 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);
- }
- 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);
- }
- } else {
- (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);
- }
- cuddRef(t);
-
- e = RAbuildSubset(dd, Ne, info);
- if (e == 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);
- } else {
- 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;
- } else {
- infoN->resultN = r;
- }
-
- return(r);
-
-} /* end of RAbuildSubset */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds don't care nodes.]
-
- Description [Finds don't care nodes by traversing f and b in parallel.
- Returns the care status of the visited f node if successful; CARE_ERROR
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddBiasedUnderApprox]
-
-******************************************************************************/
-static int
-BAapplyBias(
- DdManager *dd,
- DdNode *f,
- DdNode *b,
- ApproxInfo *info,
- DdHashTable *cache)
-{
- DdNode *one, *zero, *res;
- DdNode *Ft, *Fe, *B, *Bt, *Be;
- unsigned int topf, topb;
- NodeData *infoF;
- int careT, careE;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- if (!st_lookup(info->table, (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);
- }
-
- topf = dd->perm[f->index];
- B = Cudd_Regular(b);
- topb = cuddI(dd,B->index);
- if (topf <= topb) {
- Ft = cuddT(f); Fe = cuddE(f);
- } else {
- 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);
- }
- } else {
- Bt = Be = b;
- }
-
- careT = BAapplyBias(dd, Ft, Bt, info, cache);
- if (careT == CARE_ERROR)
- return(CARE_ERROR);
- careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache);
- if (careE == CARE_ERROR)
- return(CARE_ERROR);
- if (careT == TOTAL_CARE && careE == TOTAL_CARE) {
- infoF->care = TOTAL_CARE;
- } else {
- 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);
- }
- }
- return(infoF->care);
-
-} /* end of BAapplyBias */
diff --git a/src/bdd/cudd/cuddBddAbs.c b/src/bdd/cudd/cuddBddAbs.c
deleted file mode 100644
index 9552464e..00000000
--- a/src/bdd/cudd/cuddBddAbs.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddBddAbs.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int bddCheckPositiveCube ARGS((DdManager *manager, DdNode *cube));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Existentially abstracts all the variables in cube from f.]
-
- Description [Existentially abstracts all the variables in cube from f.
- Returns the abstracted BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_bddExistAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- 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);
- }
-
- do {
- manager->reordered = 0;
- res = cuddBddExistAbstractRecur(manager, f, cube);
- } while (manager->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_bddExistAbstract */
-
-
-/**Function********************************************************************
-
- Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the
- variables in cube.]
-
- Description [Takes the exclusive OR of two BDDs and simultaneously abstracts
- the variables in cube. The variables are existentially abstracted. Returns a
- pointer to the result is successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_bddXorExistAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube)
-{
- 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);
- }
-
- do {
- manager->reordered = 0;
- res = cuddBddXorExistAbstractRecur(manager, f, g, cube);
- } while (manager->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_bddXorExistAbstract */
-
-
-/**Function********************************************************************
-
- Synopsis [Universally abstracts all the variables in cube from f.]
-
- Description [Universally abstracts all the variables in cube from f.
- Returns the abstracted BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_bddUnivAbstract(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- 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);
- }
-
- do {
- manager->reordered = 0;
- res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube);
- } while (manager->reordered == 1);
- if (res != NULL) res = Cudd_Not(res);
-
- return(res);
-
-} /* end of Cudd_bddUnivAbstract */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the boolean difference of f with respect to x.]
-
- Description [Computes the boolean difference of f with respect to the
- variable with index x. Returns the BDD of the boolean difference if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_bddBooleanDiff(
- DdManager * manager,
- DdNode * f,
- int x)
-{
- DdNode *res, *var;
-
- /* If the variable is not currently in the manager, f cannot
- ** depend on it.
- */
- if (x >= manager->size) return(Cudd_Not(DD_ONE(manager)));
- var = manager->vars[x];
-
- do {
- manager->reordered = 0;
- res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var);
- } while (manager->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_bddBooleanDiff */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variable is dependent on others in a
- function.]
-
- Description [Checks whether a variable is dependent on others in a
- function. Returns 1 if the variable is dependent; 0 otherwise. No
- new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_bddVarIsDependent(
- DdManager *dd, /* manager */
- DdNode *f, /* function */
- DdNode *var /* variable */)
-{
- DdNode *F, *res, *zero, *ft, *fe;
- unsigned topf, level;
- DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
- int retval;
-
- zero = Cudd_Not(DD_ONE(dd));
- if (Cudd_IsConstant(f)) return(f == zero);
-
- /* From now on f is not constant. */
- F = Cudd_Regular(f);
- topf = (unsigned) dd->perm[F->index];
- level = (unsigned) dd->perm[var->index];
-
- /* 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);
- }
-
- cacheOp =
- (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_bddVarIsDependent;
- res = cuddCacheLookup2(dd,cacheOp,f,var);
- if (res != NULL) {
- return(res != zero);
- }
-
- /* Compute cofactors. */
- ft = Cudd_NotCond(cuddT(F), f != F);
- fe = Cudd_NotCond(cuddE(F), f != F);
-
- if (topf == level) {
- retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
- } else {
- retval = Cudd_bddVarIsDependent(dd,ft,var) &&
- Cudd_bddVarIsDependent(dd,fe,var);
- }
-
- cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));
-
- return(retval);
-
-} /* Cudd_bddVarIsDependent */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.]
-
- Description [Performs the recursive steps of Cudd_bddExistAbstract.
- Returns the BDD obtained by abstracting the variables
- of cube from f if successful; NULL otherwise. It is also used by
- Cudd_bddUnivAbstract.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract]
-
-******************************************************************************/
-DdNode *
-cuddBddExistAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * cube)
-{
- 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. */
- if (cube == one || F == one) {
- return(f);
- }
- /* From now on, f and cube are non-constant. */
-
- /* 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);
- }
-
- /* Check the cache. */
- if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) {
- return(res);
- }
-
- /* Compute the cofactors of f. */
- T = cuddT(F); E = cuddE(F);
- if (f != F) {
- 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);
- }
- cuddRef(res1);
- 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) {
- 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);
- return(res);
- } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */
- 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);
- }
- 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);
- }
- cuddDeref(res1);
- cuddDeref(res2);
- if (F->ref != 1)
- cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
- return(res);
- }
-
-} /* end of cuddBddExistAbstractRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the
- variables in cube.]
-
- Description [Takes the exclusive OR of two BDDs and simultaneously abstracts
- the variables in cube. The variables are existentially abstracted. Returns a
- pointer to the result is successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddAndAbstract]
-
-******************************************************************************/
-DdNode *
-cuddBddXorExistAbstractRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube)
-{
- DdNode *F, *fv, *fnv, *G, *gv, *gnv;
- DdNode *one, *zero, *r, *t, *e, *Cube;
- unsigned int topf, topg, topcube, top, index;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (f == g) {
- return(zero);
- }
- if (f == Cudd_Not(g)) {
- return(one);
- }
- if (cube == one) {
- return(cuddBddXorRecur(manager, f, g));
- }
- if (f == one) {
- return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
- }
- if (g == one) {
- return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
- }
- if (f == zero) {
- return(cuddBddExistAbstractRecur(manager, g, cube));
- }
- if (g == zero) {
- 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;
- }
-
- /* Check cache. */
- r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube);
- if (r != NULL) {
- return(r);
- }
-
- /* Here we can skip the use of cuddI, because the operands are known
- ** to be non-constant.
- */
- F = Cudd_Regular(f);
- topf = manager->perm[F->index];
- G = Cudd_Regular(g);
- topg = manager->perm[G->index];
- top = ddMin(topf, topg);
- topcube = manager->perm[cube->index];
-
- if (topcube < top) {
- 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);
- }
- } else {
- 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);
- }
- } else {
- gv = gnv = g;
- }
-
- if (topcube == top) {
- Cube = cuddT(cube);
- } else {
- Cube = cube;
- }
-
- t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
- if (t == NULL) return(NULL);
-
- /* Special case: 1 OR anything = 1. Hence, no need to compute
- ** 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);
- }
- 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));
- 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);
- }
- cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
- return (r);
-
-} /* end of cuddBddXorExistAbstractRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.]
-
- Description [Performs the recursive steps of Cudd_bddBoleanDiff.
- Returns the BDD obtained by XORing the cofactors of f with respect to
- var if successful; NULL otherwise. Exploits the fact that dF/dx =
- dF'/dx.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddBddBooleanDiffRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * var)
-{
- DdNode *T, *E, *res, *res1, *res2;
-
- statLine(manager);
- if (cuddI(manager,f->index) > manager->perm[var->index]) {
- /* 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));
- return(res);
- }
-
- /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */
-
- /* Check the cache. */
- res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
- if (res != NULL) {
- return(res);
- }
-
- /* Compute the cofactors of f. */
- T = cuddT(f); E = cuddE(f);
-
- res1 = cuddBddBooleanDiffRecur(manager, T, var);
- if (res1 == NULL) return(NULL);
- cuddRef(res1);
- res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
- if (res2 == 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);
- }
- cuddDeref(res1);
- cuddDeref(res2);
- cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res);
- return(res);
-
-} /* end of cuddBddBooleanDiffRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Checks whether cube is an BDD representing the product of
- positive literals.]
-
- Description [Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-bddCheckPositiveCube(
- DdManager * manager,
- DdNode * cube)
-{
- if (Cudd_IsComplement(cube)) return(0);
- if (cube == DD_ONE(manager)) return(1);
- if (cuddIsConstant(cube)) return(0);
- if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) {
- return(bddCheckPositiveCube(manager, cuddT(cube)));
- }
- return(0);
-
-} /* end of bddCheckPositiveCube */
-
diff --git a/src/bdd/cudd/cuddBddCorr.c b/src/bdd/cudd/cuddBddCorr.c
deleted file mode 100644
index c99324a8..00000000
--- a/src/bdd/cudd/cuddBddCorr.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddBddCorr.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-typedef struct hashEntry {
- DdNode *f;
- DdNode *g;
-} HashEntry;
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-#ifdef CORREL_STATS
-static int num_calls;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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((char *key, int modulus));
-static enum st_retval CorrelCleanUp ARGS((char *key, char *value, char *arg));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the correlation of f and g.]
-
- Description [Computes the correlation of f and g. If f == g, their
- correlation is 1. If f == g', their correlation is 0. Returns the
- fraction of minterms in the ON-set of the EXNOR of f and g. If it
- runs out of memory, returns (double)CUDD_OUT_OF_MEM.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddCorrelationWeights]
-
-******************************************************************************/
-double
-Cudd_bddCorrelation(
- DdManager * manager,
- DdNode * f,
- DdNode * g)
-{
-
- st_table *table;
- double correlation;
-
-#ifdef CORREL_STATS
- num_calls = 0;
-#endif
-
- table = st_init_table(CorrelCompare,CorrelHash);
- if (table == NULL) return((double)CUDD_OUT_OF_MEM);
- correlation = bddCorrelationAux(manager,f,g,table);
- st_foreach(table, CorrelCleanUp, NIL(char));
- st_free_table(table);
- return(correlation);
-
-} /* end of Cudd_bddCorrelation */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the correlation of f and g for given input
- probabilities.]
-
- Description [Computes the correlation of f and g for given input
- probabilities. On input, prob\[i\] is supposed to contain the
- probability of the i-th input variable to be 1.
- If f == g, their correlation is 1. If f == g', their
- correlation is 0. Returns the probability that f and g have the same
- value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The
- correlation of f and the constant one gives the probability of f.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddCorrelation]
-
-******************************************************************************/
-double
-Cudd_bddCorrelationWeights(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- double * prob)
-{
-
- st_table *table;
- double correlation;
-
-#ifdef CORREL_STATS
- num_calls = 0;
-#endif
-
- 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, CorrelCleanUp, NIL(char));
- st_free_table(table);
- return(correlation);
-
-} /* end of Cudd_bddCorrelationWeights */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddCorrelation.]
-
- Description [Performs the recursive step of Cudd_bddCorrelation.
- Returns the fraction of minterms in the ON-set of the EXNOR of f and
- g.]
-
- SideEffects [None]
-
- SeeAlso [bddCorrelationWeightsAux]
-
-******************************************************************************/
-static double
-bddCorrelationAux(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- st_table * table)
-{
- DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
- double min, *pmin, min1, min2, *dummy;
- HashEntry *entry;
- unsigned int topF, topG;
-
- statLine(dd);
-#ifdef CORREL_STATS
- num_calls++;
-#endif
-
- /* Terminal cases: only work for BDDs. */
- if (f == g) return(1.0);
- if (f == Cudd_Not(g)) return(0.0);
-
- /* Standardize call using the following properties:
- ** (f EXNOR g) = (g EXNOR f)
- ** (f' EXNOR g') = (f EXNOR g).
- */
- if (f > g) {
- DdNode *tmp = f;
- f = g; g = tmp;
- }
- if (Cudd_IsComplement(f)) {
- f = Cudd_Not(f);
- g = Cudd_Not(g);
- }
- /* From now on, f is regular. */
-
- entry = ALLOC(HashEntry,1);
- if (entry == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- entry->f = f; entry->g = g;
-
- /* We do not use the fact that
- ** correlation(f,g') = 1 - correlation(f,g)
- ** to minimize the risk of cancellation.
- */
- if (st_lookup(table, (char *)entry, (char **)&dummy)) {
- min = *dummy;
- 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); } else { Fv = Fnv = f; }
- if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; }
-
- if (g != G) {
- Gv = Cudd_Not(Gv);
- Gnv = Cudd_Not(Gnv);
- }
-
- min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0;
- if (min1 == (double)CUDD_OUT_OF_MEM) {
- FREE(entry);
- return(CUDD_OUT_OF_MEM);
- }
- min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0;
- if (min2 == (double)CUDD_OUT_OF_MEM) {
- FREE(entry);
- return(CUDD_OUT_OF_MEM);
- }
- min = (min1+min2);
-
- pmin = ALLOC(double,1);
- if (pmin == NULL) {
- 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) {
- FREE(entry);
- FREE(pmin);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(min);
-
-} /* end of bddCorrelationAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [bddCorrelationAux]
-
-******************************************************************************/
-static double
-bddCorrelationWeightsAux(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- double * prob,
- st_table * table)
-{
- DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
- double min, *pmin, min1, min2, *dummy;
- HashEntry *entry;
- int topF, topG, index;
-
- statLine(dd);
-#ifdef CORREL_STATS
- num_calls++;
-#endif
-
- /* Terminal cases: only work for BDDs. */
- if (f == g) return(1.0);
- if (f == Cudd_Not(g)) return(0.0);
-
- /* Standardize call using the following properties:
- ** (f EXNOR g) = (g EXNOR f)
- ** (f' EXNOR g') = (f EXNOR g).
- */
- if (f > g) {
- DdNode *tmp = f;
- f = g; g = tmp;
- }
- if (Cudd_IsComplement(f)) {
- f = Cudd_Not(f);
- g = Cudd_Not(g);
- }
- /* From now on, f is regular. */
-
- entry = ALLOC(HashEntry,1);
- if (entry == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return((double)CUDD_OUT_OF_MEM);
- }
- entry->f = f; entry->g = g;
-
- /* We do not use the fact that
- ** correlation(f,g') = 1 - correlation(f,g)
- ** to minimize the risk of cancellation.
- */
- if (st_lookup(table, (char *)entry, (char **)&dummy)) {
- min = *dummy;
- 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;
- } else {
- 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);
- }
-
- min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index];
- if (min1 == (double)CUDD_OUT_OF_MEM) {
- 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) {
- FREE(entry);
- return((double)CUDD_OUT_OF_MEM);
- }
- min = (min1+min2);
-
- pmin = ALLOC(double,1);
- if (pmin == NULL) {
- 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) {
- FREE(entry);
- FREE(pmin);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(min);
-
-} /* end of bddCorrelationWeightsAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Compares two hash table entries.]
-
- Description [Compares two hash table entries. Returns 0 if they are
- identical; 1 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-CorrelCompare(
- const char * key1,
- const char * key2)
-{
- HashEntry *entry1;
- HashEntry *entry2;
-
- entry1 = (HashEntry *) key1;
- entry2 = (HashEntry *) key2;
- if (entry1->f != entry2->f || entry1->g != entry2->g) return(1);
-
- return(0);
-
-} /* end of CorrelCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Hashes a hash table entry.]
-
- Description [Hashes a hash table entry. It is patterned after
- st_strhash. Returns a value between 0 and modulus.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-CorrelHash(
- char * key,
- int modulus)
-{
- HashEntry *entry;
- int val = 0;
-
- entry = (HashEntry *) key;
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
- val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g));
-#else
- val = ((int) entry->f)*997 + ((int) entry->g);
-#endif
-
- return ((val < 0) ? -val : val) % modulus;
-
-} /* end of CorrelHash */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees memory associated with hash table.]
-
- Description [Frees memory associated with hash table. Returns
- ST_CONTINUE.]
-
- SideEffects [None]
-
-******************************************************************************/
-static enum st_retval
-CorrelCleanUp(
- char * key,
- char * value,
- char * arg)
-{
- double *d;
- HashEntry *entry;
-
- entry = (HashEntry *) key;
- FREE(entry);
- d = (double *)value;
- FREE(d);
- return ST_CONTINUE;
-
-} /* end of CorrelCleanUp */
-
diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c
deleted file mode 100644
index b44e40de..00000000
--- a/src/bdd/cudd/cuddBddIte.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddBddIte.c]
-
- PackageName [cudd]
-
- Synopsis [BDD ITE function and satellites.]
-
- Description [External procedures included in this module:
- <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>
- Internal procedures included in this module:
- <ul>
- <li> cuddBddIteRecur()
- <li> cuddBddIntersectRecur()
- <li> cuddBddAndRecur()
- <li> cuddBddXorRecur()
- </ul>
- Static procedures included in this module:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements ITE(f,g,h).]
-
- Description [Implements ITE(f,g,h). Returns a pointer to the
- resulting BDD if successful; NULL if the intermediate result blows
- up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]
-
-******************************************************************************/
-DdNode *
-Cudd_bddIte(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddIteRecur(dd,f,g,h);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddIte */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements ITEconstant(f,g,h).]
-
- Description [Implements ITEconstant(f,g,h). Returns a pointer to the
- resulting BDD (which may or may not be constant) or DD_NON_CONSTANT.
- No new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]
-
-******************************************************************************/
-DdNode *
-Cudd_bddIteConstant(
- DdManager * dd,
- DdNode * f,
- 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;
- unsigned int topf, topg, toph, v;
-
- statLine(dd);
- /* Trivial cases. */
- if (f == one) /* ITE(1,G,H) => G */
- return(g);
-
- 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 */
-
- 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 */
-
- if (g == Cudd_Not(h))
- 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));
- }
-
- 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);
- }
-
- /* Compute cofactors. */
- if (topf <= v) {
- v = ddMin(topf, v); /* v = top_var(F,G,H) */
- Fv = cuddT(f); Fnv = cuddE(f);
- } else {
- Fv = Fnv = f;
- }
-
- if (topg == v) {
- Gv = cuddT(g); Gnv = cuddE(g);
- } else {
- 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);
- }
- } else {
- 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);
- }
- 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, t);
- return(Cudd_NotCond(t,comple));
-
-} /* end of Cudd_bddIteConstant */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns a function included in the intersection of f and g.]
-
- Description [Computes a function included in the intersection of f and
- g. (That is, a witness that the intersection is not empty.)
- Cudd_bddIntersect tries to build as few new nodes as possible. If the
- only result of interest is whether f and g intersect,
- Cudd_bddLeq should be used instead.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]
-
-******************************************************************************/
-DdNode *
-Cudd_bddIntersect(
- DdManager * dd /* manager */,
- DdNode * f /* first operand */,
- DdNode * g /* second operand */)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddIntersectRecur(dd,f,g);
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_bddIntersect */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the conjunction of two BDDs f and g.]
-
- Description [Computes the conjunction of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect
- Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddAnd(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddAndRecur(dd,f,g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddAnd */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the disjunction of two BDDs f and g.]
-
- Description [Computes the disjunction of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor
- Cudd_bddXor Cudd_bddXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddOr(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
- } while (dd->reordered == 1);
- res = Cudd_NotCond(res,res != NULL);
- return(res);
-
-} /* end of Cudd_bddOr */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the NAND of two BDDs f and g.]
-
- Description [Computes the NAND of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor
- Cudd_bddXor Cudd_bddXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddNand(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddAndRecur(dd,f,g);
- } while (dd->reordered == 1);
- res = Cudd_NotCond(res,res != NULL);
- return(res);
-
-} /* end of Cudd_bddNand */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the NOR of two BDDs f and g.]
-
- Description [Computes the NOR of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand
- Cudd_bddXor Cudd_bddXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddNor(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddNor */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the exclusive OR of two BDDs f and g.]
-
- Description [Computes the exclusive OR of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr
- Cudd_bddNand Cudd_bddNor Cudd_bddXnor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddXor(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddXorRecur(dd,f,g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddXor */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the exclusive NOR of two BDDs f and g.]
-
- Description [Computes the exclusive NOR of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr
- Cudd_bddNand Cudd_bddNor Cudd_bddXor]
-
-******************************************************************************/
-DdNode *
-Cudd_bddXnor(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddXorRecur(dd,f,Cudd_Not(g));
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddXnor */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines whether f is less than or equal to g.]
-
- Description [Returns 1 if f is less than or equal to g; 0 otherwise.
- No new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]
-
-******************************************************************************/
-int
-Cudd_bddLeq(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
- unsigned int topf, topg, res;
-
- statLine(dd);
- /* Terminal cases and normalization. */
- 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);
- } else if (Cudd_IsComplement(f) && g < f) {
- tmp = g;
- g = Cudd_Not(f);
- f = Cudd_Not(tmp);
- }
-
- /* Now g is regular and, if f is not regular, f < g. */
- one = DD_ONE(dd);
- if (g == one) return(1); /* no need to test against zero */
- if (f == one) return(0); /* since at this point g != one */
- if (Cudd_Not(f) == g) return(0); /* because neither is constant */
- zero = Cudd_Not(one);
- if (f == zero) return(1);
-
- /* Here neither f nor g is constant. */
-
- /* Check cache. */
- tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *,
- DdNode *))Cudd_bddLeq,f,g);
- if (tmp != NULL) {
- return(tmp == one);
- }
-
- /* Compute cofactors. */
- F = Cudd_Regular(f);
- 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);
- }
- } else {
- fv = fvn = f;
- }
- if (topg <= topf) {
- gv = cuddT(g); gvn = cuddE(g);
- } else {
- gv = gvn = g;
- }
-
- /* Recursive calls. Since we want to maximize the probability of
- ** the special case f(1,...,1) > g(1,...,1), we consider the negative
- ** cofactors first. Indeed, the complementation parity of the positive
- ** cofactors is the same as the one of the parent functions.
- */
- 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));
- return(res);
-
-} /* end of Cudd_bddLeq */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddIte.]
-
- Description [Implements the recursive step of Cudd_bddIte. Returns a
- pointer to the resulting BDD. NULL if the intermediate result blows
- up or if reordering occurs.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddBddIteRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *one, *zero, *res;
- DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
- unsigned int topf, topg, toph, v;
- 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 == (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));
- }
- } 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 == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
- 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));
- }
-
- /* Check remaining one variable case. */
- 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);
- }
-
- /* From here, there are no constants. */
- comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
-
- /* f & g are now regular pointers */
-
- v = ddMin(topg, toph);
-
- /* 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));
- }
-
- /* Check cache. */
- r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
- if (r != NULL) {
- 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);
- } else {
- Fv = Fnv = f;
- }
- if (topg == v) {
- index = g->index;
- Gv = cuddT(g); Gnv = cuddE(g);
- } else {
- 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);
- }
- } else {
- Hv = Hnv = h;
- }
-
- /* Recursive step. */
- t = cuddBddIteRecur(dd,Fv,Gv,Hv);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
- if (e == 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);
- }
- cuddDeref(t);
- cuddDeref(e);
-
- cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddIteRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddIntersect.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIntersect]
-
-******************************************************************************/
-DdNode *
-cuddBddIntersectRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
- DdNode *F, *G, *t, *e;
- DdNode *fv, *fnv, *gv, *gnv;
- DdNode *one, *zero;
- unsigned int index, topf, topg;
-
- statLine(dd);
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
- if (f == g || g == one) return(f);
- if (f == one) return(g);
-
- /* At this point f and g are not constant. */
- if (f > g) { DdNode *tmp = f; f = g; g = tmp; }
- res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
- if (res != NULL) return(res);
-
- /* Find splitting variable. Here we can skip the use of cuddI,
- ** because the operands are known to be non-constant.
- */
- F = Cudd_Regular(f);
- topf = dd->perm[F->index];
- G = Cudd_Regular(g);
- topg = dd->perm[G->index];
-
- /* 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);
- }
- } else {
- 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);
- }
- } else {
- gv = gnv = g;
- }
-
- /* Compute partial results. */
- t = cuddBddIntersectRecur(dd,fv,gv);
- if (t == NULL) return(NULL);
- cuddRef(t);
- if (t != zero) {
- e = zero;
- } else {
- e = cuddBddIntersectRecur(dd,fnv,gnv);
- if (e == NULL) {
- Cudd_IterDerefBdd(dd, t);
- return(NULL);
- }
- }
- cuddRef(e);
-
- if (t == e) { /* both equal zero */
- 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);
- } else {
- res = cuddUniqueInter(dd,(int)index,t,e);
- if (res == NULL) {
- Cudd_IterDerefBdd(dd, t);
- Cudd_IterDerefBdd(dd, e);
- return(NULL);
- }
- }
- cuddDeref(e);
- cuddDeref(t);
-
- cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res);
-
- return(res);
-
-} /* end of cuddBddIntersectRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddAnd.]
-
- Description [Implements the recursive step of Cudd_bddAnd by taking
- the conjunction of two BDDs. Returns a pointer to the result is
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddAnd]
-
-******************************************************************************/
-DdNode *
-cuddBddAndRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g)
-{
- DdNode *F, *fv, *fnv, *G, *gv, *gnv;
- 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(f);
- else return(Cudd_Not(one));
- }
- if (F == one) {
- if (f == one) return(g);
- else return(f);
- }
- if (G == one) {
- 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);
- }
-
- /* Check cache. */
- if (F->ref != 1 || G->ref != 1) {
- 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
- ** to be non-constant.
- */
- topf = manager->perm[F->index];
- topg = manager->perm[G->index];
-
- /* 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);
- }
- } else {
- 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);
- }
- } else {
- gv = gnv = g;
- }
-
- t = cuddBddAndRecur(manager, fv, gv);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddBddAndRecur(manager, fnv, gnv);
- 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_bddAnd, f, g, r);
- return(r);
-
-} /* end of cuddBddAndRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddXor.]
-
- Description [Implements the recursive step of Cudd_bddXor by taking
- the exclusive OR of two BDDs. Returns a pointer to the result is
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddXor]
-
-******************************************************************************/
-DdNode *
-cuddBddXorRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g)
-{
- DdNode *fv, *fnv, *G, *gv, *gnv;
- DdNode *one, *zero, *r, *t, *e;
- unsigned int topf, topg, index;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- 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;
- }
- if (g == zero) return(f);
- if (g == one) return(Cudd_Not(f));
- if (Cudd_IsComplement(f)) {
- f = Cudd_Not(f);
- g = Cudd_Not(g);
- }
- /* Now the first argument is regular. */
- if (f == one) return(Cudd_Not(g));
-
- /* At this point f and g are not constant. */
-
- /* Check cache. */
- r = cuddCacheLookup2(manager, Cudd_bddXor, 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];
- G = Cudd_Regular(g);
- topg = manager->perm[G->index];
-
- /* Compute cofactors. */
- if (topf <= topg) {
- index = f->index;
- fv = cuddT(f);
- fnv = cuddE(f);
- } else {
- 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);
- }
- } else {
- gv = gnv = g;
- }
-
- t = cuddBddXorRecur(manager, fv, gv);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddBddXorRecur(manager, fnv, gnv);
- 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);
- cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
- return(r);
-
-} /* end of cuddBddXorRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Replaces variables with constants if possible.]
-
- Description [This function performs part of the transformation to
- standard form by replacing variables with constants if possible.]
-
- SideEffects [None]
-
- SeeAlso [bddVarToCanonical bddVarToCanonicalSimple]
-
-******************************************************************************/
-static void
-bddVarToConst(
- DdNode * f,
- DdNode ** gp,
- DdNode ** hp,
- DdNode * one)
-{
- DdNode *g = *gp;
- DdNode *h = *hp;
-
- if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
- *gp = one;
- } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
- *gp = Cudd_Not(one);
- }
- if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
- *hp = Cudd_Not(one);
- } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
- *hp = one;
- }
-
-} /* end of bddVarToConst */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks unique member from equiv expressions.]
-
- Description [Reduces 2 variable expressions to canonical form.]
-
- SideEffects [None]
-
- SeeAlso [bddVarToConst bddVarToCanonicalSimple]
-
-******************************************************************************/
-static int
-bddVarToCanonical(
- DdManager * dd,
- DdNode ** fp,
- DdNode ** gp,
- DdNode ** hp,
- unsigned int * topfp,
- 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;
-
- f = *fp;
- g = *gp;
- h = *hp;
- F = Cudd_Regular(f);
- G = Cudd_Regular(g);
- H = Cudd_Regular(h);
- topf = cuddI(dd,F->index);
- topg = cuddI(dd,G->index);
- toph = cuddI(dd,H->index);
-
- 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);
- }
- 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);
- }
- 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;
- }
- 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;
- }
- if (change != 0) {
- *fp = f;
- *gp = g;
- *hp = h;
- }
- *topfp = cuddI(dd,f->index);
- *topgp = cuddI(dd,g->index);
- *tophp = cuddI(dd,Cudd_Regular(h)->index);
-
- return(comple);
-
-} /* end of bddVarToCanonical */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks unique member from equiv expressions.]
-
- Description [Makes sure the first two pointers are regular. This
- mat require the complementation of the result, which is signaled by
- returning 1 instead of 0. This function is simpler than the general
- case because it assumes that no two arguments are the same or
- complementary, and no argument is constant.]
-
- SideEffects [None]
-
- SeeAlso [bddVarToConst bddVarToCanonical]
-
-******************************************************************************/
-static int
-bddVarToCanonicalSimple(
- DdManager * dd,
- DdNode ** fp,
- DdNode ** gp,
- DdNode ** hp,
- unsigned int * topfp,
- unsigned int * topgp,
- unsigned int * tophp)
-{
- register DdNode *r, *f, *g, *h;
- int comple, change;
-
- f = *fp;
- g = *gp;
- h = *hp;
-
- 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;
- }
- 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 (change) {
- *fp = f;
- *gp = g;
- *hp = h;
- }
-
- /* Here we can skip the use of cuddI, because the operands are known
- ** to be non-constant.
- */
- *topfp = dd->perm[f->index];
- *topgp = dd->perm[g->index];
- *tophp = dd->perm[Cudd_Regular(h)->index];
-
- return(comple);
-
-} /* end of bddVarToCanonicalSimple */
-
diff --git a/src/bdd/cudd/cuddBridge.c b/src/bdd/cudd/cuddBridge.c
deleted file mode 100644
index ccc0893f..00000000
--- a/src/bdd/cudd/cuddBridge.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddBridge.c]
-
- PackageName [cudd]
-
- Synopsis [Translation from BDD to ADD and vice versa and transfer between
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Converts an ADD to a BDD.]
-
- Description [Converts an ADD to a BDD by replacing all
- discriminants greater than or equal to value with 1, and all other
- discriminants with 0. Returns a pointer to the resulting BDD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd
- Cudd_addBddStrictThreshold]
-
-******************************************************************************/
-DdNode *
-Cudd_addBddThreshold(
- DdManager * dd,
- DdNode * f,
- CUDD_VALUE_TYPE value)
-{
- DdNode *res;
- DdNode *val;
-
- val = cuddUniqueConst(dd,value);
- if (val == NULL) return(NULL);
- cuddRef(val);
-
- do {
- dd->reordered = 0;
- res = addBddDoThreshold(dd, f, val);
- } while (dd->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(dd, val);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, val);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addBddThreshold */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts an ADD to a BDD.]
-
- Description [Converts an ADD to a BDD by replacing all
- discriminants STRICTLY greater than value with 1, and all other
- discriminants with 0. Returns a pointer to the resulting BDD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd
- Cudd_addBddThreshold]
-
-******************************************************************************/
-DdNode *
-Cudd_addBddStrictThreshold(
- DdManager * dd,
- DdNode * f,
- CUDD_VALUE_TYPE value)
-{
- DdNode *res;
- DdNode *val;
-
- val = cuddUniqueConst(dd,value);
- if (val == NULL) return(NULL);
- cuddRef(val);
-
- do {
- dd->reordered = 0;
- res = addBddDoStrictThreshold(dd, f, val);
- } while (dd->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(dd, val);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, val);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addBddStrictThreshold */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts an ADD to a BDD.]
-
- Description [Converts an ADD to a BDD by replacing all
- discriminants greater than or equal to lower and less than or equal to
- upper with 1, and all other discriminants with 0. Returns a pointer to
- the resulting BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold
- Cudd_addBddPattern Cudd_BddToAdd]
-
-******************************************************************************/
-DdNode *
-Cudd_addBddInterval(
- DdManager * dd,
- DdNode * f,
- CUDD_VALUE_TYPE lower,
- CUDD_VALUE_TYPE upper)
-{
- DdNode *res;
- DdNode *l;
- DdNode *u;
-
- /* Create constant nodes for the interval bounds, so that we can use
- ** the global cache.
- */
- l = cuddUniqueConst(dd,lower);
- if (l == NULL) return(NULL);
- cuddRef(l);
- u = cuddUniqueConst(dd,upper);
- if (u == NULL) {
- Cudd_RecursiveDeref(dd,l);
- return(NULL);
- }
- cuddRef(u);
-
- do {
- 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);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, l);
- Cudd_RecursiveDeref(dd, u);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addBddInterval */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts an ADD to a BDD by extracting the i-th bit from
- the leaves.]
-
- Description [Converts an ADD to a BDD by replacing all
- discriminants whose i-th bit is equal to 1 with 1, and all other
- discriminants with 0. The i-th bit refers to the integer
- representation of the leaf value. If the value is has a fractional
- part, it is ignored. Repeated calls to this procedure allow one to
- transform an integer-valued ADD into an array of BDDs, one for each
- bit of the leaf values. Returns a pointer to the resulting BDD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd]
-
-******************************************************************************/
-DdNode *
-Cudd_addBddIthBit(
- DdManager * dd,
- DdNode * f,
- int bit)
-{
- DdNode *res;
- DdNode *index;
-
- index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit);
- if (index == NULL) return(NULL);
- cuddRef(index);
-
- do {
- dd->reordered = 0;
- res = addBddDoIthBit(dd, f, index);
- } while (dd->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(dd, index);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, index);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addBddIthBit */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a BDD to a 0-1 ADD.]
-
- Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the
- resulting ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval
- Cudd_addBddStrictThreshold]
-
-******************************************************************************/
-DdNode *
-Cudd_BddToAdd(
- DdManager * dd,
- DdNode * B)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = ddBddToAddRecur(dd, B);
- } while (dd->reordered ==1);
- return(res);
-
-} /* end of Cudd_BddToAdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts an ADD to a BDD.]
-
- Description [Converts an ADD to a BDD by replacing all
- discriminants different from 0 with 1. Returns a pointer to the
- resulting BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval
- Cudd_addBddStrictThreshold]
-
-******************************************************************************/
-DdNode *
-Cudd_addBddPattern(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddBddDoPattern(dd, f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addBddPattern */
-
-
-/**Function********************************************************************
-
- Synopsis [Convert a BDD from a manager to another one.]
-
- Description [Convert a BDD from a manager to another one. The orders of the
- variables in the two managers may be different. Returns a
- pointer to the BDD in the destination manager if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_bddTransfer(
- DdManager * ddSource,
- DdManager * ddDestination,
- DdNode * f)
-{
- DdNode *res;
- do {
- ddDestination->reordered = 0;
- res = cuddBddTransfer(ddSource, ddDestination, f);
- } while (ddDestination->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddTransfer */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Convert a BDD from a manager to another one.]
-
- Description [Convert a BDD from a manager to another one. Returns a
- pointer to the BDD in the destination manager if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddTransfer]
-
-******************************************************************************/
-DdNode *
-cuddBddTransfer(
- DdManager * ddS,
- DdManager * ddD,
- DdNode * f)
-{
- DdNode *res;
- st_table *table = NULL;
- st_generator *gen = NULL;
- DdNode *key, *value;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) goto failure;
- res = cuddBddTransferRecur(ddS, ddD, f, table);
- if (res != NULL) cuddRef(res);
-
- /* Dereference all elements in the table and dispose of the table.
- ** This must be done also if res is NULL to avoid leaks in case of
- ** reordering. */
- gen = st_init_gen(table);
- if (gen == NULL) goto failure;
- while (st_gen(gen, (char **) &key, (char **) &value)) {
- Cudd_RecursiveDeref(ddD, value);
- }
- st_free_gen(gen); gen = NULL;
- st_free_table(table); table = NULL;
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-failure:
- if (table != NULL) st_free_table(table);
- if (gen != NULL) st_free_gen(gen);
- return(NULL);
-
-} /* end of cuddBddTransfer */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addBddPattern.]
-
- Description [Performs the recursive step for Cudd_addBddPattern. Returns a
- pointer to the resulting BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddAddBddDoPattern(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int v;
-
- statLine(dd);
- /* Check terminal case. */
- if (cuddIsConstant(f)) {
- return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd)));
- }
-
- /* Check cache. */
- res = cuddCacheLookup1(dd,Cudd_addBddPattern,f);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = cuddAddBddDoPattern(dd,fv);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- 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);
- } else {
- 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);
-
- /* Store result. */
- cuddCacheInsert1(dd,Cudd_addBddPattern,f,res);
-
- return(res);
-
-} /* end of cuddAddBddDoPattern */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addBddThreshold.]
-
- Description [Performs the recursive step for Cudd_addBddThreshold.
- Returns a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [addBddDoStrictThreshold]
-
-******************************************************************************/
-static DdNode *
-addBddDoThreshold(
- DdManager * dd,
- DdNode * f,
- DdNode * val)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int v;
-
- statLine(dd);
- /* Check terminal case. */
- if (cuddIsConstant(f)) {
- return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val)));
- }
-
- /* Check cache. */
- res = cuddCacheLookup2(dd,addBddDoThreshold,f,val);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = addBddDoThreshold(dd,fv,val);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- 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);
- } else {
- 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);
-
- /* Store result. */
- cuddCacheInsert2(dd,addBddDoThreshold,f,val,res);
-
- return(res);
-
-} /* end of addBddDoThreshold */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.]
-
- Description [Performs the recursive step for Cudd_addBddStrictThreshold.
- Returns a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [addBddDoThreshold]
-
-******************************************************************************/
-static DdNode *
-addBddDoStrictThreshold(
- DdManager * dd,
- DdNode * f,
- DdNode * val)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int v;
-
- statLine(dd);
- /* Check terminal case. */
- if (cuddIsConstant(f)) {
- return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val)));
- }
-
- /* Check cache. */
- res = cuddCacheLookup2(dd,addBddDoStrictThreshold,f,val);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = addBddDoStrictThreshold(dd,fv,val);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- 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);
- } else {
- 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);
-
- /* Store result. */
- cuddCacheInsert2(dd,addBddDoStrictThreshold,f,val,res);
-
- return(res);
-
-} /* end of addBddDoStrictThreshold */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addBddInterval.]
-
- Description [Performs the recursive step for Cudd_addBddInterval.
- Returns a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [addBddDoThreshold addBddDoStrictThreshold]
-
-******************************************************************************/
-static DdNode *
-addBddDoInterval(
- DdManager * dd,
- DdNode * f,
- DdNode * l,
- DdNode * u)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int v;
-
- statLine(dd);
- /* Check terminal case. */
- if (cuddIsConstant(f)) {
- return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u)));
- }
-
- /* Check cache. */
- res = cuddCacheLookup(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = addBddDoInterval(dd,fv,l,u);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- 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);
- } else {
- 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);
-
- /* Store result. */
- cuddCacheInsert(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u,res);
-
- return(res);
-
-} /* end of addBddDoInterval */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_addBddIthBit.]
-
- Description [Performs the recursive step for Cudd_addBddIthBit.
- Returns a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-addBddDoIthBit(
- DdManager * dd,
- DdNode * f,
- DdNode * index)
-{
- DdNode *res, *T, *E;
- DdNode *fv, *fvn;
- int mask, value;
- int v;
-
- 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));
- }
-
- /* Check cache. */
- res = cuddCacheLookup2(dd,addBddDoIthBit,f,index);
- if (res != NULL) return(res);
-
- /* Recursive step. */
- v = f->index;
- fv = cuddT(f); fvn = cuddE(f);
-
- T = addBddDoIthBit(dd,fv,index);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- 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);
- } else {
- 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);
-
- /* Store result. */
- cuddCacheInsert2(dd,addBddDoIthBit,f,index,res);
-
- return(res);
-
-} /* end of addBddDoIthBit */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step for Cudd_BddToAdd.]
-
- Description [Performs the recursive step for Cudd_BddToAdd. Returns a
- pointer to the resulting ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-ddBddToAddRecur(
- DdManager * dd,
- DdNode * B)
-{
- DdNode *one;
- DdNode *res, *res1, *T, *E, *Bt, *Be;
- int complement = 0;
-
- statLine(dd);
- one = DD_ONE(dd);
-
- if (Cudd_IsConstant(B)) {
- 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));
- } else {
- Bt = cuddT(B);
- Be = cuddE(B);
- }
-
- T = ddBddToAddRecur(dd, Bt);
- if (T == NULL) return(NULL);
- cuddRef(T);
-
- E = ddBddToAddRecur(dd, Be);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
-
- if (complement) {
- cuddRef(res);
- res1 = cuddAddCmplRecur(dd, res);
- if (res1 == NULL) {
- Cudd_RecursiveDeref(dd, res);
- return(NULL);
- }
- cuddRef(res1);
- Cudd_RecursiveDeref(dd, res);
- res = res1;
- cuddDeref(res);
- }
-
- /* Store result. */
- cuddCacheInsert1(dd,ddBddToAddRecur,B,res);
-
- return(res);
-
-} /* end of ddBddToAddRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddTransfer.]
-
- Description [Performs the recursive step of Cudd_bddTransfer.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddBddTransfer]
-
-******************************************************************************/
-static DdNode *
-cuddBddTransferRecur(
- DdManager * ddS,
- DdManager * ddD,
- DdNode * f,
- st_table * table)
-{
- DdNode *ft, *fe, *t, *e, *var, *res;
- DdNode *one, *zero;
- int index;
- int comple = 0;
-
- statLine(ddD);
- one = DD_ONE(ddD);
- comple = Cudd_IsComplement(f);
-
- /* Trivial cases. */
- if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple));
-
- /* Make canonical to increase the utilization of the cache. */
- f = Cudd_NotCond(f,comple);
- /* 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));
-
- /* Recursive step. */
- index = f->index;
- ft = cuddT(f); fe = cuddE(f);
-
- t = cuddBddTransferRecur(ddS, ddD, ft, table);
- if (t == NULL) {
- return(NULL);
- }
- cuddRef(t);
-
- e = cuddBddTransferRecur(ddS, ddD, fe, table);
- if (e == NULL) {
- Cudd_RecursiveDeref(ddD, t);
- return(NULL);
- }
- cuddRef(e);
-
- zero = Cudd_Not(one);
- var = cuddUniqueInter(ddD,index,one,zero);
- if (var == NULL) {
- 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);
- }
- 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);
- }
- return(Cudd_NotCond(res,comple));
-
-} /* end of cuddBddTransferRecur */
-
diff --git a/src/bdd/cudd/cuddCache.c b/src/bdd/cudd/cuddCache.c
deleted file mode 100644
index d9e40921..00000000
--- a/src/bdd/cudd/cuddCache.c
+++ /dev/null
@@ -1,1023 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddCache.c]
-
- PackageName [cudd]
-
- 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> ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifdef DD_CACHE_PROFILE
-#define DD_HYSTO_BINS 8
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes the computed table.]
-
- Description [Initializes the computed table. It is called by
- Cudd_Init. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Init]
-
-******************************************************************************/
-int
-cuddInitCache(
- DdManager * unique /* unique table */,
- unsigned int cacheSize /* initial size of the cache */,
- unsigned int maxCacheSize /* cache size beyond which no resizing occurs */)
-{
- int i;
- unsigned int logSize;
-#ifndef DD_CACHE_PROFILE
- DdNodePtr *mem;
- ptruint offset;
-#endif
-
- /* Round cacheSize to largest power of 2 not greater than the requested
- ** initial cache size. */
- logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2));
- cacheSize = 1 << logSize;
- unique->acache = ALLOC(DdCache,cacheSize+1);
- if (unique->acache == NULL) {
- 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
- ** DD_CACHE_PROFILE is not defined. */
-#ifdef DD_CACHE_PROFILE
- unique->cache = unique->acache;
- unique->memused += (cacheSize) * sizeof(DdCache);
-#else
- mem = (DdNodePtr *) unique->acache;
- offset = (ptruint) mem & (sizeof(DdCache) - 1);
- mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr);
- unique->cache = (DdCache *) mem;
- assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0);
- unique->memused += (cacheSize+1) * sizeof(DdCache);
-#endif
- unique->cacheSlots = cacheSize;
- unique->cacheShift = sizeof(int) * 8 - logSize;
- 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;
- Cudd_SetMinHit(unique,DD_MIN_HIT);
- /* Initialize to avoid division by 0 and immediate resizing. */
- unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1);
- unique->cacheHits = 0;
- unique->totCachehits = 0;
- /* The sum of cacheMisses and totCacheMisses is always correct,
- ** even though cacheMisses is larger than it should for the reasons
- ** explained above. */
- unique->totCacheMisses = -unique->cacheMisses;
- unique->cachecollisions = 0;
- unique->cacheinserts = 0;
- unique->cacheLastInserts = 0;
- unique->cachedeletions = 0;
-
- /* Initialize the cache */
- for (i = 0; (unsigned) i < cacheSize; i++) {
- unique->cache[i].h = 0; /* unused slots */
- unique->cache[i].data = NULL; /* invalid entry */
-#ifdef DD_CACHE_PROFILE
- unique->cache[i].count = 0;
-#endif
- }
-
- return(1);
-
-} /* end of cuddInitCache */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a result in the cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddCacheInsert2 cuddCacheInsert1]
-
-******************************************************************************/
-void
-cuddCacheInsert(
- DdManager * table,
- ptruint op,
- DdNode * f,
- DdNode * g,
- DdNode * h,
- DdNode * data)
-{
- int posn;
- register DdCache *entry;
- ptruint uf, ug, uh;
-
- uf = (ptruint) f | (op & 0xe);
- ug = (ptruint) g | (op >> 4);
- uh = (ptruint) h;
-
- posn = ddCHash2(uh,uf,ug,table->cacheShift);
- entry = &table->cache[posn];
-
- table->cachecollisions += entry->data != NULL;
- table->cacheinserts++;
-
- entry->f = (DdNode *) uf;
- entry->g = (DdNode *) ug;
- entry->h = uh;
- entry->data = data;
-#ifdef DD_CACHE_PROFILE
- entry->count++;
-#endif
-
-} /* end of cuddCacheInsert */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a result in the cache for a function with two
- operands.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddCacheInsert cuddCacheInsert1]
-
-******************************************************************************/
-void
-cuddCacheInsert2(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *, DdNode *),
- DdNode * f,
- DdNode * g,
- DdNode * data)
-{
- int posn;
- register DdCache *entry;
-
- posn = ddCHash2(op,f,g,table->cacheShift);
- entry = &table->cache[posn];
-
- if (entry->data != NULL) {
- table->cachecollisions++;
- }
- table->cacheinserts++;
-
- entry->f = f;
- entry->g = g;
- entry->h = (ptruint) op;
- entry->data = data;
-#ifdef DD_CACHE_PROFILE
- entry->count++;
-#endif
-
-} /* end of cuddCacheInsert2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a result in the cache for a function with two
- operands.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddCacheInsert cuddCacheInsert2]
-
-******************************************************************************/
-void
-cuddCacheInsert1(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *),
- DdNode * f,
- DdNode * data)
-{
- int posn;
- register DdCache *entry;
-
- posn = ddCHash2(op,f,f,table->cacheShift);
- entry = &table->cache[posn];
-
- if (entry->data != NULL) {
- table->cachecollisions++;
- }
- table->cacheinserts++;
-
- entry->f = f;
- entry->g = f;
- entry->h = (ptruint) op;
- entry->data = data;
-#ifdef DD_CACHE_PROFILE
- entry->count++;
-#endif
-
-} /* end of cuddCacheInsert1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f,
- g, and h.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookup2 cuddCacheLookup1]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookup(
- DdManager * table,
- ptruint op,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
- ptruint uf, ug, uh;
-
- uf = (ptruint) f | (op & 0xe);
- ug = (ptruint) g | (op >> 4);
- uh = (ptruint) h;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f,
- g, and h.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookupZdd(
- DdManager * table,
- ptruint op,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
- ptruint uf, ug, uh;
-
- uf = (ptruint) f | (op & 0xe);
- ug = (ptruint) g | (op >> 4);
- uh = (ptruint) h;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookupZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f
- and g.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookup cuddCacheLookup1]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookup2(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *, DdNode *),
- DdNode * f,
- DdNode * g)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookup2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookup cuddCacheLookup2]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookup1(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *),
- DdNode * f)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookup1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f
- and g.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookup2Zdd(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *, DdNode *),
- DdNode * f,
- DdNode * g)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookup2Zdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f.]
-
- Description [Returns the result if found; it returns NULL if no
- result is found.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd]
-
-******************************************************************************/
-DdNode *
-cuddCacheLookup1Zdd(
- DdManager * table,
- DdNode * (*op)(DdManager *, DdNode *),
- DdNode * f)
-{
- int posn;
- DdCache *en,*cache;
- DdNode *data;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
-
- 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);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddCacheLookup1Zdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in the cache for the result of op applied to f,
- g, and h.]
-
- Description [Looks up in the cache for the result of op applied to f,
- g, and h. Assumes that the calling procedure (e.g.,
- Cudd_bddIteConstant) is only interested in whether the result is
- constant or not. Returns the result if found (possibly
- DD_NON_CONSTANT); otherwise it returns NULL.]
-
- SideEffects [None]
-
- SeeAlso [cuddCacheLookup]
-
-******************************************************************************/
-DdNode *
-cuddConstantLookup(
- DdManager * table,
- ptruint op,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- int posn;
- DdCache *en,*cache;
- ptruint uf, ug, uh;
-
- uf = (ptruint) f | (op & 0xe);
- ug = (ptruint) g | (op >> 4);
- uh = (ptruint) h;
-
- cache = table->cache;
-#ifdef DD_DEBUG
- if (cache == NULL) {
- return(NULL);
- }
-#endif
- posn = ddCHash2(uh,uf,ug,table->cacheShift);
- en = &cache[posn];
-
- /* We do not reclaim here because the result should not be
- * 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++;
- return(en->data);
- }
-
- /* Cache miss: decide whether to resize. */
- table->cacheMisses++;
-
- if (table->cacheSlack >= 0 &&
- table->cacheHits > table->cacheMisses * table->minHit) {
- cuddCacheResize(table);
- }
-
- return(NULL);
-
-} /* end of cuddConstantLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes and prints a profile of the cache usage.]
-
- Description [Computes and prints a profile of the cache usage.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddCacheProfile(
- DdManager * table,
- FILE * fp)
-{
- DdCache *cache = table->cache;
- int slots = table->cacheSlots;
- int nzeroes = 0;
- int i, retval;
- double exUsed;
-
-#ifdef DD_CACHE_PROFILE
- double count, mean, meansq, stddev, expected;
- long max, min;
- int imax, imin;
- double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */
- int nbins = DD_HYSTO_BINS;
- int bin;
- long thiscount;
- double totalcount, exStddev;
-
- meansq = mean = expected = 0.0;
- max = min = (long) cache[0].count;
- imax = imin = 0;
- totalcount = 0.0;
-
- hystogramQ = ALLOC(double, nbins);
- if (hystogramQ == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- hystogramR = ALLOC(double, nbins);
- if (hystogramR == NULL) {
- FREE(hystogramQ);
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (i = 0; i < nbins; i++) {
- 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;
- }
- 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);
- exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots);
-
- retval = fprintf(fp,"Cache average accesses = %g\n", mean);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache access standard deviation = %g ", stddev);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"(expected = %g)\n", exStddev);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
- 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);
- 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]);
- 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);
- }
-
- FREE(hystogramQ);
- FREE(hystogramR);
-#else
- for (i = 0; i < slots; i++) {
- nzeroes += cache[i].h == 0;
- }
- exUsed = 100.0 *
- (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);
- if (retval == EOF) return(0);
-#endif
- return(1);
-
-} /* end of cuddCacheProfile */
-
-
-/**Function********************************************************************
-
- Synopsis [Resizes the cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddCacheResize(
- DdManager * table)
-{
- DdCache *cache, *oldcache, *oldacache, *entry, *old;
- int i;
- int posn, shift;
- unsigned int slots, oldslots;
- double offset;
- int moved = 0;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-#ifndef DD_CACHE_PROFILE
- ptruint misalignment;
- DdNodePtr *mem;
-#endif
-
- oldcache = table->cache;
- oldacache = table->acache;
- oldslots = table->cacheSlots;
- slots = table->cacheSlots = oldslots << 1;
-
-#ifdef DD_VERBOSE
- (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n",
- 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));
-#endif
-
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- table->acache = cache = ALLOC(DdCache,slots+1);
- MMoutOfMemory = saveHandler;
- /* 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");
-#endif
- table->cacheSlots = oldslots;
- table->acache = oldacache;
- /* Do not try to resize again. */
- table->maxCacheHard = oldslots - 1;
- table->cacheSlack = - (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
- ** DD_CACHE_PROFILE is not defined. */
-#ifdef DD_CACHE_PROFILE
- table->cache = cache;
-#else
- mem = (DdNodePtr *) cache;
- misalignment = (ptruint) mem & (sizeof(DdCache) - 1);
- mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr);
- table->cache = cache = (DdCache *) mem;
- assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0);
-#endif
- shift = --(table->cacheShift);
- table->memused += (slots - oldslots) * sizeof(DdCache);
- table->cacheSlack -= slots; /* need these many slots to double again */
-
- /* Clear new cache. */
- for (i = 0; (unsigned) i < slots; i++) {
- cache[i].data = NULL;
- cache[i].h = 0;
-#ifdef DD_CACHE_PROFILE
- 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;
-#ifdef DD_CACHE_PROFILE
- entry->count = 1;
-#endif
- moved++;
- }
- }
-
- FREE(oldacache);
-
- /* Reinitialize measurements so as to avoid division by 0 and
- ** immediate resizing.
- */
- offset = (double) (int) (slots * table->minHit + 1);
- table->totCacheMisses += table->cacheMisses - offset;
- table->cacheMisses = offset;
- table->totCachehits += table->cacheHits;
- table->cacheHits = 0;
- table->cacheLastInserts = table->cacheinserts - (double) moved;
-
-} /* end of cuddCacheResize */
-
-
-/**Function********************************************************************
-
- Synopsis [Flushes the cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddCacheFlush(
- DdManager * table)
-{
- int i, slots;
- DdCache *cache;
-
- slots = table->cacheSlots;
- cache = table->cache;
- for (i = 0; i < slots; i++) {
- table->cachedeletions += cache[i].data != NULL;
- cache[i].data = NULL;
- }
- table->cacheLastInserts = table->cacheinserts;
-
- return;
-
-} /* end of cuddCacheFlush */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the floor of the logarithm to the base 2.]
-
- Description [Returns the floor of the logarithm to the base 2.
- The input value is assumed to be greater than 0.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddComputeFloorLog2(
- unsigned int value)
-{
- int floorLog = 0;
-#ifdef DD_DEBUG
- assert(value > 0);
-#endif
- while (value > 1) {
- floorLog++;
- value >>= 1;
- }
- return(floorLog);
-
-} /* end of cuddComputeFloorLog2 */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
diff --git a/src/bdd/cudd/cuddCheck.c b/src/bdd/cudd/cuddCheck.c
deleted file mode 100644
index aec8246d..00000000
--- a/src/bdd/cudd/cuddCheck.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddCheck.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static void debugFindParent ARGS((DdManager *table, DdNode *node));
-#if 0
-static void debugCheckParent ARGS((DdManager *table, DdNode *node));
-#endif
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for inconsistencies in the DD heap.]
-
- Description [Checks for inconsistencies in the DD heap:
- <ul>
- <li> node has illegal index
- <li> live node has dead children
- <li> node has illegal Then or Else pointers
- <li> BDD/ADD node has identical children
- <li> ZDD node has zero then child
- <li> wrong number of total nodes
- <li> wrong number of dead nodes
- <li> ref count error at node
- </ul>
- Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is
- not enough memory; 1 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CheckKeys]
-
-******************************************************************************/
-int
-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);
- 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) {
- (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++;
-#if 0
- debugCheckParent(table,f);
-#endif
- } 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;
- }
- 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)) {
- (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++;
-#if 0
- debugCheckParent(table,f);
-#endif
- } 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: 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 */
-
- /* Check the constant table. */
- nodelist = table->constants.nodelist;
- slots = table->constants.slots;
-
- 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");
-#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));
-#else
- fprintf(table->err,
- " node 0x%x, id = %d, ref = %d, value = %g\n",
- (unsigned)f,f->index,f->ref,cuddV(f));
-#endif
- flag = 1;
- }
- } else {
- deadNode++;
- }
- f = f->next;
- }
- }
- if ((unsigned) totalNode != table->constants.keys) {
- (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;
- }
- gen = st_init_gen(edgeTable);
- while (st_gen(gen,(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));
-#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));
-#endif
- debugFindParent(table,f);
- flag = 1;
- }
- }
- st_free_gen(gen);
- st_free_table(edgeTable);
-
- return (flag);
-
-} /* end of Cudd_DebugCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for several conditions that should not occur.]
-
- Description [Checks for the following conditions:
- <ul>
- <li>Wrong sizes of subtables.
- <li>Wrong number of keys found in unique subtable.
- <li>Wrong number of dead found in unique subtable.
- <li>Wrong number of keys found in the constant table
- <li>Wrong number of dead found in the constant table
- <li>Wrong number of total slots found
- <li>Wrong number of maximum keys found
- <li>Wrong number of total dead found
- </ul>
- Reports the average length of non-empty lists. Returns the number of
- subtables for which the number of keys is wrong.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DebugCheck]
-
-******************************************************************************/
-int
-Cudd_CheckKeys(
- DdManager * table)
-{
- int size;
- int i,j;
- DdNodePtr *nodelist;
- DdNode *node;
- DdNode *sentinel = &(table->sentinel);
- DdSubtable *subtable;
- int keys;
- int dead;
- int count = 0;
- int totalKeys = 0;
- int totalSlots = 0;
- int totalDead = 0;
- int nonEmpty = 0;
- unsigned int slots;
- int logSlots;
- int shift;
-
- 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--;
- }
- node = node->next;
- }
- }
- 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 \
-in unique table no. %d (difference=%d)\n", i, dead);
- }
- } /* 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;
- }
- }
- 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 \
-in ZDD unique table no. %d (difference=%d)\n", i, dead);
- }
- } /* for each ZDD subtable */
-
- /* Check the constant table. */
- subtable = &(table->constants);
- 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 \
-in the constant table (difference=%d)\n", keys);
- count++;
- }
- if (dead != 0) {
- (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);
- }
- if ((unsigned) totalSlots != table->slots) {
- (void) fprintf(table->err, "Wrong number of total slots found \
-(difference=%d)\n", 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));
- }
- if ((unsigned) totalDead != table->dead + table->deadZ) {
- (void) fprintf(table->err, "Wrong number of total dead found \
-(difference=%d)\n", totalDead-table->dead);
- }
- (void)printf("Average length of non-empty lists = %g\n",
- (double) table->keys / (double) nonEmpty);
-
- return(count);
-
-} /* end of Cudd_CheckKeys */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints information about the heap.]
-
- Description [Prints to the manager's stdout the number of live nodes for each
- level of the DD heap that contains at least one live node. It also
- prints a summary containing:
- <ul>
- <li> total number of tables;
- <li> number of tables with live nodes;
- <li> table with the largest number of live nodes;
- <li> number of nodes in that table.
- </ul>
- If more than one table contains the maximum number of live nodes,
- only the one of lowest index is reported. Returns 1 in case of success
- and 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddHeapProfile(
- DdManager * dd)
-{
- 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 */
-
- /* Print header. */
-#if SIZEOF_VOID_P == 8
- retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n",
- (unsigned long) dd);
-#else
- retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n",
- (unsigned) 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 = 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;
- }
- }
-
- /* Print summary. */
- retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ",
- ntables+1, nonempty, largest);
- if (retval == EOF) return 0;
- retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes);
- if (retval == EOF) return 0;
-
- return(1);
-
-} /* end of cuddHeapProfile */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints out information on a node.]
-
- Description [Prints out information on a node.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddPrintNode(
- DdNode * f,
- FILE *fp)
-{
- 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));
-#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));
-#endif
-
-} /* end of cuddPrintNode */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the variable groups as a parenthesized list.]
-
- Description [Prints the variable groups as a parenthesized list.
- For each group the level range that it represents is printed. After
- each group, the group's flags are printed, preceded by a `|'. For
- each flag (except MTR_TERMINAL) a character is printed.
- <ul>
- <li>F: MTR_FIXED
- <li>N: MTR_NEWNODE
- <li>S: MTR_SOFT
- </ul>
- The second argument, silent, if different from 0, causes
- Cudd_PrintVarGroups to only check the syntax of the group tree.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddPrintVarGroups(
- DdManager * dd /* manager */,
- MtrNode * root /* root of the group tree */,
- int zdd /* 0: BDD; 1: ZDD */,
- int silent /* flag to check tree syntax only */)
-{
- MtrNode *node;
- int level;
-
- assert(root != NULL);
- assert(root->younger == NULL || root->younger->elder == root);
- assert(root->elder == NULL || root->elder->younger == root);
- if (zdd) {
- level = dd->permZ[root->index];
- } else {
- level = dd->perm[root->index];
- }
- if (!silent) (void) printf("(%d",level);
- if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
- 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;
- }
- }
- 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");
- }
- assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
- return;
-
-} /* end of cuddPrintVarGroups */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Searches the subtables above node for its parents.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-debugFindParent(
- DdManager * table,
- DdNode * node)
-{
- int i,j;
- 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;
-
- 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));
-#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));
-#endif
- }
- f = f->next;
- }
- }
- }
-
-} /* end of debugFindParent */
-
-
-#if 0
-/**Function********************************************************************
-
- Synopsis [Reports an error if a (dead) node has a non-dead parent.]
-
- Description [Searches all the subtables above node. Very expensive.
- The same check is now implemented more efficiently in ddDebugCheck.]
-
- SideEffects [None]
-
- SeeAlso [debugFindParent]
-
-******************************************************************************/
-static void
-debugCheckParent(
- DdManager * table,
- 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;
-
- 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;
- }
- }
- }
-}
-#endif
diff --git a/src/bdd/cudd/cuddClip.c b/src/bdd/cudd/cuddClip.c
deleted file mode 100644
index 4da296ef..00000000
--- a/src/bdd/cudd/cuddClip.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddClip.c]
-
- PackageName [cudd]
-
- Synopsis [Clipping functions.]
-
- Description [External procedures included in this module:
- <ul>
- <li> Cudd_bddClippingAnd()
- <li> Cudd_bddClippingAndAbstract()
- </ul>
- Internal procedures included in this module:
- <ul>
- <li> cuddBddClippingAnd()
- <li> cuddBddClippingAndAbstract()
- </ul>
- Static procedures included in this module:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Approximates the conjunction of two BDDs f and g.]
-
- Description [Approximates the conjunction of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddAnd]
-
-******************************************************************************/
-DdNode *
-Cudd_bddClippingAnd(
- DdManager * dd /* manager */,
- DdNode * f /* first conjunct */,
- DdNode * g /* second conjunct */,
- int maxDepth /* maximum recursion depth */,
- int direction /* under (0) or over (1) approximation */)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddClippingAnd(dd,f,g,maxDepth,direction);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddClippingAnd */
-
-
-/**Function********************************************************************
-
- Synopsis [Approximates the conjunction of two BDDs f and g and
- simultaneously abstracts the variables in cube.]
-
- Description [Approximates the conjunction of two BDDs f and g and
- simultaneously abstracts the variables in cube. The variables are
- existentially abstracted. Returns a pointer to the resulting BDD if
- successful; NULL if the intermediate result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd]
-
-******************************************************************************/
-DdNode *
-Cudd_bddClippingAndAbstract(
- DdManager * dd /* manager */,
- DdNode * f /* first conjunct */,
- DdNode * g /* second conjunct */,
- DdNode * cube /* cube of variables to be abstracted */,
- int maxDepth /* maximum recursion depth */,
- int direction /* under (0) or over (1) approximation */)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddClippingAndAbstract */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Approximates the conjunction of two BDDs f and g.]
-
- Description [Approximates the conjunction of two BDDs f and g. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddClippingAnd]
-
-******************************************************************************/
-DdNode *
-cuddBddClippingAnd(
- DdManager * dd /* manager */,
- DdNode * f /* first conjunct */,
- DdNode * g /* second conjunct */,
- int maxDepth /* maximum recursion depth */,
- int direction /* under (0) or over (1) approximation */)
-{
- DdNode *res;
-
- res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction);
-
- return(res);
-
-} /* end of cuddBddClippingAnd */
-
-
-/**Function********************************************************************
-
- Synopsis [Approximates the conjunction of two BDDs f and g and
- simultaneously abstracts the variables in cube.]
-
- Description [Approximates the conjunction of two BDDs f and g and
- simultaneously abstracts the variables in cube. Returns a
- pointer to the resulting BDD if successful; NULL if the intermediate
- result blows up.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddClippingAndAbstract]
-
-******************************************************************************/
-DdNode *
-cuddBddClippingAndAbstract(
- DdManager * dd /* manager */,
- DdNode * f /* first conjunct */,
- DdNode * g /* second conjunct */,
- DdNode * cube /* cube of variables to be abstracted */,
- int maxDepth /* maximum recursion depth */,
- int direction /* under (0) or over (1) approximation */)
-{
- DdNode *res;
-
- res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction);
-
- return(res);
-
-} /* end of cuddBddClippingAndAbstract */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddClippingAnd.]
-
- Description [Implements the recursive step of Cudd_bddClippingAnd by taking
- the conjunction of two BDDs. Returns a pointer to the result is
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddBddClippingAnd]
-
-******************************************************************************/
-static DdNode *
-cuddBddClippingAndRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- int distance,
- int direction)
-{
- DdNode *F, *ft, *fe, *G, *gt, *ge;
- DdNode *one, *zero, *r, *t, *e;
- unsigned int topf, topg, index;
- DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
- 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)));
- }
-
- /* At this point f and g are not constant. */
- distance--;
-
- /* Check cache. Try to increase cache efficiency by sorting the
- ** pointers. */
- if (f > g) {
- DdNode *tmp = f;
- f = g; g = tmp;
- }
- F = Cudd_Regular(f);
- G = Cudd_Regular(g);
- cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *))
- (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd);
- if (F->ref != 1 || G->ref != 1) {
- r = cuddCacheLookup2(manager, cacheOp, 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];
-
- /* 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);
- }
- } else {
- 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);
- }
- } else {
- gt = ge = g;
- }
-
- t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction);
- if (e == NULL) {
- Cudd_RecursiveDeref(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_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);
- return(r);
-
-} /* end of cuddBddClippingAndRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the
- variables in cube.]
-
- Description [Approximates the AND of two BDDs and simultaneously
- abstracts the variables in cube. The variables are existentially
- abstracted. Returns a pointer to the result is successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddClippingAndAbstract]
-
-******************************************************************************/
-static DdNode *
-cuddBddClipAndAbsRecur(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube,
- int distance,
- int direction)
-{
- DdNode *F, *ft, *fe, *G, *gt, *ge;
- DdNode *one, *zero, *r, *t, *e, *Cube;
- unsigned int topf, topg, topcube, top, index;
- ptruint cacheTag;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
- if (f == one && g == one) return(one);
- if (cube == one) {
- return(cuddBddClippingAndRecur(manager, f, g, distance, direction));
- }
- if (f == one || f == g) {
- return (cuddBddExistAbstractRecur(manager, g, cube));
- }
- if (g == one) {
- return (cuddBddExistAbstractRecur(manager, f, cube));
- }
- if (distance == 0) return(Cudd_NotCond(one,(direction == 0)));
-
- /* At this point f, g, and cube are not constant. */
- distance--;
-
- /* Check cache. */
- if (f > g) { /* Try to increase cache efficiency. */
- 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;
- if (F->ref != 1 || G->ref != 1) {
- 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
- ** to be non-constant.
- */
- topf = manager->perm[F->index];
- topg = manager->perm[G->index];
- top = ddMin(topf, topg);
- topcube = manager->perm[cube->index];
-
- if (topcube < top) {
- 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);
- }
- } else {
- 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);
- }
- } else {
- gt = ge = g;
- }
-
- if (topcube == top) {
- Cube = cuddT(cube);
- } else {
- Cube = cube;
- }
-
- t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction);
- if (t == NULL) return(NULL);
-
- /* Special case: 1 OR anything = 1. Hence, no need to compute
- ** 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);
- }
- 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));
- 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)
- cuddCacheInsert(manager, cacheTag, f, g, cube, r);
- return (r);
-
-} /* end of cuddBddClipAndAbsRecur */
-
diff --git a/src/bdd/cudd/cuddCof.c b/src/bdd/cudd/cuddCof.c
deleted file mode 100644
index f79e3f91..00000000
--- a/src/bdd/cudd/cuddCof.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddCof.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the cofactor of f with respect to g.]
-
- Description [Computes the cofactor of f with respect to g; g must be
- the BDD or the ADD of a cube. Returns a pointer to the cofactor if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]
-
-******************************************************************************/
-DdNode *
-Cudd_Cofactor(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res,*zero;
-
- 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);
- }
- do {
- dd->reordered = 0;
- res = cuddCofactorRecur(dd,f,g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_Cofactor */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the children of g.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddGetBranches(
- DdNode * g,
- DdNode ** g1,
- DdNode ** g0)
-{
- DdNode *G = Cudd_Regular(g);
-
- *g1 = cuddT(G);
- *g0 = cuddE(G);
- if (Cudd_IsComplement(g)) {
- *g1 = Cudd_Not(*g1);
- *g0 = Cudd_Not(*g0);
- }
-
-} /* end of cuddGetBranches */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether g is the BDD of a cube.]
-
- Description [Checks whether g is the BDD of a cube. Returns 1 in case
- of success; 0 otherwise. The constant 1 is a valid cube, but all other
- constant functions cause cuddCheckCube to return 0.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddCheckCube(
- DdManager * dd,
- DdNode * g)
-{
- DdNode *g1,*g0,*one,*zero;
-
- one = DD_ONE(dd);
- if (g == one) return(1);
- if (Cudd_IsConstant(g)) return(0);
-
- zero = Cudd_Not(one);
- cuddGetBranches(g,&g1,&g0);
-
- if (g0 == zero) {
- return(cuddCheckCube(dd, g1));
- }
- if (g1 == zero) {
- return(cuddCheckCube(dd, g0));
- }
- return(0);
-
-} /* end of cuddCheckCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_Cofactor.]
-
- Description [Performs the recursive step of Cudd_Cofactor. Returns a
- pointer to the cofactor if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Cofactor]
-
-******************************************************************************/
-DdNode *
-cuddCofactorRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
- unsigned int topf,topg;
- int comple;
-
- statLine(dd);
- F = Cudd_Regular(f);
- if (cuddIsConstant(F)) return(f);
-
- one = DD_ONE(dd);
-
- /* The invariant g != 0 is true on entry to this procedure and is
- ** recursively maintained by it. Therefore it suffices to test g
- ** against one to make sure it is not constant.
- */
- if (g == one) return(f);
- /* From now on, f and g are known not to be constants. */
-
- comple = f != F;
- r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
- if (r != NULL) {
- return(Cudd_NotCond(r,comple));
- }
-
- topf = dd->perm[F->index];
- G = Cudd_Regular(g);
- topg = dd->perm[G->index];
-
- /* We take the cofactors of F because we are going to rely on
- ** the fact that the cofactors of the complement are the complements
- ** of the cofactors to better utilize the cache. Variable comple
- ** remembers whether we have to complement the result or not.
- */
- if (topf <= topg) {
- f1 = cuddT(F); f0 = cuddE(F);
- } else {
- f1 = f0 = F;
- }
- if (topg <= topf) {
- g1 = cuddT(G); g0 = cuddE(G);
- if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
- } else {
- 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);
- } else /* if (topf < topg) */ {
- 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);
- }
-
- cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r);
-
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddCofactorRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddCompose.c b/src/bdd/cudd/cuddCompose.c
deleted file mode 100644
index 8c858051..00000000
--- a/src/bdd/cudd/cuddCompose.c
+++ /dev/null
@@ -1,1722 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddCompose.c]
-
- PackageName [cudd]
-
- 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>
- 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
- cache. There are different procedured for BDDs and ADDs. This is
- because bddPermuteRecur uses cuddBddIteRecur. If this were changed,
- the procedures could be merged.]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-#ifdef DD_DEBUG
-static int addPermuteRecurHits;
-static int bddPermuteRecurHits;
-static int bddVectorComposeHits;
-static int addVectorComposeHits;
-
-static int addGeneralVectorComposeHits;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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 * 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Substitutes g for x_v in the BDD for f.]
-
- Description [Substitutes g for x_v in the BDD for f. v is the index of the
- variable to be substituted. Cudd_bddCompose passes the corresponding
- projection function to the recursive procedure, so that the cache may
- be used. Returns the composed BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_bddCompose(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- int v)
-{
- DdNode *proj, *res;
-
- /* Sanity check. */
- if (v < 0 || v > dd->size) return(NULL);
-
- proj = dd->vars[v];
- do {
- dd->reordered = 0;
- res = cuddBddComposeRecur(dd,f,g,proj);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddCompose */
-
-
-/**Function********************************************************************
-
- Synopsis [Substitutes g for x_v in the ADD for f.]
-
- Description [Substitutes g for x_v in the ADD for f. v is the index of the
- variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes
- the corresponding projection function to the recursive procedure, so
- that the cache may be used. Returns the composed ADD if successful;
- NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_addCompose(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- int v)
-{
- DdNode *proj, *res;
-
- /* Sanity check. */
- if (v < 0 || v > dd->size) return(NULL);
-
- proj = dd->vars[v];
- do {
- dd->reordered = 0;
- res = cuddAddComposeRecur(dd,f,g,proj);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addCompose */
-
-
-/**Function********************************************************************
-
- Synopsis [Permutes the variables of an ADD.]
-
- Description [Given a permutation in array permut, creates a new ADD
- with permuted variables. There should be an entry in array permut
- for each variable in the manager. The i-th entry of permut holds the
- index of the variable that is to substitute the i-th
- variable. Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]
-
-******************************************************************************/
-DdNode *
-Cudd_addPermute(
- DdManager * manager,
- DdNode * node,
- int * permut)
-{
- 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);
- } while (manager->reordered == 1);
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addPermute */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two sets of variables of the same size (x and y) in
- the ADD f.]
-
- Description [Swaps two sets of variables of the same size (x and y) in
- the ADD f. The size is given by n. The two sets of variables are
- assumed to be disjoint. Returns a pointer to the resulting ADD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
-
-******************************************************************************/
-DdNode *
-Cudd_addSwapVariables(
- DdManager * dd,
- DdNode * f,
- DdNode ** x,
- DdNode ** y,
- int n)
-{
- DdNode *swapped;
- int i, j, k;
- int *permut;
-
- permut = ALLOC(int,dd->size);
- if (permut == 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;
- }
-
- swapped = Cudd_addPermute(dd,f,permut);
- FREE(permut);
-
- return(swapped);
-
-} /* end of Cudd_addSwapVariables */
-
-
-/**Function********************************************************************
-
- Synopsis [Permutes the variables of a BDD.]
-
- Description [Given a permutation in array permut, creates a new BDD
- with permuted variables. There should be an entry in array permut
- for each variable in the manager. The i-th entry of permut holds the
- index of the variable that is to substitute the i-th variable.
- Returns a pointer to the resulting BDD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
-
-******************************************************************************/
-DdNode *
-Cudd_bddPermute(
- DdManager * manager,
- DdNode * node,
- int * permut)
-{
- 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);
-
- } while (manager->reordered == 1);
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_bddPermute */
-
-
-/**Function********************************************************************
-
- Synopsis [Remaps the variables of a BDD using the default variable map.]
-
- Description [Remaps the variables of a BDD using the default
- variable map. A typical use of this function is to swap two sets of
- variables. The variable map must be registered with Cudd_SetVarMap.
- Returns a pointer to the resulting BDD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap]
-
-******************************************************************************/
-DdNode *
-Cudd_bddVarMap(
- DdManager * manager /* DD manager */,
- DdNode * f /* function in which to remap variables */)
-{
- DdNode *res;
-
- if (manager->map == NULL) return(NULL);
- do {
- manager->reordered = 0;
- res = cuddBddVarMapRecur(manager, f);
- } while (manager->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_bddVarMap */
-
-
-/**Function********************************************************************
-
- Synopsis [Registers a variable mapping with the manager.]
-
- Description [Registers with the manager a variable mapping described
- by two sets of variables. This variable mapping is then used by
- functions like Cudd_bddVarMap. This function is convenient for
- those applications that perform the same mapping several times.
- However, if several different permutations are used, it may be more
- efficient not to rely on the registered mapping, because changing
- mapping causes the cache to be cleared. (The initial setting,
- however, does not clear the cache.) The two sets of variables (x and
- y) must have the same size (x and y). The size is given by n. The
- two sets of variables are normally disjoint, but this restriction is
- not imposeded by the function. When new variables are created, the
- map is automatically extended (each new variable maps to
- itself). The typical use, however, is to wait until all variables
- are created, and then create the map. Returns 1 if the mapping is
- successfully registered with the manager; 0 otherwise.]
-
- SideEffects [Modifies the manager. May clear the cache.]
-
- SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables]
-
-******************************************************************************/
-int
-Cudd_SetVarMap (
- DdManager *manager /* DD manager */,
- DdNode **x /* first array of variables */,
- DdNode **y /* second array of variables */,
- int n /* length of both arrays */)
-{
- int i;
-
- if (manager->map != NULL) {
- cuddCacheFlush(manager);
- } else {
- manager->map = 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;
- }
- /* 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;
- }
- return(1);
-
-} /* end of Cudd_SetVarMap */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two sets of variables of the same size (x and y) in
- the BDD f.]
-
- Description [Swaps two sets of variables of the same size (x and y)
- in the BDD f. The size is given by n. The two sets of variables are
- assumed to be disjoint. Returns a pointer to the resulting BDD if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]
-
-******************************************************************************/
-DdNode *
-Cudd_bddSwapVariables(
- DdManager * dd,
- DdNode * f,
- DdNode ** x,
- DdNode ** y,
- int n)
-{
- DdNode *swapped;
- int i, j, k;
- int *permut;
-
- permut = ALLOC(int,dd->size);
- if (permut == 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;
- }
-
- swapped = Cudd_bddPermute(dd,f,permut);
- FREE(permut);
-
- return(swapped);
-
-} /* end of Cudd_bddSwapVariables */
-
-
-/**Function********************************************************************
-
- Synopsis [Rearranges a set of variables in the BDD B.]
-
- Description [Rearranges a set of variables in the BDD B. The size of
- the set is given by n. This procedure is intended for the
- `randomization' of the priority functions. Returns a pointer to the
- BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables
- Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect]
-
-******************************************************************************/
-DdNode *
-Cudd_bddAdjPermuteX(
- DdManager * dd,
- DdNode * B,
- DdNode ** x,
- int n)
-{
- DdNode *swapped;
- int i, j, k;
- int *permut;
-
- permut = ALLOC(int,dd->size);
- if (permut == 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;
- }
-
- swapped = Cudd_bddPermute(dd,B,permut);
- FREE(permut);
-
- return(swapped);
-
-} /* end of Cudd_bddAdjPermuteX */
-
-
-/**Function********************************************************************
-
- Synopsis [Composes an ADD with a vector of 0-1 ADDs.]
-
- Description [Given a vector of 0-1 ADDs, creates a new ADD by
- substituting the 0-1 ADDs for the variables of the ADD f. There
- should be an entry in vector for each variable in the manager.
- If no substitution is sought for a given variable, the corresponding
- projection function should be specified in the vector.
- This function implements simultaneous composition.
- Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose
- Cudd_bddVectorCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_addVectorCompose(
- DdManager * dd,
- DdNode * f,
- DdNode ** vector)
-{
- 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;
- }
- }
-
- /* Recursively solve the problem. */
- res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest);
- if (res != NULL) cuddRef(res);
-
- /* Dispose of local cache. */
- cuddHashTableQuit(table);
- } while (dd->reordered == 1);
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addVectorCompose */
-
-
-/**Function********************************************************************
-
- Synopsis [Composes an ADD with a vector of ADDs.]
-
- Description [Given a vector of ADDs, creates a new ADD by substituting the
- ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted
- for the x_v and vectorOff the ADDs to be substituted for x_v'. There should
- be an entry in vector for each variable in the manager. If no substitution
- is sought for a given variable, the corresponding projection function should
- be specified in the vector. This function implements simultaneous
- composition. Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute
- Cudd_addCompose Cudd_bddVectorCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_addGeneralVectorCompose(
- DdManager * dd,
- DdNode * f,
- DdNode ** vectorOn,
- DdNode ** vectorOff)
-{
- 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;
- }
- }
-
- /* Recursively solve the problem. */
- res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn,
- vectorOff,deepest);
- if (res != NULL) cuddRef(res);
-
- /* Dispose of local cache. */
- cuddHashTableQuit(table);
- } while (dd->reordered == 1);
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addGeneralVectorCompose */
-
-
-/**Function********************************************************************
-
- Synopsis [Composes an ADD with a vector of 0-1 ADDs.]
-
- Description [Given a vector of 0-1 ADDs, creates a new ADD by
- substituting the 0-1 ADDs for the variables of the ADD f. There
- should be an entry in vector for each variable in the manager.
- This function implements non-simultaneous composition. If any of the
- functions being composed depends on any of the variables being
- substituted, then the result depends on the order of composition,
- which in turn depends on the variable order: The variables farther from
- the roots in the order are substituted first.
- Returns a pointer to the resulting ADD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_addNonSimCompose(
- DdManager * dd,
- DdNode * f,
- DdNode ** vector)
-{
- 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
- ** variables being substituted.
- ** The replacement relation is the product of the terms (yi EXNOR gi).
- ** This apporach allows us to use the global cache for this function,
- ** with great savings in memory with respect to using arrays for the
- ** cache entries.
- ** First we build replacement relation and cube of substituted
- ** variables from the vector specifying the desired composition.
- */
- key = DD_ONE(dd);
- cuddRef(key);
- 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);
- 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);
- 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);
- 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;
- }
- }
-
- /* 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);
-
- Cudd_RecursiveDeref(dd,key);
- Cudd_RecursiveDeref(dd,cube);
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_addNonSimCompose */
-
-
-/**Function********************************************************************
-
- Synopsis [Composes a BDD with a vector of BDDs.]
-
- Description [Given a vector of BDDs, creates a new BDD by
- substituting the BDDs for the variables of the BDD f. There
- should be an entry in vector for each variable in the manager.
- If no substitution is sought for a given variable, the corresponding
- projection function should be specified in the vector.
- This function implements simultaneous composition.
- Returns a pointer to the resulting BDD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose]
-
-******************************************************************************/
-DdNode *
-Cudd_bddVectorCompose(
- DdManager * dd,
- DdNode * f,
- DdNode ** vector)
-{
- 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;
- }
- }
-
- /* Recursively solve the problem. */
- res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest);
- if (res != NULL) cuddRef(res);
-
- /* Dispose of local cache. */
- cuddHashTableQuit(table);
- } while (dd->reordered == 1);
-
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_bddVectorCompose */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddCompose.]
-
- Description [Performs the recursive step of Cudd_bddCompose.
- Exploits the fact that the composition of f' with g
- produces the complement of the composition of f with g to better
- utilize the cache. Returns the composed BDD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddCompose]
-
-******************************************************************************/
-DdNode *
-cuddBddComposeRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * proj)
-{
- DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
- unsigned int v, topf, topg, topindex;
- int comple;
-
- statLine(dd);
- v = dd->perm[proj->index];
- F = Cudd_Regular(f);
- topf = cuddI(dd,F->index);
-
- /* Terminal case. Subsumes the test for constant f. */
- if (topf > v) return(f);
-
- /* We solve the problem for a regular pointer, and then complement
- ** the result if the pointer was originally complemented.
- */
- comple = Cudd_IsComplement(f);
-
- /* Check cache. */
- r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
- if (r != NULL) {
- 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;
- f1 = cuddT(F);
- f0 = cuddE(F);
- }
- 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);
- 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);
- }
-
- cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r);
-
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddComposeRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addCompose.]
-
- Description [Performs the recursive step of Cudd_addCompose.
- Returns the composed BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addCompose]
-
-******************************************************************************/
-DdNode *
-cuddAddComposeRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * proj)
-{
- DdNode *f1, *f0, *g1, *g0, *r, *t, *e;
- unsigned int v, topf, topg, topindex;
-
- statLine(dd);
- v = dd->perm[proj->index];
- topf = cuddI(dd,f->index);
-
- /* Terminal case. Subsumes the test for constant f. */
- if (topf > v) return(f);
-
- /* Check cache. */
- r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
- if (r != NULL) {
- 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;
- 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;
- } 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);
-
- return(r);
-
-} /* end of cuddAddComposeRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_addPermute.]
-
- Description [ Recursively puts the ADD in the order given in the
- array permut. Checks for trivial cases to terminate recursion, then
- splits on the children of this node. Once the solutions for the
- children are obtained, it puts into the current position the node
- from the rest of the ADD that should be here. Then returns this ADD.
- The key here is that the node being visited is NOT put in its proper
- place by this instance, but rather is switched when its proper
- position is reached in the recursion tree.<p>
- The DdNode * that is returned is the same ADD as passed in as node,
- but in the new order.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addPermute cuddBddPermuteRecur]
-
-******************************************************************************/
-static DdNode *
-cuddAddPermuteRecur(
- DdManager * manager /* DD manager */,
- DdHashTable * table /* computed table */,
- DdNode * node /* ADD to be reordered */,
- int * permut /* permutation array */)
-{
- DdNode *T,*E;
- DdNode *res,*var;
- int index;
-
- statLine(manager);
- /* Check for terminal case of constant node. */
- if (cuddIsConstant(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++;
-#endif
- return(res);
- }
-
- /* Split and recur on children of this node. */
- T = cuddAddPermuteRecur(manager,table,cuddT(node),permut);
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddAddPermuteRecur(manager,table,cuddE(node),permut);
- if (E == NULL) {
- Cudd_RecursiveDeref(manager, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Move variable that should be in this position to this position
- ** by creating a single var ADD for that variable, and calling
- ** cuddAddIteRecur with the T and E we just created.
- */
- index = permut[node->index];
- var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager));
- if (var == NULL) return(NULL);
- 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);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(manager,var);
- Cudd_RecursiveDeref(manager, T);
- Cudd_RecursiveDeref(manager, E);
-
- /* Do not keep the result if the reference count is only 1, since
- ** 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);
- }
- }
- cuddDeref(res);
- return(res);
-
-} /* end of cuddAddPermuteRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddPermute.]
-
- Description [ Recursively puts the BDD in the order given in the array permut.
- Checks for trivial cases to terminate recursion, then splits on the
- children of this node. Once the solutions for the children are
- obtained, it puts into the current position the node from the rest of
- the BDD that should be here. Then returns this BDD.
- The key here is that the node being visited is NOT put in its proper
- place by this instance, but rather is switched when its proper position
- is reached in the recursion tree.<p>
- The DdNode * that is returned is the same BDD as passed in as node,
- but in the new order.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPermute cuddAddPermuteRecur]
-
-******************************************************************************/
-static DdNode *
-cuddBddPermuteRecur(
- DdManager * manager /* DD manager */,
- DdHashTable * table /* computed table */,
- DdNode * node /* BDD to be reordered */,
- int * permut /* permutation array */)
-{
- 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);
- }
-
- /* If problem already solved, look up answer and return. */
- if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) {
-#ifdef DD_DEBUG
- bddPermuteRecurHits++;
-#endif
- return(Cudd_NotCond(res,N != node));
- }
-
- /* Split and recur on children of this node. */
- T = cuddBddPermuteRecur(manager,table,cuddT(N),permut);
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddBddPermuteRecur(manager,table,cuddE(N),permut);
- if (E == NULL) {
- Cudd_IterDerefBdd(manager, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Move variable that should be in this position to this position
- ** by retrieving the single var BDD for that variable, and calling
- ** cuddBddIteRecur with the T and E we just created.
- */
- 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);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(manager, T);
- Cudd_IterDerefBdd(manager, E);
-
- /* Do not keep the result if the reference count is only 1, since
- ** 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);
- }
- }
- cuddDeref(res);
- return(Cudd_NotCond(res,N != node));
-
-} /* end of cuddBddPermuteRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_bddVarMap.]
-
- Description [Implements the recursive step of Cudd_bddVarMap.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddVarMap]
-
-******************************************************************************/
-static DdNode *
-cuddBddVarMapRecur(
- DdManager *manager /* DD manager */,
- DdNode *f /* BDD to be remapped */)
-{
- 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);
- }
-
- /* 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));
- }
-
- /* Split and recur on children of this node. */
- T = cuddBddVarMapRecur(manager,cuddT(F));
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddBddVarMapRecur(manager,cuddE(F));
- if (E == NULL) {
- Cudd_IterDerefBdd(manager, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Move variable that should be in this position to this position
- ** by retrieving the single var BDD for that variable, and calling
- ** cuddBddIteRecur with the T and E we just created.
- */
- 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);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(manager, T);
- Cudd_IterDerefBdd(manager, E);
-
- /* Do not keep the result if the reference count is only 1, since
- ** it will not be visited again.
- */
- if (F->ref != 1) {
- cuddCacheInsert1(manager,Cudd_bddVarMap,F,res);
- }
- cuddDeref(res);
- return(Cudd_NotCond(res,F != f));
-
-} /* end of cuddBddVarMapRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addVectorCompose.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-cuddAddVectorComposeRecur(
- DdManager * dd /* DD manager */,
- DdHashTable * table /* computed table */,
- DdNode * f /* ADD in which to compose */,
- DdNode ** vector /* functions to substitute */,
- int deepest /* depth of deepest substitution */)
-{
- DdNode *T,*E;
- DdNode *res;
-
- statLine(dd);
- /* If we are past the deepest substitution, return f. */
- if (cuddI(dd,f->index) > deepest) {
- return(f);
- }
-
- if ((res = cuddHashTableLookup1(table,f)) != NULL) {
-#ifdef DD_DEBUG
- addVectorComposeHits++;
-#endif
- return(res);
- }
-
- /* Split and recur on children of this node. */
- T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest);
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest);
- if (E == NULL) {
- Cudd_RecursiveDeref(dd, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Retrieve the 0-1 ADD for the current top variable and call
- ** cuddAddIteRecur with the T and E we just created.
- */
- res = cuddAddIteRecur(dd,vector[f->index],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);
-
- /* 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_RecursiveDeref(dd, res);
- return(NULL);
- }
- }
- cuddDeref(res);
- return(res);
-
-} /* end of cuddAddVectorComposeRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-cuddAddGeneralVectorComposeRecur(
- DdManager * dd /* DD manager */,
- DdHashTable * table /* computed table */,
- DdNode * f /* ADD in which to compose */,
- DdNode ** vectorOn /* functions to substitute for x_i */,
- DdNode ** vectorOff /* functions to substitute for x_i' */,
- int deepest /* depth of deepest substitution */)
-{
- DdNode *T,*E,*t,*e;
- DdNode *res;
-
- /* If we are past the deepest substitution, return f. */
- if (cuddI(dd,f->index) > deepest) {
- return(f);
- }
-
- if ((res = cuddHashTableLookup1(table,f)) != NULL) {
-#ifdef DD_DEBUG
- addGeneralVectorComposeHits++;
-#endif
- return(res);
- }
-
- /* Split and recur on children of this node. */
- T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f),
- vectorOn,vectorOff,deepest);
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f),
- vectorOn,vectorOff,deepest);
- if (E == NULL) {
- Cudd_RecursiveDeref(dd, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Retrieve the compose ADDs for the current top variable and call
- ** cuddAddApplyRecur with the T and E we just created.
- */
- t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T);
- if (t == NULL) {
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- return(NULL);
- }
- cuddRef(t);
- e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E);
- if (e == NULL) {
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- Cudd_RecursiveDeref(dd,t);
- return(NULL);
- }
- cuddRef(e);
- res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
- if (res == NULL) {
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- Cudd_RecursiveDeref(dd,t);
- Cudd_RecursiveDeref(dd,e);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- Cudd_RecursiveDeref(dd,t);
- Cudd_RecursiveDeref(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_RecursiveDeref(dd, res);
- return(NULL);
- }
- }
- cuddDeref(res);
- return(res);
-
-} /* end of cuddAddGeneralVectorComposeRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addNonSimCompose.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-cuddAddNonSimComposeRecur(
- DdManager * dd,
- DdNode * f,
- DdNode ** vector,
- DdNode * key,
- DdNode * cube,
- int lastsub)
-{
- DdNode *f1, *f0, *key1, *key0, *cube1, *var;
- DdNode *T,*E;
- DdNode *r;
- unsigned int top, topf, topk, topc;
- unsigned int index;
- int i;
- DdNode **vect1;
- DdNode **vect0;
-
- statLine(dd);
- /* If we are past the deepest substitution, return f. */
- if (cube == DD_ONE(dd) || cuddIsConstant(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);
- }
-
- /* Find top variable. we just need to look at f, key, and cube,
- ** because all the varibles in the gi are in key.
- */
- topf = cuddI(dd,f->index);
- topk = cuddI(dd,key->index);
- top = ddMin(topf,topk);
- topc = cuddI(dd,cube->index);
- top = ddMin(top,topc);
- index = dd->invperm[top];
-
- /* Compute the cofactors. */
- if (topf == top) {
- f1 = cuddT(f);
- f0 = cuddE(f);
- } else {
- 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) {
- Cudd_RecursiveDeref(dd,var);
- return(NULL);
- }
- cuddRef(key1);
- Cudd_RecursiveDeref(dd,var);
- key0 = key1;
- } else {
- 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 = ALLOC(DdNode *,lastsub);
- if (vect1 == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- Cudd_RecursiveDeref(dd,key1);
- return(NULL);
- }
- vect0 = ALLOC(DdNode *,lastsub);
- if (vect0 == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- Cudd_RecursiveDeref(dd,key1);
- 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;
- }
- }
- vect1[index] = vect0[index] = NULL;
-
- /* Recur on children. */
- T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub);
- FREE(vect1);
- if (T == NULL) {
- Cudd_RecursiveDeref(dd,key1);
- FREE(vect0);
- return(NULL);
- }
- cuddRef(T);
- E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
- FREE(vect0);
- if (E == NULL) {
- Cudd_RecursiveDeref(dd,key1);
- Cudd_RecursiveDeref(dd,T);
- return(NULL);
- }
- cuddRef(E);
- Cudd_RecursiveDeref(dd,key1);
-
- /* Retrieve the 0-1 ADD for the current top variable from vector,
- ** and call cuddAddIteRecur with the T and E we just created.
- */
- r = cuddAddIteRecur(dd,vector[index],T,E);
- if (r == NULL) {
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- cuddDeref(r);
-
- /* Store answer to trim recursion. */
- cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r);
-
- return(r);
-
-} /* end of cuddAddNonSimComposeRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddVectorCompose.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-cuddBddVectorComposeRecur(
- DdManager * dd /* DD manager */,
- DdHashTable * table /* computed table */,
- DdNode * f /* BDD in which to compose */,
- DdNode ** vector /* functions to be composed */,
- int deepest /* depth of the deepest substitution */)
-{
- 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);
- }
-
- /* If problem already solved, look up answer and return. */
- if ((res = cuddHashTableLookup1(table,F)) != NULL) {
-#ifdef DD_DEBUG
- bddVectorComposeHits++;
-#endif
- return(Cudd_NotCond(res,F != f));
- }
-
- /* Split and recur on children of this node. */
- T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest);
- if (T == NULL) return(NULL);
- cuddRef(T);
- E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest);
- if (E == NULL) {
- Cudd_IterDerefBdd(dd, T);
- return(NULL);
- }
- cuddRef(E);
-
- /* Call cuddBddIteRecur with the BDD that replaces the current top
- ** variable and the T and E we just created.
- */
- res = cuddBddIteRecur(dd,vector[F->index],T,E);
- if (res == NULL) {
- Cudd_IterDerefBdd(dd, T);
- Cudd_IterDerefBdd(dd, E);
- return(NULL);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(dd, T);
- 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);
- }
- }
- cuddDeref(res);
- return(Cudd_NotCond(res,F != f));
-
-} /* end of cuddBddVectorComposeRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison of a function to the i-th ADD variable.]
-
- Description [Comparison of a function to the i-th ADD variable. Returns 1 if
- the function is the i-th ADD variable; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DD_INLINE
-static int
-ddIsIthAddVar(
- DdManager * dd,
- DdNode * f,
- unsigned int i)
-{
- return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd));
-
-} /* end of ddIsIthAddVar */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison of a pair of functions to the i-th ADD variable.]
-
- Description [Comparison of a pair of functions to the i-th ADD
- variable. Returns 1 if the functions are the i-th ADD variable and its
- complement; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DD_INLINE
-static int
-ddIsIthAddVarPair(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- 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));
-
-} /* end of ddIsIthAddVarPair */
diff --git a/src/bdd/cudd/cuddDecomp.c b/src/bdd/cudd/cuddDecomp.c
deleted file mode 100644
index 4fde7392..00000000
--- a/src/bdd/cudd/cuddDecomp.c
+++ /dev/null
@@ -1,2150 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddDecomp.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-#define DEPTH 5
-#define THRESHOLD 10
-#define NONE 0
-#define PAIR_ST 1
-#define PAIR_CR 2
-#define G_ST 3
-#define G_CR 4
-#define H_ST 5
-#define H_CR 6
-#define BOTH_G 7
-#define BOTH_H 8
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-typedef struct Conjuncts {
- DdNode *g;
- DdNode *h;
-} Conjuncts;
-
-typedef struct NodeStat {
- int distance;
- int localRef;
-} NodeStat;
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
-#endif
-
-static DdNode *one, *zero;
-long lastTimeG;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-#define FactorsNotStored(factors) ((int)((long)(factors) & 01))
-
-#define FactorsComplement(factors) ((Conjuncts *)((long)(factors) | 01))
-
-#define FactorsUncomplement(factors) ((Conjuncts *)((long)(factors) ^ 01))
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way conjunctive decomposition of a BDD.]
-
- Description [Performs two-way conjunctive decomposition of a
- BDD. This procedure owes its name to the use of supersetting to
- obtain an initial factor of the given function. Returns the number
- of conjuncts produced, that is, 2 if successful; 1 if no meaningful
- decomposition was found; 0 otherwise. The conjuncts produced by this
- procedure tend to be imbalanced.]
-
- SideEffects [The factors are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the conjuncts are already
- referenced. If the function returns 0, the array for the conjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp
- Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox
- Cudd_bddSqueeze Cudd_bddLICompaction]
-
-******************************************************************************/
-int
-Cudd_bddApproxConjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** conjuncts /* address of the first factor */)
-{
- DdNode *superset1, *superset2, *glocal, *hlocal;
- int nvars = Cudd_SupportSize(dd,f);
-
- /* Find a tentative first factor by overapproximation and minimization. */
- superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0);
- if (superset1 == NULL) return(0);
- cuddRef(superset1);
- superset2 = Cudd_bddSqueeze(dd,f,superset1);
- if (superset2 == NULL) {
- Cudd_RecursiveDeref(dd,superset1);
- return(0);
- }
- cuddRef(superset2);
- Cudd_RecursiveDeref(dd,superset1);
-
- /* Compute the second factor by minimization. */
- hlocal = Cudd_bddLICompaction(dd,f,superset2);
- if (hlocal == NULL) {
- Cudd_RecursiveDeref(dd,superset2);
- return(0);
- }
- cuddRef(hlocal);
-
- /* Refine the first factor by minimization. If h turns out to be f, this
- ** 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);
- }
- cuddRef(glocal);
- Cudd_RecursiveDeref(dd,superset2);
-
- if (glocal != DD_ONE(dd)) {
- if (hlocal != DD_ONE(dd)) {
- *conjuncts = 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 = ALLOC(DdNode *,1);
- if (*conjuncts == NULL) {
- Cudd_RecursiveDeref(dd,glocal);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- (*conjuncts)[0] = glocal;
- return(1);
- }
- } else {
- Cudd_RecursiveDeref(dd,glocal);
- *conjuncts = 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 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way disjunctive decomposition of a BDD.]
-
- Description [Performs two-way disjunctive decomposition of a BDD.
- Returns the number of disjuncts produced, that is, 2 if successful;
- 1 if no meaningful decomposition was found; 0 otherwise. The
- disjuncts produced by this procedure tend to be imbalanced.]
-
- SideEffects [The two disjuncts are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the disjuncts are already
- referenced. If the function returns 0, the array for the disjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp
- Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]
-
-******************************************************************************/
-int
-Cudd_bddApproxDisjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** disjuncts /* address of the array of the disjuncts */)
-{
- int result, i;
-
- result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts);
- for (i = 0; i < result; i++) {
- (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
- }
- return(result);
-
-} /* end of Cudd_bddApproxDisjDecomp */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way conjunctive decomposition of a BDD.]
-
- Description [Performs two-way conjunctive decomposition of a
- BDD. This procedure owes its name to the iterated use of
- supersetting to obtain a factor of the given function. Returns the
- number of conjuncts produced, that is, 2 if successful; 1 if no
- meaningful decomposition was found; 0 otherwise. The conjuncts
- produced by this procedure tend to be imbalanced.]
-
- SideEffects [The factors are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the conjuncts are already
- referenced. If the function returns 0, the array for the conjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp
- Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox
- Cudd_bddSqueeze Cudd_bddLICompaction]
-
-******************************************************************************/
-int
-Cudd_bddIterConjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** conjuncts /* address of the array of conjuncts */)
-{
- DdNode *superset1, *superset2, *old[2], *res[2];
- int sizeOld, sizeNew;
- int nvars = Cudd_SupportSize(dd,f);
-
- old[0] = DD_ONE(dd);
- cuddRef(old[0]);
- old[1] = f;
- cuddRef(old[1]);
- 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]);
- Cudd_RecursiveDeref(dd,superset1);
- return(0);
- }
- cuddRef(superset2);
- Cudd_RecursiveDeref(dd,superset1);
- 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);
- 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]);
-
- 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);
-
- /* Refine the first factor by minimization. If h turns out to
- ** 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);
- }
- cuddRef(superset1);
- Cudd_RecursiveDeref(dd,old[0]);
- old[0] = superset1;
-
- if (old[0] != DD_ONE(dd)) {
- if (old[1] != DD_ONE(dd)) {
- *conjuncts = 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 = ALLOC(DdNode *,1);
- if (*conjuncts == NULL) {
- Cudd_RecursiveDeref(dd,old[0]);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- (*conjuncts)[0] = old[0];
- return(1);
- }
- } else {
- Cudd_RecursiveDeref(dd,old[0]);
- *conjuncts = 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 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way disjunctive decomposition of a BDD.]
-
- Description [Performs two-way disjunctive decomposition of a BDD.
- Returns the number of disjuncts produced, that is, 2 if successful;
- 1 if no meaningful decomposition was found; 0 otherwise. The
- disjuncts produced by this procedure tend to be imbalanced.]
-
- SideEffects [The two disjuncts are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the disjuncts are already
- referenced. If the function returns 0, the array for the disjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp
- Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]
-
-******************************************************************************/
-int
-Cudd_bddIterDisjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** disjuncts /* address of the array of the disjuncts */)
-{
- int result, i;
-
- result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts);
- for (i = 0; i < result; i++) {
- (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
- }
- return(result);
-
-} /* end of Cudd_bddIterDisjDecomp */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way conjunctive decomposition of a BDD.]
-
- Description [Performs two-way conjunctive decomposition of a
- BDD. This procedure owes its name to the fact tht it generalizes the
- decomposition based on the cofactors with respect to one
- variable. Returns the number of conjuncts produced, that is, 2 if
- successful; 1 if no meaningful decomposition was found; 0
- otherwise. The conjuncts produced by this procedure tend to be
- balanced.]
-
- SideEffects [The two factors are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the conjuncts are already
- referenced. If the function returns 0, the array for the conjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp
- Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp]
-
-******************************************************************************/
-int
-Cudd_bddGenConjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** conjuncts /* address of the array of conjuncts */)
-{
- int result;
- DdNode *glocal, *hlocal;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- do {
- dd->reordered = 0;
- result = cuddConjunctsAux(dd, f, &glocal, &hlocal);
- } while (dd->reordered == 1);
-
- if (result == 0) {
- return(0);
- }
-
- if (glocal != one) {
- if (hlocal != one) {
- *conjuncts = 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 = ALLOC(DdNode *,1);
- if (*conjuncts == NULL) {
- Cudd_RecursiveDeref(dd,glocal);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- (*conjuncts)[0] = glocal;
- return(1);
- }
- } else {
- Cudd_RecursiveDeref(dd,glocal);
- *conjuncts = 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 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way disjunctive decomposition of a BDD.]
-
- Description [Performs two-way disjunctive decomposition of a BDD.
- Returns the number of disjuncts produced, that is, 2 if successful;
- 1 if no meaningful decomposition was found; 0 otherwise. The
- disjuncts produced by this procedure tend to be balanced.]
-
- SideEffects [The two disjuncts are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the disjuncts are already
- referenced. If the function returns 0, the array for the disjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp
- Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp]
-
-******************************************************************************/
-int
-Cudd_bddGenDisjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** disjuncts /* address of the array of the disjuncts */)
-{
- int result, i;
-
- result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts);
- for (i = 0; i < result; i++) {
- (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
- }
- return(result);
-
-} /* end of Cudd_bddGenDisjDecomp */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way conjunctive decomposition of a BDD.]
-
- Description [Conjunctively decomposes one BDD according to a
- variable. If <code>f</code> is the function of the BDD and
- <code>x</code> is the variable, the decomposition is
- <code>(f+x)(f+x')</code>. The variable is chosen so as to balance
- the sizes of the two conjuncts and to keep them small. Returns the
- number of conjuncts produced, that is, 2 if successful; 1 if no
- meaningful decomposition was found; 0 otherwise.]
-
- SideEffects [The two factors are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the conjuncts are already
- referenced. If the function returns 0, the array for the conjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp
- Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp]
-
-*****************************************************************************/
-int
-Cudd_bddVarConjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** conjuncts /* address of the array of conjuncts */)
-{
- int best;
- int min;
- DdNode *support, *scan, *var, *glocal, *hlocal;
-
- /* Find best cofactoring variable. */
- support = Cudd_Support(dd,f);
- if (support == NULL) return(0);
- if (Cudd_IsConstant(support)) {
- *conjuncts = 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);
- }
-#ifdef DD_DEBUG
- assert(best >= 0 && best < dd->size);
-#endif
- Cudd_RecursiveDeref(dd,support);
-
- var = Cudd_bddIthVar(dd,best);
- glocal = Cudd_bddOr(dd,f,var);
- if (glocal == NULL) {
- return(0);
- }
- cuddRef(glocal);
- hlocal = Cudd_bddOr(dd,f,Cudd_Not(var));
- if (hlocal == NULL) {
- Cudd_RecursiveDeref(dd,glocal);
- return(0);
- }
- cuddRef(hlocal);
-
- if (glocal != DD_ONE(dd)) {
- if (hlocal != DD_ONE(dd)) {
- *conjuncts = 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 = ALLOC(DdNode *,1);
- if (*conjuncts == NULL) {
- Cudd_RecursiveDeref(dd,glocal);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- (*conjuncts)[0] = glocal;
- return(1);
- }
- } else {
- Cudd_RecursiveDeref(dd,glocal);
- *conjuncts = 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 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs two-way disjunctive decomposition of a BDD.]
-
- Description [Performs two-way disjunctive decomposition of a BDD
- according to a variable. If <code>f</code> is the function of the
- BDD and <code>x</code> is the variable, the decomposition is
- <code>f*x + f*x'</code>. The variable is chosen so as to balance
- the sizes of the two disjuncts and to keep them small. Returns the
- number of disjuncts produced, that is, 2 if successful; 1 if no
- meaningful decomposition was found; 0 otherwise.]
-
- SideEffects [The two disjuncts are returned in an array as side effects.
- The array is allocated by this function. It is the caller's responsibility
- to free it. On successful completion, the disjuncts are already
- referenced. If the function returns 0, the array for the disjuncts is
- not allocated. If the function returns 1, the only factor equals the
- function to be decomposed.]
-
- SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp
- Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp]
-
-******************************************************************************/
-int
-Cudd_bddVarDisjDecomp(
- DdManager * dd /* manager */,
- DdNode * f /* function to be decomposed */,
- DdNode *** disjuncts /* address of the array of the disjuncts */)
-{
- int result, i;
-
- result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts);
- for (i = 0; i < result; i++) {
- (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
- }
- return(result);
-
-} /* end of Cudd_bddVarDisjDecomp */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Get longest distance of node from constant.]
-
- Description [Get longest distance of node from constant. Returns the
- distance of the root from the constant if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static NodeStat *
-CreateBotDist(
- DdNode * node,
- st_table * distanceTable)
-{
- DdNode *N, *Nv, *Nnv;
- int distance, distanceNv, distanceNnv;
- NodeStat *nodeStat, *nodeStatNv, *nodeStatNnv;
-
-#if 0
- if (Cudd_IsConstant(node)) {
- 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);
- }
-
- Nv = cuddT(N);
- Nnv = cuddE(N);
- Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
- Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
-
- /* Recur on the children. */
- nodeStatNv = CreateBotDist(Nv, distanceTable);
- if (nodeStatNv == NULL) return(NULL);
- distanceNv = nodeStatNv->distance;
-
- nodeStatNnv = CreateBotDist(Nnv, distanceTable);
- if (nodeStatNnv == NULL) return(NULL);
- distanceNnv = nodeStatNnv->distance;
- /* Store max distance from constant; note sometimes this distance
- ** may be to 0.
- */
- distance = (distanceNv > distanceNnv) ? (distanceNv+1) : (distanceNnv + 1);
-
- nodeStat = ALLOC(NodeStat, 1);
- if (nodeStat == NULL) {
- return(0);
- }
- nodeStat->distance = distance;
- nodeStat->localRef = 1;
-
- if (st_insert(distanceTable, (char *)N, (char *)nodeStat) ==
- ST_OUT_OF_MEM) {
- return(0);
-
- }
- return(nodeStat);
-
-} /* end of CreateBotDist */
-
-
-/**Function********************************************************************
-
- Synopsis [Count the number of minterms of each node ina a BDD and
- store it in a hash table.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double
-CountMinterms(
- DdNode * node,
- double max,
- st_table * mintermTable,
- FILE *fp)
-{
- DdNode *N, *Nv, *Nnv;
- double min, minNv, minNnv;
- double *dummy;
-
- N = Cudd_Regular(node);
-
- if (cuddIsConstant(N)) {
- 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);
- }
-
- Nv = cuddT(N);
- Nnv = cuddE(N);
- Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
- Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
-
- /* Recur on the children. */
- minNv = CountMinterms(Nv, max, mintermTable, fp);
- if (minNv == -1.0) return(-1.0);
- minNnv = CountMinterms(Nnv, max, mintermTable, fp);
- if (minNnv == -1.0) return(-1.0);
- min = minNv / 2.0 + minNnv / 2.0;
- /* store
- */
-
- dummy = ALLOC(double, 1);
- 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");
- }
- return(min);
-
-} /* end of CountMinterms */
-
-
-/**Function********************************************************************
-
- Synopsis [Free factors structure]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ConjunctsFree(
- DdManager * dd,
- Conjuncts * factors)
-{
- Cudd_RecursiveDeref(dd, factors->g);
- Cudd_RecursiveDeref(dd, factors->h);
- FREE(factors);
- return;
-
-} /* end of ConjunctsFree */
-
-
-/**Function********************************************************************
-
- Synopsis [Check whether the given pair is in the tables.]
-
- Description [.Check whether the given pair is in the tables. gTable
- and hTable are combined.
- absence in both is indicated by 0,
- presence in gTable is indicated by 1,
- presence in hTable by 2 and
- presence in both by 3.
- The values returned by this function are PAIR_ST,
- PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE.
- PAIR_ST implies g in gTable and h in hTable
- PAIR_CR implies g in hTable and h in gTable
- G_ST implies g in gTable and h not in any table
- G_CR implies g in hTable and h not in any table
- H_ST implies h in hTable and g not in any table
- H_CR implies h in gTable and g not in any table
- BOTH_G implies both in gTable
- BOTH_H implies both in hTable
- NONE implies none in table; ]
-
- SideEffects []
-
- SeeAlso [CheckTablesCacheAndReturn CheckInTables]
-
-******************************************************************************/
-static int
-PairInTables(
- DdNode * g,
- DdNode * h,
- st_table * ghTable)
-{
- int valueG, valueH, gPresent, hPresent;
-
- valueG = valueH = gPresent = hPresent = 0;
-
- gPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(g), &valueG);
- hPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(h), &valueH);
-
- if (!gPresent && !hPresent) return(NONE);
-
- if (!hPresent) {
- 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);
- }
- /* 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);
- } else {
- return(BOTH_H);
- }
-
-} /* end of PairInTables */
-
-
-/**Function********************************************************************
-
- Synopsis [Check the tables for the existence of pair and return one
- combination, cache the result.]
-
- Description [Check the tables for the existence of pair and return
- one combination, cache the result. The assumption is that one of the
- conjuncts is already in the tables.]
-
- SideEffects [g and h referenced for the cache]
-
- SeeAlso [ZeroCase]
-
-******************************************************************************/
-static Conjuncts *
-CheckTablesCacheAndReturn(
- DdNode * node,
- DdNode * g,
- DdNode * h,
- st_table * ghTable,
- st_table * cacheTable)
-{
- int pairValue;
- int value;
- Conjuncts *factors;
-
- value = 0;
- /* check tables */
- pairValue = PairInTables(g, h, ghTable);
- assert(pairValue != NONE);
- /* if both dont exist in table, we know one exists(either g or h).
- * Therefore store the other and proceed
- */
- factors = 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);
- }
- }
- 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);
- }
- }
- 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);
- }
- }
- 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);
- }
- }
- factors->g = h;
- factors->h = g;
- } else if (pairValue == PAIR_CR) {
- /* pair exists in table */
- factors->g = h;
- factors->h = g;
- } else if (pairValue == PAIR_ST) {
- factors->g = g;
- factors->h = h;
- }
-
- /* cache the result for this node */
- if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) {
- FREE(factors);
- return(NULL);
- }
-
- return(factors);
-
-} /* end of CheckTablesCacheAndReturn */
-
-/**Function********************************************************************
-
- Synopsis [Check the tables for the existence of pair and return one
- combination, store in cache.]
-
- Description [Check the tables for the existence of pair and return
- one combination, store in cache. The pair that has more pointers to
- it is picked. An approximation of the number of local pointers is
- made by taking the reference count of the pairs sent. ]
-
- SideEffects []
-
- SeeAlso [ZeroCase BuildConjuncts]
-
-******************************************************************************/
-static Conjuncts *
-PickOnePair(
- DdNode * node,
- DdNode * g1,
- DdNode * h1,
- DdNode * g2,
- DdNode * h2,
- st_table * ghTable,
- st_table * cacheTable)
-{
- int value;
- Conjuncts *factors;
- int oneRef, twoRef;
-
- factors = ALLOC(Conjuncts, 1);
- if (factors == NULL) return(NULL);
-
- /* count the number of pointers to pair 2 */
- if (h2 == one) {
- twoRef = (Cudd_Regular(g2))->ref;
- } else if (g2 == one) {
- twoRef = (Cudd_Regular(h2))->ref;
- } else {
- 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;
- } else if (g1 == one) {
- oneRef = (Cudd_Regular(h1))->ref;
- } else {
- 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;
- } else {
- factors->g = g2;
- factors->h = h2;
- }
-
- /*
- * Store computed factors in respective tables to encourage
- * 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) {
- FREE(factors);
- return(NULL);
- }
- }
- } else {
- value = 1;
- if (st_insert(ghTable, (char *)Cudd_Regular(factors->g),
- (char *)(long)value) == ST_OUT_OF_MEM) {
- 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) {
- FREE(factors);
- return(NULL);
- }
- }
- } else {
- value = 2;
- if (st_insert(ghTable, (char *)Cudd_Regular(factors->h),
- (char *)(long)value) == ST_OUT_OF_MEM) {
- FREE(factors);
- return(NULL);
- }
- }
- }
-
- /* Store factors in cache table for later use. */
- if (st_insert(cacheTable, (char *)node, (char *)factors) ==
- ST_OUT_OF_MEM) {
- FREE(factors);
- return(NULL);
- }
-
- return(factors);
-
-} /* end of PickOnePair */
-
-
-/**Function********************************************************************
-
- Synopsis [Check if the two pairs exist in the table, If any of the
- conjuncts do exist, store in the cache and return the corresponding pair.]
-
- Description [Check if the two pairs exist in the table. If any of
- the conjuncts do exist, store in the cache and return the
- corresponding pair.]
-
- SideEffects []
-
- SeeAlso [ZeroCase BuildConjuncts]
-
-******************************************************************************/
-static Conjuncts *
-CheckInTables(
- DdNode * node,
- DdNode * g1,
- DdNode * h1,
- DdNode * g2,
- DdNode * h2,
- st_table * ghTable,
- st_table * cacheTable,
- int * outOfMem)
-{
- int pairValue1, pairValue2;
- Conjuncts *factors;
- int value;
-
- *outOfMem = 0;
-
- /* check existence of pair in table */
- pairValue1 = PairInTables(g1, h1, ghTable);
- pairValue2 = PairInTables(g2, h2, ghTable);
-
- /* if none of the 4 exist in the gh tables, return NULL */
- if ((pairValue1 == NONE) && (pairValue2 == NONE)) {
- return NULL;
- }
-
- factors = ALLOC(Conjuncts, 1);
- if (factors == NULL) {
- *outOfMem = 1;
- return NULL;
- }
-
- /* pairs that already exist in the table get preference. */
- if (pairValue1 == PAIR_ST) {
- factors->g = g1;
- factors->h = h1;
- } else if (pairValue2 == PAIR_ST) {
- factors->g = g2;
- factors->h = h2;
- } else if (pairValue1 == PAIR_CR) {
- factors->g = h1;
- factors->h = g1;
- } else if (pairValue2 == PAIR_CR) {
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- FREE(factors);
- return(NULL);
- }
- return factors;
-} /* end of CheckInTables */
-
-
-
-/**Function********************************************************************
-
- Synopsis [If one child is zero, do explicitly what Restrict does or better]
-
- Description [If one child is zero, do explicitly what Restrict does or better.
- First separate a variable and its child in the base case. In case of a cube
- times a function, separate the cube and function. As a last resort, look in
- tables.]
-
- SideEffects [Frees the BDDs in factorsNv. factorsNv itself is not freed
- because it is freed above.]
-
- SeeAlso [BuildConjuncts]
-
-******************************************************************************/
-static Conjuncts *
-ZeroCase(
- DdManager * dd,
- DdNode * node,
- Conjuncts * factorsNv,
- st_table * ghTable,
- st_table * cacheTable,
- int switched)
-{
- int topid;
- DdNode *g, *h, *g1, *g2, *h1, *h2, *x, *N, *G, *H, *Gv, *Gnv;
- DdNode *Hv, *Hnv;
- int value;
- int outOfMem;
- Conjuncts *factors;
-
- /* get var at this node */
- N = Cudd_Regular(node);
- topid = N->index;
- x = dd->vars[topid];
- x = (switched) ? Cudd_Not(x): x;
- cuddRef(x);
-
- /* Seprate variable and child */
- if (factorsNv->g == one) {
- Cudd_RecursiveDeref(dd, factorsNv->g);
- factors = 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);
- 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 = 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);
- 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);
- Gv = cuddT(G);
- Gnv = cuddE(G);
- Gv = Cudd_NotCond(Gv, Cudd_IsComplement(node));
- 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 = Cudd_Regular(factorsNv->h);
- Hv = cuddT(H);
- Hnv = cuddE(H);
- Hv = Cudd_NotCond(Hv, Cudd_IsComplement(node));
- 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);
- }
-
- /* build g1 = x*g; h1 = h */
- /* build g2 = g; h2 = x*h */
- Cudd_RecursiveDeref(dd, x);
- h1 = factorsNv->h;
- 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;
- }
-
- 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;
- }
-
- /* 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 {
- 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)) {
- Cudd_RecursiveDeref(dd, g2);
- Cudd_RecursiveDeref(dd, h2);
- } else {
- Cudd_RecursiveDeref(dd, g1);
- Cudd_RecursiveDeref(dd, h1);
- }
- }
-
- return(factors);
-} /* end of ZeroCase */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the conjuncts recursively, bottom up.]
-
- Description [Builds the conjuncts recursively, bottom up. Constants
- are returned as (f, f). The cache is checked for previously computed
- result. The decomposition points are determined by the local
- reference count of this node and the longest distance from the
- constant. At the decomposition point, the factors returned are (f,
- 1). Recur on the two children. The order is determined by the
- heavier branch. Combine the factors of the two children and pick the
- one that already occurs in the gh table. Occurence in g is indicated
- by value 1, occurence in h by 2, occurence in both 3.]
-
- SideEffects []
-
- SeeAlso [cuddConjunctsAux]
-
-******************************************************************************/
-static Conjuncts *
-BuildConjuncts(
- DdManager * dd,
- DdNode * node,
- st_table * distanceTable,
- st_table * cacheTable,
- int approxDistance,
- int maxLocalRef,
- st_table * ghTable,
- st_table * mintermTable)
-{
- int topid, distance;
- Conjuncts *factorsNv, *factorsNnv, *factors;
- Conjuncts *dummy;
- DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv;
- double minNv = 0.0, minNnv = 0.0;
- double *doubleDummy;
- int switched =0;
- int outOfMem;
- int freeNv = 0, freeNnv = 0, freeTemp;
- NodeStat *nodeStat;
- int value;
-
- /* if f is constant, return (f,f) */
- if (Cudd_IsConstant(node)) {
- factors = 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);
- }
-
- /* 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);
- }
- 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 = 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;
- 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;
- FREE(factors);
- return NULL;
- }
- }
- return(FactorsComplement(factors));
- }
-
- /* get the children and recur */
- Nv = cuddT(N);
- Nnv = cuddE(N);
- Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
- Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
-
- /* Choose which subproblem to solve first based on the number of
- * 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 (!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 (minNv < minNnv) {
- 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) 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) 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) 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;
- }
-
- /* Build the factors for this node. */
- topid = N->index;
- topv = dd->vars[topid];
-
- 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) FREE(factorsNv);
- if (freeNnv) 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) FREE(factorsNv);
- if (freeNnv) 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) FREE(factorsNv);
- if (freeNnv) FREE(factorsNnv);
- return(NULL);
- }
- cuddRef(g2);
- Cudd_RecursiveDeref(dd, factorsNv->g);
- Cudd_RecursiveDeref(dd, factorsNnv->h);
-
- 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) FREE(factorsNv);
- if (freeNnv) FREE(factorsNnv);
- return(NULL);
- }
- cuddRef(h2);
- Cudd_RecursiveDeref(dd, factorsNv->h);
- Cudd_RecursiveDeref(dd, factorsNnv->g);
- if (freeNv) FREE(factorsNv);
- if (freeNnv) FREE(factorsNnv);
-
- /* 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 {
- 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)) {
- Cudd_RecursiveDeref(dd, g2);
- Cudd_RecursiveDeref(dd, h2);
- } else {
- Cudd_RecursiveDeref(dd, g1);
- Cudd_RecursiveDeref(dd, h1);
- }
- }
-
- return(factors);
-
-} /* end of BuildConjuncts */
-
-
-/**Function********************************************************************
-
- Synopsis [Procedure to compute two conjunctive factors of f and place in *c1 and *c2.]
-
- Description [Procedure to compute two conjunctive factors of f and
- place in *c1 and *c2. Sets up the required data - table of distances
- from the constant and local reference count. Also minterm table. ]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddConjunctsAux(
- DdManager * dd,
- DdNode * f,
- DdNode ** c1,
- DdNode ** c2)
-{
- st_table *distanceTable = NULL;
- st_table *cacheTable = NULL;
- st_table *mintermTable = NULL;
- st_table *ghTable = NULL;
- st_generator *stGen;
- char *key, *value;
- Conjuncts *factors;
- int distance, approxDistance;
- double max, minterms;
- int freeFactors;
- NodeStat *nodeStat;
- int maxLocalRef;
-
- /* initialize */
- *c1 = NULL;
- *c2 = NULL;
-
- /* initialize distances table */
- distanceTable = st_init_table(st_ptrcmp,st_ptrhash);
- if (distanceTable == NULL) goto outOfMem;
-
- /* make the entry for the constant */
- nodeStat = ALLOC(NodeStat, 1);
- if (nodeStat == NULL) goto outOfMem;
- nodeStat->distance = 0;
- nodeStat->localRef = 1;
- if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) {
- goto outOfMem;
- }
-
- /* Count node distances from constant. */
- nodeStat = CreateBotDist(f, distanceTable);
- if (nodeStat == NULL) goto outOfMem;
-
- /* set the distance for the decomposition points */
- approxDistance = (DEPTH < nodeStat->distance) ? nodeStat->distance : DEPTH;
- 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, (char **)&key, (char **)&value)) {
- FREE(value);
- }
- st_free_gen(stGen); stGen = NULL;
- st_free_table(distanceTable);
- return(1);
- }
-
- /* record the maximum local reference count */
- maxLocalRef = 0;
- stGen = st_init_gen(distanceTable);
- if (stGen == NULL) goto outOfMem;
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- 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);
- if (mintermTable == NULL) goto outOfMem;
- minterms = CountMinterms(f, max, mintermTable, dd->err);
- if (minterms == -1.0) goto outOfMem;
-
- lastTimeG = Cudd_Random() & 1;
- cacheTable = st_init_table(st_ptrcmp, st_ptrhash);
- if (cacheTable == NULL) goto outOfMem;
- ghTable = st_init_table(st_ptrcmp, st_ptrhash);
- if (ghTable == NULL) goto outOfMem;
-
- /* Build conjuncts. */
- factors = BuildConjuncts(dd, f, distanceTable, cacheTable,
- approxDistance, maxLocalRef, ghTable, mintermTable);
- if (factors == NULL) goto outOfMem;
-
- /* free up tables */
- stGen = st_init_gen(distanceTable);
- if (stGen == NULL) goto outOfMem;
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- FREE(value);
- }
- st_free_gen(stGen); stGen = NULL;
- st_free_table(distanceTable); distanceTable = NULL;
- st_free_table(ghTable); ghTable = NULL;
-
- stGen = st_init_gen(mintermTable);
- if (stGen == NULL) goto outOfMem;
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- FREE(value);
- }
- st_free_gen(stGen); stGen = NULL;
- st_free_table(mintermTable); mintermTable = NULL;
-
- freeFactors = FactorsNotStored(factors);
- factors = (freeFactors) ? FactorsUncomplement(factors) : factors;
- if (factors != NULL) {
- *c1 = factors->g;
- *c2 = factors->h;
- cuddRef(*c1);
- cuddRef(*c2);
- if (freeFactors) 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));
- }
-#endif
- }
-
- stGen = st_init_gen(cacheTable);
- if (stGen == NULL) goto outOfMem;
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- ConjunctsFree(dd, (Conjuncts *)value);
- }
- st_free_gen(stGen); stGen = NULL;
-
- st_free_table(cacheTable); cacheTable = NULL;
-
- return(1);
-
-outOfMem:
- if (distanceTable != NULL) {
- stGen = st_init_gen(distanceTable);
- if (stGen == NULL) goto outOfMem;
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- 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, (char **)&key, (char **)&value)) {
- 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, (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 */
diff --git a/src/bdd/cudd/cuddEssent.c b/src/bdd/cudd/cuddEssent.c
deleted file mode 100644
index db4b8b49..00000000
--- a/src/bdd/cudd/cuddEssent.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddEssent.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* 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 $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * ddFindEssentialRecur ARGS((DdManager *dd, DdNode *f));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the essential variables of a DD.]
-
- Description [Returns the cube of the essential variables. A positive
- literal means that the variable must be set to 1 for the function to be
- 1. A negative literal means that the variable must be set to 0 for the
- function to be 1. Returns a pointer to the cube BDD if successful;
- NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIsVarEssential]
-
-******************************************************************************/
-DdNode *
-Cudd_FindEssential(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = ddFindEssentialRecur(dd,f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_FindEssential */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines whether a given variable is essential with a
- given phase in a BDD.]
-
- Description [Determines whether a given variable is essential with a
- given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1
- and f-->x_id, or if phase == 0 and f-->x_id'.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_FindEssential]
-
-******************************************************************************/
-int
-Cudd_bddIsVarEssential(
- DdManager * manager,
- DdNode * f,
- int id,
- int phase)
-{
- DdNode *var;
- int res;
- DdNode *one, *zero;
-
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- var = cuddUniqueInter(manager, id, one, zero);
-
- var = Cudd_NotCond(var,phase == 0);
-
- res = Cudd_bddIteConstant(manager, Cudd_Not(f), one, var) == one;
-
- return(res);
-
-} /* end of Cudd_bddIsVarEssential */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_FindEssential.]
-
- Description [Implements the recursive step of Cudd_FindEssential.
- Returns a pointer to the cube BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-ddFindEssentialRecur(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *T, *E, *F;
- DdNode *essT, *essE, *res;
- int index;
- DdNode *one, *lzero, *azero;
-
- one = DD_ONE(dd);
- F = Cudd_Regular(f);
- /* If f is constant the set of essential variables is empty. */
- if (cuddIsConstant(F)) return(one);
-
- res = cuddCacheLookup1(dd,Cudd_FindEssential,f);
- if (res != NULL) {
- return(res);
- }
-
- lzero = Cudd_Not(one);
- azero = DD_ZERO(dd);
- /* Find cofactors: here f is non-constant. */
- 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) {
- /* 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);
- }
- 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);
- }
- } 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;
- }
- }
-
- cuddCacheInsert1(dd,Cudd_FindEssential, f, res);
- return(res);
-
-} /* end of ddFindEssentialRecur */
-
diff --git a/src/bdd/cudd/cuddExact.c b/src/bdd/cudd/cuddExact.c
deleted file mode 100644
index 6852be68..00000000
--- a/src/bdd/cudd/cuddExact.c
+++ /dev/null
@@ -1,1004 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddExact.c]
-
- PackageName [cudd]
-
- 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>
- <li> getMaxBinomial()
- <li> gcd()
- <li> getMatrix()
- <li> freeMatrix()
- <li> getLevelKeys()
- <li> ddShuffle()
- <li> ddSiftUp()
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-#ifdef DD_STATS
-static int ddTotalShuffles;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Exact variable ordering algorithm.]
-
- Description [Exact variable ordering algorithm. Finds an optimum
- order for the variables between lower and upper. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddExact(
- DdManager * table,
- int lower,
- int upper)
-{
- int k, i, j;
- int maxBinomial, oldSubsets, newSubsets;
- int subsetCost;
- int size; /* number of variables to be reordered */
- int unused, nvars, level, result;
- int upperBound, lowerBound, cost;
- int roots;
- char *mask = NULL;
- DdHalfWord *symmInfo = NULL;
- DdHalfWord **newOrder = NULL;
- DdHalfWord **oldOrder = NULL;
- int *newCost = NULL;
- int *oldCost = NULL;
- DdHalfWord **tmpOrder;
- int *tmpCost;
- DdHalfWord *bestOrder = NULL;
- DdHalfWord *order;
-#ifdef DD_STATS
- int ddTotalSubsets;
-#endif
-
- /* 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++;
- while (table->subtables[upper].keys == 1 &&
- 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
- ** symmetry information. */
- result = cuddSymmSiftingConv(table,lower,upper);
- if (result == 0) goto cuddExactOutOfMem;
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
- ddTotalShuffles = 0;
- ddTotalSubsets = 0;
-#endif
-
- /* Initialization. */
- nvars = table->size;
- size = upper - lower + 1;
- /* Count unused variable among those to be reordered. This is only
- ** 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++;
- }
-
- /* Find the maximum number of subsets we may have to store. */
- maxBinomial = getMaxBinomial(size - unused);
- if (maxBinomial == -1) goto cuddExactOutOfMem;
-
- newOrder = getMatrix(maxBinomial, size);
- if (newOrder == NULL) goto cuddExactOutOfMem;
-
- newCost = ALLOC(int, maxBinomial);
- if (newCost == NULL) goto cuddExactOutOfMem;
-
- oldOrder = getMatrix(maxBinomial, size);
- if (oldOrder == NULL) goto cuddExactOutOfMem;
-
- oldCost = ALLOC(int, maxBinomial);
- if (oldCost == NULL) goto cuddExactOutOfMem;
-
- bestOrder = ALLOC(DdHalfWord, size);
- if (bestOrder == NULL) goto cuddExactOutOfMem;
-
- mask = ALLOC(char, nvars);
- if (mask == NULL) goto cuddExactOutOfMem;
-
- symmInfo = initSymmInfo(table, lower, upper);
- if (symmInfo == NULL) goto cuddExactOutOfMem;
-
- roots = ddCountRoots(table, lower, upper);
-
- /* Initialize the old order matrix for the empty subset and the best
- ** order to the current order. The cost for the empty subset includes
- ** the cost of the levels between upper and the constants. These levels
- ** are not going to change. Hence, we count them only once.
- */
- oldSubsets = 1;
- for (i = 0; i < size; i++) {
- 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);
- 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);
-#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;
-#ifdef DD_STATS
- ddTotalSubsets += newSubsets;
-#endif
- oldSubsets = newSubsets;
- }
- result = ddShuffle(table, bestOrder, lower, upper);
- if (result == 0) goto cuddExactOutOfMem;
-#ifdef DD_STATS
-#ifdef DD_VERBOSE
- (void) fprintf(table->out,"\n");
-#endif
- (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n",
- ddTotalSubsets);
- (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles",
- ddTotalShuffles);
-#endif
-
- freeMatrix(newOrder);
- freeMatrix(oldOrder);
- FREE(bestOrder);
- FREE(oldCost);
- FREE(newCost);
- FREE(symmInfo);
- FREE(mask);
- return(1);
-
-cuddExactOutOfMem:
-
- if (newOrder != NULL) freeMatrix(newOrder);
- if (oldOrder != NULL) freeMatrix(oldOrder);
- if (bestOrder != NULL) FREE(bestOrder);
- if (oldCost != NULL) FREE(oldCost);
- if (newCost != NULL) FREE(newCost);
- if (symmInfo != NULL) FREE(symmInfo);
- if (mask != NULL) FREE(mask);
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
-
-} /* end of cuddExact */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the maximum value of (n choose k) for a given n.]
-
- 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.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-getMaxBinomial(
- int n)
-{
- int *numerator;
- int i, j, k, y, g, result;
-
- k = (n & ~1) >> 1;
-
- numerator = 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;
- }
- }
- }
-
- result = 1;
- for (i = 0; i < k; i++)
- result *= numerator[i];
-
- FREE(numerator);
- return(result);
-
-} /* end of getMaxBinomial */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the gcd of two integers.]
-
- Description [Returns the gcd of two integers. Uses the binary GCD
- algorithm described in Cormen, Leiserson, and Rivest.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-gcd(
- int x,
- int y)
-{
- int a;
- int b;
- int lsbMask;
-
- /* GCD(n,0) = n. */
- if (x == 0) return(y);
- 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;
- } 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;
- }
- }
- }
-
- return(a);
-
-} /* end of gcd */
-
-
-/**Function********************************************************************
-
- Synopsis [Allocates a two-dimensional matrix of ints.]
-
- Description [Allocates a two-dimensional matrix of ints.
- Returns the pointer to the matrix if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [freeMatrix]
-
-******************************************************************************/
-static DdHalfWord **
-getMatrix(
- int rows /* number of rows */,
- int cols /* number of columns */)
-{
- DdHalfWord **matrix;
- int i;
-
- if (cols*rows == 0) return(NULL);
- matrix = ALLOC(DdHalfWord *, rows);
- if (matrix == NULL) return(NULL);
- matrix[0] = ALLOC(DdHalfWord, cols*rows);
- if (matrix[0] == NULL) return(NULL);
- for (i = 1; i < rows; i++) {
- matrix[i] = matrix[i-1] + cols;
- }
- return(matrix);
-
-} /* end of getMatrix */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees a two-dimensional matrix allocated by getMatrix.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [getMatrix]
-
-******************************************************************************/
-static void
-freeMatrix(
- DdHalfWord ** matrix)
-{
- FREE(matrix[0]);
- FREE(matrix);
- return;
-
-} /* end of freeMatrix */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of nodes at one level of a unique table.]
-
- Description [Returns the number of nodes at one level of a unique table.
- The projection function, if isolated, is not counted.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-getLevelKeys(
- DdManager * table,
- int l)
-{
- int isolated;
- int x; /* x is an index */
-
- x = table->invperm[l];
- isolated = table->vars[x]->ref == 1;
-
- return(table->subtables[l].keys - isolated);
-
-} /* end of getLevelKeys */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders variables according to a given permutation.]
-
- Description [Reorders variables according to a given permutation.
- The i-th permutation array contains the index of the variable that
- should be brought to the i-th level. ddShuffle assumes that no
- dead nodes are present and that the interaction matrix is properly
- initialized. The reordering is achieved by a series of upward sifts.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddShuffle(
- DdManager * table,
- DdHalfWord * permutation,
- int lower,
- int upper)
-{
- DdHalfWord index;
- int level;
- int position;
- int numvars;
- int result;
-#ifdef DD_STATS
- long localTime;
- int initialSize;
-#ifdef DD_VERBOSE
- int finalSize;
-#endif
- int previousSize;
-#endif
-
-#ifdef DD_STATS
- localTime = util_cpu_time();
- initialSize = table->keys - table->isolated;
-#endif
-
- 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,"\n");
-#endif
-
- for (level = 0; level <= upper - lower; level++) {
- index = permutation[level];
- position = table->perm[index];
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
- result = ddSiftUp(table,position,level+lower);
- if (!result) return(0);
- }
-
-#ifdef DD_STATS
- ddTotalShuffles++;
-#ifdef DD_VERBOSE
- finalSize = table->keys - table->isolated;
- if (finalSize < initialSize) {
- (void) fprintf(table->out,"-");
- } else if (finalSize > initialSize) {
- (void) fprintf(table->out,"+");
- } else {
- (void) fprintf(table->out,"=");
- }
- if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n");
- fflush(table->out);
-#endif
-#endif
-
- return(1);
-
-} /* end of ddShuffle */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves one variable up.]
-
- Description [Takes a variable from position x and sifts it up to
- position xLow; xLow should be less than or equal to x.
- Returns 1 if successful; 0 otherwise]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddSiftUp(
- DdManager * table,
- int x,
- int xLow)
-{
- int y;
- int size;
-
- y = cuddNextLow(table,x);
- while (y >= xLow) {
- size = cuddSwapInPlace(table,y,x);
- if (size == 0) {
- return(0);
- }
- x = y;
- y = cuddNextLow(table,x);
- }
- return(1);
-
-} /* end of ddSiftUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Updates the upper bound and saves the best order seen so far.]
-
- Description [Updates the upper bound and saves the best order seen so far.
- Returns the current value of the upper bound.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-updateUB(
- DdManager * table,
- int oldBound,
- DdHalfWord * bestOrder,
- int lower,
- int upper)
-{
- int i;
- int newBound = table->keys - table->isolated;
-
- if (newBound < oldBound) {
-#ifdef DD_STATS
- (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);
- } else {
- return(oldBound);
- }
-
-} /* end of updateUB */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of roots.]
-
- Description [Counts the number of roots at the levels between lower and
- upper. The computation is based on breadth-first search.
- A node is a root if it is not reachable from any previously visited node.
- (All the nodes at level lower are therefore considered roots.)
- The visited flag uses the LSB of the next pointer. Returns the root
- count. The roots that are constant nodes are always ignored.]
-
- SideEffects [None]
-
- SeeAlso [ddClearGlobal]
-
-******************************************************************************/
-static int
-ddCountRoots(
- DdManager * table,
- int lower,
- int upper)
-{
- int i,j;
- DdNode *f;
- DdNodePtr *nodelist;
- DdNode *sentinel = &(table->sentinel);
- int slots;
- int roots = 0;
- 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++;
- }
- }
- 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);
-
- return(roots);
-
-} /* end of ddCountRoots */
-
-
-/**Function********************************************************************
-
- Synopsis [Scans the DD and clears the LSB of the next pointers.]
-
- Description [Scans the DD and clears the LSB of the next pointers.
- The LSB of the next pointers are used as markers to tell whether a
- node was reached. Once the roots are counted, these flags are
- reset.]
-
- SideEffects [None]
-
- SeeAlso [ddCountRoots]
-
-******************************************************************************/
-static void
-ddClearGlobal(
- DdManager * table,
- int lower,
- int maxlevel)
-{
- int i,j;
- DdNode *f;
- DdNodePtr *nodelist;
- DdNode *sentinel = &(table->sentinel);
- 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;
- }
- }
- }
-
-} /* end of ddClearGlobal */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes a lower bound on the size of a BDD.]
-
- Description [Computes a lower bound on the size of a BDD from the
- following factors:
- <ul>
- <li> size of the lower part of it;
- <li> size of the part of the upper part not subjected to reordering;
- <li> number of roots in the part of the BDD subjected to reordering;
- <li> variable in the support of the roots in the upper part of the
- BDD subjected to reordering.
- <ul/>]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-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 */
- )
-{
- int i;
- int lb = cost;
- int lb1 = 0;
- int lb2;
- int support;
- DdHalfWord ref;
-
- /* The levels not involved in reordering are not going to change.
- ** Add their sizes to the lower bound.
- */
- for (i = 0; i < lower; 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;
- }
-
- /* 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;
- } else {
- lb2 = 0;
- }
-
- lb += lb1 > lb2 ? lb1 : lb2;
-
- return(lb);
-
-} /* end of computeLB */
-
-
-/**Function********************************************************************
-
- Synopsis [Updates entry for a subset.]
-
- Description [Updates entry for a subset. Finds the subset, if it exists.
- If the new order for the subset has lower cost, or if the subset did not
- exist, it stores the new order and cost. Returns the number of subsets
- currently in the table.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-updateEntry(
- DdManager * table,
- DdHalfWord * order,
- int level,
- int cost,
- DdHalfWord ** orders,
- int * costs,
- int subsets,
- char * mask,
- int lower,
- int upper)
-{
- int i, j;
- int size = upper - lower + 1;
-
- /* Build a mask that says what variables are in this subset. */
- for (i = lower; i <= upper; i++)
- mask[table->invperm[i]] = 0;
- for (i = level; i < size; i++)
- 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;
- }
- 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);
-
-} /* end of updateEntry */
-
-
-/**Function********************************************************************
-
- Synopsis [Pushes a variable in the order down to position "level."]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-pushDown(
- DdHalfWord * order,
- int j,
- int level)
-{
- int i;
- DdHalfWord tmp;
-
- tmp = order[j];
- for (i = j; i < level; i++) {
- order[i] = order[i+1];
- }
- order[level] = tmp;
- return;
-
-} /* end of pushDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Gathers symmetry information.]
-
- Description [Translates the symmetry information stored in the next
- field of each subtable from level to indices. This procedure is called
- immediately after symmetric sifting, so that the next fields are correct.
- By translating this informaton in terms of indices, we make it independent
- of subsequent reorderings. The format used is that of the next fields:
- a circular list where each variable points to the next variable in the
- same symmetry group. Only the entries between lower and upper are
- considered. The procedure returns a pointer to an array
- holding the symmetry information if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [checkSymmInfo]
-
-******************************************************************************/
-static DdHalfWord *
-initSymmInfo(
- DdManager * table,
- int lower,
- int upper)
-{
- int level, index, next, nextindex;
- DdHalfWord *symmInfo;
-
- symmInfo = ALLOC(DdHalfWord, table->size);
- 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;
- }
- return(symmInfo);
-
-} /* end of initSymmInfo */
-
-
-/**Function********************************************************************
-
- Synopsis [Check symmetry condition.]
-
- Description [Returns 1 if a variable is the one with the highest index
- among those belonging to a symmetry group that are in the top part of
- the BDD. The top part is given by level.]
-
- SideEffects [None]
-
- SeeAlso [initSymmInfo]
-
-******************************************************************************/
-static int
-checkSymmInfo(
- DdManager * table,
- DdHalfWord * symmInfo,
- int index,
- int level)
-{
- int i;
-
- i = symmInfo[index];
- while (i != index) {
- if (index < i && table->perm[i] <= level)
- return(0);
- i = symmInfo[i];
- }
- return(1);
-
-} /* end of checkSymmInfo */
-
diff --git a/src/bdd/cudd/cuddExport.c b/src/bdd/cudd/cuddExport.c
deleted file mode 100644
index d148be42..00000000
--- a/src/bdd/cudd/cuddExport.c
+++ /dev/null
@@ -1,1289 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddExport.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Writes a blif file representing the argument BDDs.]
-
- Description [Writes a blif file representing the argument BDDs as a
- network of multiplexers. One multiplexer is written for each BDD
- node. It returns 1 in case of success; 0 otherwise (e.g.,
- out-of-memory, file system full, or an ADD with constants different
- from 0 and 1). Cudd_DumpBlif does not close the file: This is the
- caller responsibility. Cudd_DumpBlif uses a minimal unique subset of
- the hexadecimal address of a node as name for it. If the argument
- inames is non-null, it is assumed to hold the pointers to the names
- of the inputs. Similarly for onames.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal
- Cudd_DumpDaVinci Cudd_DumpFactoredForm]
-
-******************************************************************************/
-int
-Cudd_DumpBlif(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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) */,
- char * mname /* model name (or NULL) */,
- FILE * fp /* pointer to the dump file */)
-{
- 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 = ALLOC(int,nvars);
- if (sorted == NULL) {
- 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. */
- support = Cudd_VectorSupport(dd,f,n);
- 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 */
-
- /* Write the header (.model .inputs .outputs). */
- if (mname == NULL) {
- retval = fprintf(fp,".model DD\n.inputs");
- } else {
- retval = fprintf(fp,".model %s\n.inputs",mname);
- }
- 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 (retval == EOF) goto failure;
- }
- }
- FREE(sorted);
- sorted = NULL;
-
- /* Write the .output line. */
- 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;
- }
- retval = fprintf(fp,"\n");
- if (retval == EOF) goto failure;
-
- retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp);
- if (retval == 0) goto failure;
-
- /* Write trailer and return. */
- retval = fprintf(fp,".end\n");
- if (retval == EOF) goto failure;
-
- return(1);
-
-failure:
- if (sorted != NULL) FREE(sorted);
- if (support != NULL) Cudd_RecursiveDeref(dd,support);
- return(0);
-
-} /* end of Cudd_DumpBlif */
-
-
-/**Function********************************************************************
-
- 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.,
- out-of-memory, file system full, or an ADD with constants different
- from 0 and 1). Cudd_DumpBlif does not close the file: This is the
- caller responsibility. Cudd_DumpBlif uses a minimal unique subset of
- the hexadecimal address of a node as name for it. If the argument
- inames is non-null, it is assumed to hold the pointers to the names
- of the inputs. Similarly for onames. This function prints out only
- .names part.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal
- Cudd_DumpDaVinci Cudd_DumpFactoredForm]
-
-******************************************************************************/
-int
-Cudd_DumpBlifBody(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- st_table *visited = NULL;
- int retval;
- int i;
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* To account for the possible complement on the root,
- ** we put either a buffer or an inverter at the output of
- ** the multiplexer representing the top node.
- */
- for (i = 0; i < n; i++) {
- 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);
-#else
- ".names %x f%d\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), i);
-#endif
- } else {
- retval = fprintf(fp,
-#if SIZEOF_VOID_P == 8
- ".names %lx %s\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), onames[i]);
-#else
- ".names %x %s\n", (unsigned) f[i] / (unsigned) 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;
- }
-
- st_free_table(visited);
- return(1);
-
-failure:
- if (visited != NULL) st_free_table(visited);
- return(0);
-
-} /* end of Cudd_DumpBlifBody */
-
-
-/**Function********************************************************************
-
- Synopsis [Writes a dot file representing the argument DDs.]
-
- Description [Writes a file representing the argument DDs in a format
- suitable for the graph drawing program dot.
- It returns 1 in case of success; 0 otherwise (e.g., out-of-memory,
- file system full).
- Cudd_DumpDot does not close the file: This is the caller
- responsibility. Cudd_DumpDot uses a minimal unique subset of the
- hexadecimal address of a node as name for it.
- If the argument inames is non-null, it is assumed to hold the pointers
- to the names of the inputs. Similarly for onames.
- Cudd_DumpDot uses the following convention to draw arcs:
- <ul>
- <li> solid line: THEN arcs;
- <li> dotted line: complement arcs;
- <li> dashed line: regular ELSE arcs.
- </ul>
- The dot options are chosen so that the drawing fits on a letter-size
- sheet.
- ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal
- Cudd_DumpDaVinci Cudd_DumpFactoredForm]
-
-******************************************************************************/
-int
-Cudd_DumpDot(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- 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;
-
- /* Build a bit array with the support of f. */
- sorted = ALLOC(int,nvars);
- if (sorted == NULL) {
- 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. */
- support = Cudd_VectorSupport(dd,f,n);
- 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 */
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* Find how many most significant hex digits are identical
- ** in the addresses of all the nodes. Build a mask based
- ** on this knowledge, so that digits that carry no information
- ** will not be printed. This is done in two steps.
- ** 1. We scan the symbol table to find the bits that differ
- ** in at least 2 addresses.
- ** 2. We choose one of the possible masks. There are 8 possible
- ** masks for 32-bit integer, and 16 possible masks for 64-bit
- ** integers.
- */
-
- /* Find the bits that are different. */
- refAddr = (long) Cudd_Regular(f[0]);
- diff = 0;
- gen = st_init_gen(visited);
- if (gen == NULL) goto failure;
- while (st_gen(gen, (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;
- }
-
- /* 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");
- if (retval == EOF) return(0);
-
- /* Write the input name subgraph by scanning the support array. */
- retval = fprintf(fp,"{ node [shape = plaintext];\n");
- if (retval == EOF) goto failure;
- retval = fprintf(fp," edge [style = invis];\n");
- if (retval == EOF) goto failure;
- /* We use a name ("CONST NODES") with an embedded blank, because
- ** it is unlikely to appear as an input name.
- */
- retval = fprintf(fp," \"CONST NODES\" [style = invis];\n");
- 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 (retval == EOF) goto failure;
- }
- }
- retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
- if (retval == EOF) goto failure;
-
- /* Write the output node subgraph. */
- 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;
- }
-
- /* 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]]);
- }
- 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 (retval == EOF) goto failure;
- }
- scan = scan->next;
- }
- }
- 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]; ");
- 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 = scan->next;
- }
- }
- retval = fprintf(fp,"}\n}\n");
- if (retval == EOF) goto failure;
-
- /* 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;
- }
-
- /* 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;
- }
- 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 = scan->next;
- }
- }
-
- /* Write trailer and return. */
- retval = fprintf(fp,"}\n");
- if (retval == EOF) goto failure;
-
- st_free_table(visited);
- FREE(sorted);
- return(1);
-
-failure:
- if (sorted != NULL) FREE(sorted);
- if (support != NULL) Cudd_RecursiveDeref(dd,support);
- if (visited != NULL) st_free_table(visited);
- return(0);
-
-} /* end of Cudd_DumpDot */
-
-
-/**Function********************************************************************
-
- Synopsis [Writes a daVinci file representing the argument BDDs.]
-
- Description [Writes a daVinci file representing the argument BDDs.
- It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or
- file system full). Cudd_DumpDaVinci does not close the file: This
- is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique
- subset of the hexadecimal address of a node as name for it. If the
- argument inames is non-null, it is assumed to hold the pointers to
- the names of the inputs. Similarly for onames.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal
- Cudd_DumpFactoredForm]
-
-******************************************************************************/
-int
-Cudd_DumpDaVinci(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- DdNode *support = NULL;
- DdNode *scan;
- st_table *visited = NULL;
- int retval;
- int i;
- st_generator *gen;
- long refAddr, diff, mask;
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* Find how many most significant hex digits are identical
- ** in the addresses of all the nodes. Build a mask based
- ** on this knowledge, so that digits that carry no information
- ** will not be printed. This is done in two steps.
- ** 1. We scan the symbol table to find the bits that differ
- ** in at least 2 addresses.
- ** 2. We choose one of the possible masks. There are 8 possible
- ** masks for 32-bit integer, and 16 possible masks for 64-bit
- ** integers.
- */
-
- /* Find the bits that are different. */
- refAddr = (long) Cudd_Regular(f[0]);
- diff = 0;
- gen = st_init_gen(visited);
- while (st_gen(gen, (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;
- }
- st_free_table(visited);
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- retval = fprintf(fp, "[");
- 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;
- }
-
- /* Write trailer and return. */
- retval = fprintf(fp, "]\n");
- if (retval == EOF) goto failure;
-
- st_free_table(visited);
- return(1);
-
-failure:
- if (support != NULL) Cudd_RecursiveDeref(dd,support);
- if (visited != NULL) st_free_table(visited);
- return(0);
-
-} /* end of Cudd_DumpDaVinci */
-
-
-/**Function********************************************************************
-
- Synopsis [Writes a DDcal file representing the argument BDDs.]
-
- Description [Writes a DDcal file representing the argument BDDs.
- It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or
- file system full). Cudd_DumpDDcal does not close the file: This
- is the caller responsibility. Cudd_DumpDDcal uses a minimal unique
- subset of the hexadecimal address of a node as name for it. If the
- argument inames is non-null, it is assumed to hold the pointers to
- the names of the inputs. Similarly for onames.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci
- Cudd_DumpFactoredForm]
-
-******************************************************************************/
-int
-Cudd_DumpDDcal(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- 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;
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* Find how many most significant hex digits are identical
- ** in the addresses of all the nodes. Build a mask based
- ** on this knowledge, so that digits that carry no information
- ** will not be printed. This is done in two steps.
- ** 1. We scan the symbol table to find the bits that differ
- ** in at least 2 addresses.
- ** 2. We choose one of the possible masks. There are 8 possible
- ** masks for 32-bit integer, and 16 possible masks for 64-bit
- ** integers.
- */
-
- /* Find the bits that are different. */
- refAddr = (long) Cudd_Regular(f[0]);
- diff = 0;
- gen = st_init_gen(visited);
- while (st_gen(gen, (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;
- }
- st_free_table(visited);
-
- /* Build a bit array with the support of f. */
- sorted = ALLOC(int,nvars);
- if (sorted == NULL) {
- 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. */
- support = Cudd_VectorSupport(dd,f,n);
- 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 */
- 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 (retval == EOF) goto failure;
- }
- retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * ");
- if (retval == EOF) goto failure;
- }
- FREE(sorted);
- sorted = NULL;
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* 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;
- }
- retval = fprintf(fp, "]\n");
- if (retval == EOF) goto failure;
-
- st_free_table(visited);
- return(1);
-
-failure:
- if (sorted != NULL) FREE(sorted);
- if (support != NULL) Cudd_RecursiveDeref(dd,support);
- if (visited != NULL) st_free_table(visited);
- return(0);
-
-} /* end of Cudd_DumpDDcal */
-
-
-/**Function********************************************************************
-
- Synopsis [Writes factored forms representing the argument BDDs.]
-
- Description [Writes factored forms representing the argument BDDs.
- The format of the factored form is the one used in the genlib files
- for technology mapping in sis. It returns 1 in case of success; 0
- otherwise (e.g., file system full). Cudd_DumpFactoredForm does not
- close the file: This is the caller responsibility. Caution must be
- exercised because a factored form may be exponentially larger than
- the argument BDD. If the argument inames is non-null, it is assumed
- to hold the pointers to the names of the inputs. Similarly for
- onames.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci
- Cudd_DumpDDcal]
-
-******************************************************************************/
-int
-Cudd_DumpFactoredForm(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- 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 (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);
- }
-
- return(1);
-
-} /* end of Cudd_DumpFactoredForm */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_DumpBlif.]
-
- Description [Performs the recursive step of Cudd_DumpBlif. Traverses
- the BDD f and writes a multiplexer-network description to the file
- pointed by fp in blif format. f is assumed to be a regular pointer
- and ddDoDumpBlif guarantees this assumption in the recursive calls.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddDoDumpBlif(
- DdManager * dd,
- DdNode * f,
- FILE * fp,
- st_table * visited,
- char ** names)
-{
- DdNode *T, *E;
- int retval;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- /* If already visited, nothing to do. */
- if (st_is_member(visited, (char *) f) == 1)
- return(1);
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Mark node as visited. */
- if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
- return(0);
-
- /* 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));
-#else
- retval = fprintf(fp, ".names %x\n1\n",(unsigned) f / (unsigned) sizeof(DdNode));
-#endif
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
- }
-
- /* Check whether this is an ADD. We deal with 0-1 ADDs, but not
- ** with the general case.
- */
- if (f == DD_ZERO(dd)) {
-#if SIZEOF_VOID_P == 8
- retval = fprintf(fp, ".names %lx\n",(unsigned long) f / (unsigned long) sizeof(DdNode));
-#else
- retval = fprintf(fp, ".names %x\n",(unsigned) f / (unsigned) sizeof(DdNode));
-#endif
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
- }
- if (cuddIsConstant(f))
- return(0);
-
- /* Recursive calls. */
- T = cuddT(f);
- retval = ddDoDumpBlif(dd,T,fp,visited,names);
- if (retval != 1) return(retval);
- E = Cudd_Regular(cuddE(f));
- retval = ddDoDumpBlif(dd,E,fp,visited,names);
- if (retval != 1) return(retval);
-
- /* Write multiplexer taking complement arc into account. */
- if (names != NULL) {
- retval = fprintf(fp,".names %s", names[f->index]);
- } else {
- retval = fprintf(fp,".names %d", f->index);
- }
- if (retval == EOF)
- 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));
- } 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));
- }
-#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));
- } 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));
- }
-#endif
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
-
-} /* end of ddDoDumpBlif */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_DumpDaVinci.]
-
- Description [Performs the recursive step of Cudd_DumpDaVinci. Traverses
- the BDD f and writes a term expression to the file
- pointed by fp in daVinci format. f is assumed to be a regular pointer
- and ddDoDumpDaVinci guarantees this assumption in the recursive calls.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddDoDumpDaVinci(
- DdManager * dd,
- DdNode * f,
- FILE * fp,
- st_table * visited,
- char ** names,
- long mask)
-{
- DdNode *T, *E;
- int retval;
- long id;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- id = ((long) f & mask) / sizeof(DdNode);
-
- /* If already visited, insert a reference. */
- if (st_is_member(visited, (char *) f) == 1) {
- retval = fprintf(fp,"r(\"%lx\")", id);
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
- }
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Mark node as visited. */
- if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
- return(0);
-
- /* 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));
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
- }
-
- /* Recursive calls. */
- if (names != NULL) {
- retval = fprintf(fp,
- "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%s\"),",
- id, names[f->index]);
- } else {
- retval = fprintf(fp,
- "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%d\"),",
- id, f->index);
- }
- retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],");
- if (retval == EOF) return(0);
- T = cuddT(f);
- 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");
- if (retval == EOF) return(0);
- E = Cudd_Regular(cuddE(f));
- retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask);
- if (retval != 1) return(retval);
-
- retval = fprintf(fp,")]))");
- if (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
-
-} /* end of ddDoDumpDaVinci */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_DumpDDcal.]
-
- Description [Performs the recursive step of Cudd_DumpDDcal. Traverses
- the BDD f and writes a line for each node to the file
- pointed by fp in DDcal format. f is assumed to be a regular pointer
- and ddDoDumpDDcal guarantees this assumption in the recursive calls.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddDoDumpDDcal(
- DdManager * dd,
- DdNode * f,
- FILE * fp,
- st_table * visited,
- char ** names,
- long mask)
-{
- DdNode *T, *E;
- int retval;
- long id, idT, idE;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- id = ((long) f & mask) / sizeof(DdNode);
-
- /* If already visited, do nothing. */
- if (st_is_member(visited, (char *) f) == 1) {
- return(1);
- }
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Mark node as visited. */
- if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
- return(0);
-
- /* 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 (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
- }
-
- /* Recursive calls. */
- T = cuddT(f);
- retval = ddDoDumpDDcal(dd,T,fp,visited,names,mask);
- if (retval != 1) return(retval);
- 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);
- 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)) ? "'" : "");
- } 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 (retval == EOF) {
- return(0);
- } else {
- return(1);
- }
-
-} /* end of ddDoDumpDDcal */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_DumpFactoredForm.]
-
- Description [Performs the recursive step of
- Cudd_DumpFactoredForm. Traverses the BDD f and writes a factored
- form for each node to the file pointed by fp in terms of the
- factored forms of the children. Constants are propagated, and
- absorption is applied. f is assumed to be a regular pointer and
- ddDoDumpFActoredForm guarantees this assumption in the recursive
- calls.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpFactoredForm]
-
-******************************************************************************/
-static int
-ddDoDumpFactoredForm(
- DdManager * dd,
- DdNode * f,
- FILE * fp,
- char ** names)
-{
- DdNode *T, *E;
- int retval;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
- assert(!Cudd_IsConstant(f));
-#endif
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Recursive calls. */
- T = cuddT(f);
- E = cuddE(f);
- if (T != DD_ZERO(dd)) {
- if (E != 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 (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]);
- } 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 */
-
diff --git a/src/bdd/cudd/cuddGenCof.c b/src/bdd/cudd/cuddGenCof.c
deleted file mode 100644
index 142ee27e..00000000
--- a/src/bdd/cudd/cuddGenCof.c
+++ /dev/null
@@ -1,1968 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddGenCof.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Codes for edge markings in Cudd_bddLICompaction. The codes are defined
-** so that they can be bitwise ORed to implement the code priority scheme.
-*/
-#define DD_LIC_DC 0
-#define DD_LIC_1 1
-#define DD_LIC_0 2
-#define DD_LIC_NL 3
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Key for the cache used in the edge marking phase. */
-typedef struct MarkCacheKey {
- DdNode *f;
- DdNode *c;
-} MarkCacheKey;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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((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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes f constrain c.]
-
- Description [Computes f constrain c (f @ c).
- Uses a canonical form: (f' @ c) = ( f @ c)'. (Note: this is not true
- for c.) List of special cases:
- <ul>
- <li> f @ 0 = 0
- <li> f @ 1 = f
- <li> 0 @ c = 0
- <li> 1 @ c = 1
- <li> f @ f = 1
- <li> f @ f'= 0
- </ul>
- Returns a pointer to the result if successful; NULL otherwise. Note that if
- F=(f1,...,fn) and reordering takes place while computing F @ c, then the
- image restriction property (Img(F,c) = Img(F @ c)) is lost.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRestrict Cudd_addConstrain]
-
-******************************************************************************/
-DdNode *
-Cudd_bddConstrain(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddConstrainRecur(dd,f,c);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddConstrain */
-
-
-/**Function********************************************************************
-
- Synopsis [BDD restrict according to Coudert and Madre's algorithm
- (ICCAD90).]
-
- Description [BDD restrict according to Coudert and Madre's algorithm
- (ICCAD90). Returns the restricted BDD if successful; otherwise NULL.
- If application of restrict results in a BDD larger than the input
- BDD, the input BDD is returned.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain Cudd_addRestrict]
-
-******************************************************************************/
-DdNode *
-Cudd_bddRestrict(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *suppF, *suppC, *commonSupport;
- DdNode *cplus, *res;
- int retval;
- int sizeF, sizeRes;
-
- /* Check terminal cases here to avoid computing supports in trivial cases.
- ** This also allows us notto check later for the case c == 0, in which
- ** there is no common support. */
- if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd)));
- if (Cudd_IsConstant(f)) return(f);
- if (f == c) return(DD_ONE(dd));
- if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
-
- /* Check if supports intersect. */
- retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC);
- if (retval == 0) {
- 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);
-
- /* 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);
- }
- cuddRef(cplus);
- Cudd_IterDerefBdd(dd,suppC);
-
- do {
- dd->reordered = 0;
- res = cuddBddRestrictRecur(dd, f, cplus);
- } while (dd->reordered == 1);
- if (res == NULL) {
- Cudd_IterDerefBdd(dd,cplus);
- return(NULL);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(dd,cplus);
- /* Make restric safe by returning the smaller of the input and the
- ** result. */
- sizeF = Cudd_DagSize(f);
- sizeRes = Cudd_DagSize(res);
- if (sizeF <= sizeRes) {
- Cudd_IterDerefBdd(dd, res);
- return(f);
- } else {
- cuddDeref(res);
- return(res);
- }
-
-} /* end of Cudd_bddRestrict */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes f constrain c for ADDs.]
-
- Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1
- ADD. List of special cases:
- <ul>
- <li> F @ 0 = 0
- <li> F @ 1 = F
- <li> 0 @ c = 0
- <li> 1 @ c = 1
- <li> F @ F = 1
- </ul>
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain]
-
-******************************************************************************/
-DdNode *
-Cudd_addConstrain(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddConstrainRecur(dd,f,c);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addConstrain */
-
-
-/**Function********************************************************************
-
- Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.]
-
- Description [BDD conjunctive decomposition as in McMillan's CAV96
- paper. The decomposition is canonical only for a given variable
- order. If canonicity is required, variable ordering must be disabled
- after the decomposition has been computed. Returns an array with one
- entry for each BDD variable in the manager if successful; otherwise
- NULL. The components of the solution have their reference counts
- already incremented (unlike the results of most other functions in
- the package.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract]
-
-******************************************************************************/
-DdNode **
-Cudd_bddConstrainDecomp(
- DdManager * dd,
- DdNode * f)
-{
- DdNode **decomp;
- int res;
- int i;
-
- /* Create an initialize decomposition array. */
- decomp = ALLOC(DdNode *,dd->size);
- if (decomp == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < dd->size; i++) {
- 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;
- }
- }
- res = cuddBddConstrainDecomp(dd,f,decomp);
- } while (dd->reordered == 1);
- if (res == 0) {
- 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]);
- }
- }
- return(decomp);
-
-} /* end of Cudd_bddConstrainDecomp */
-
-
-/**Function********************************************************************
-
- Synopsis [ADD restrict according to Coudert and Madre's algorithm
- (ICCAD90).]
-
- Description [ADD restrict according to Coudert and Madre's algorithm
- (ICCAD90). Returns the restricted ADD if successful; otherwise NULL.
- If application of restrict results in an ADD larger than the input
- ADD, the input ADD is returned.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addConstrain Cudd_bddRestrict]
-
-******************************************************************************/
-DdNode *
-Cudd_addRestrict(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *supp_f, *supp_c;
- DdNode *res, *commonSupport;
- int intersection;
- int sizeF, sizeRes;
-
- /* Check if supports intersect. */
- supp_f = Cudd_Support(dd, f);
- if (supp_f == NULL) {
- return(NULL);
- }
- cuddRef(supp_f);
- supp_c = Cudd_Support(dd, c);
- if (supp_c == 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);
- }
- cuddRef(commonSupport);
- Cudd_RecursiveDeref(dd,supp_f);
- Cudd_RecursiveDeref(dd,supp_c);
- intersection = commonSupport != DD_ONE(dd);
- 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);
- }
- } else {
- return(f);
- }
-
-} /* end of Cudd_addRestrict */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes a vector whose image equals a non-zero function.]
-
- Description [Computes a vector of BDDs whose image equals a non-zero
- function.
- The result depends on the variable order. The i-th component of the vector
- depends only on the first i variables in the order. Each BDD in the vector
- is not larger than the BDD of the given characteristic function. This
- function is based on the description of char-to-vect in "Verification of
- Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C.
- Berthet and J. C. Madre.
- Returns a pointer to an array containing the result if successful; NULL
- otherwise. The size of the array equals the number of variables in the
- manager. The components of the solution have their reference counts
- already incremented (unlike the results of most other functions in
- the package.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain]
-
-******************************************************************************/
-DdNode **
-Cudd_bddCharToVect(
- DdManager * dd,
- DdNode * f)
-{
- int i, j;
- DdNode **vect;
- DdNode *res = NULL;
-
- if (f == Cudd_Not(DD_ONE(dd))) return(NULL);
-
- vect = ALLOC(DdNode *, dd->size);
- if (vect == 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;
- }
- cuddRef(res);
- vect[dd->invperm[i]] = res;
- }
- } while (dd->reordered == 1);
- if (res == NULL) {
- FREE(vect);
- return(NULL);
- }
- return(vect);
-
-} /* end of Cudd_bddCharToVect */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs safe minimization of a BDD.]
-
- Description [Performs safe minimization of a BDD. Given the BDD
- <code>f</code> of a function to be minimized and a BDD
- <code>c</code> representing the care set, Cudd_bddLICompaction
- produces the BDD of a function that agrees with <code>f</code>
- wherever <code>c</code> is 1. Safe minimization means that the size
- of the result is guaranteed not to exceed the size of
- <code>f</code>. This function is based on the DAC97 paper by Hong et
- al.. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRestrict]
-
-******************************************************************************/
-DdNode *
-Cudd_bddLICompaction(
- DdManager * dd /* manager */,
- DdNode * f /* function to be minimized */,
- DdNode * c /* constraint (care set) */)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddLICompaction(dd,f,c);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddLICompaction */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a small BDD in a function interval.]
-
- Description [Finds a small BDD in a function interval. Given BDDs
- <code>l</code> and <code>u</code>, representing the lower bound and
- upper bound of a function interval, Cudd_bddSqueeze produces the BDD
- of a function within the interval with a small BDD. Returns a
- pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction]
-
-******************************************************************************/
-DdNode *
-Cudd_bddSqueeze(
- DdManager * dd /* manager */,
- DdNode * l /* lower bound */,
- DdNode * u /* upper bound */)
-{
- DdNode *res;
- int sizeRes, sizeL, sizeU;
-
- do {
- 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.
- ** We first compare to u, so that in case l == 0 and u == 1, we return
- ** 0 as in other minimization algorithms. */
- sizeRes = Cudd_DagSize(res);
- sizeU = Cudd_DagSize(u);
- if (sizeU <= sizeRes) {
- 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;
- }
- return(res);
-
-} /* end of Cudd_bddSqueeze */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a small BDD that agrees with <code>f</code> over
- <code>c</code>.]
-
- Description [Finds a small BDD that agrees with <code>f</code> over
- <code>c</code>. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze]
-
-******************************************************************************/
-DdNode *
-Cudd_bddMinimize(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *cplus, *res;
-
- if (c == Cudd_Not(DD_ONE(dd))) return(c);
- if (Cudd_IsConstant(f)) return(f);
- if (f == c) return(DD_ONE(dd));
- if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
-
- cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0);
- if (cplus == NULL) return(NULL);
- cuddRef(cplus);
- res = Cudd_bddLICompaction(dd,f,cplus);
- if (res == NULL) {
- Cudd_IterDerefBdd(dd,cplus);
- return(NULL);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(dd,cplus);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_bddMinimize */
-
-
-/**Function********************************************************************
-
- Synopsis [Find a dense subset of BDD <code>f</code>.]
-
- Description [Finds a dense subset of BDD <code>f</code>. Density is
- the ratio of number of minterms to number of nodes. Uses several
- techniques in series. It is more expensive than other subsetting
- procedures, but often produces better results. See
- Cudd_SubsetShortPaths for a description of the threshold and nvars
- parameters. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetRemap Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch
- Cudd_bddSqueeze]
-
-******************************************************************************/
-DdNode *
-Cudd_SubsetCompress(
- DdManager * dd /* manager */,
- DdNode * f /* BDD whose subset is sought */,
- int nvars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the subset */)
-{
- DdNode *res, *tmp1, *tmp2;
-
- tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0);
- if (tmp1 == NULL) return(NULL);
- cuddRef(tmp1);
- tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0);
- if (tmp2 == 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);
- }
- cuddRef(res);
- Cudd_IterDerefBdd(dd,tmp2);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_SubsetCompress */
-
-
-/**Function********************************************************************
-
- Synopsis [Find a dense superset of BDD <code>f</code>.]
-
- Description [Finds a dense superset of BDD <code>f</code>. Density is
- the ratio of number of minterms to number of nodes. Uses several
- techniques in series. It is more expensive than other supersetting
- procedures, but often produces better results. See
- Cudd_SupersetShortPaths for a description of the threshold and nvars
- parameters. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths
- Cudd_SupersetHeavyBranch Cudd_bddSqueeze]
-
-******************************************************************************/
-DdNode *
-Cudd_SupersetCompress(
- DdManager * dd /* manager */,
- DdNode * f /* BDD whose superset is sought */,
- int nvars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the superset */)
-{
- DdNode *subset;
-
- subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold);
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_SupersetCompress */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddConstrain.]
-
- Description [Performs the recursive step of Cudd_bddConstrain.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrain]
-
-******************************************************************************/
-DdNode *
-cuddBddConstrainRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
- DdNode *one, *zero;
- unsigned int topf, topc;
- 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);
-
- /* Make canonical to increase the utilization of the cache. */
- if (Cudd_IsComplement(f)) {
- 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.
- */
-
- /* Check the cache. */
- r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c);
- if (r != NULL) {
- 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);
- } else {
- 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);
- }
- } else {
- Cv = Cnv = c;
- }
-
- if (!Cudd_IsConstant(Cv)) {
- 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));
- }
- cuddRef(t);
-
- if (!Cudd_IsConstant(Cnv)) {
- 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));
- }
- 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);
- } 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);
-
- cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r);
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddConstrainRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddRestrict.]
-
- Description [Performs the recursive step of Cudd_bddRestrict.
- Returns the restricted BDD if successful; otherwise NULL.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddRestrict]
-
-******************************************************************************/
-DdNode *
-cuddBddRestrictRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
- unsigned int topf, topc;
- 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);
-
- /* Make canonical to increase the utilization of the cache. */
- if (Cudd_IsComplement(f)) {
- 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.
- */
-
- /* Check the cache. */
- r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c);
- if (r != NULL) {
- 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;
-
- /* 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);
- 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);
- }
- } else {
- Cv = Cnv = c;
- }
-
- if (!Cudd_IsConstant(Cv)) {
- 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));
- }
- cuddRef(t);
-
- if (!Cudd_IsConstant(Cnv)) {
- 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));
- }
- 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);
- } 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);
-
- cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r);
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddRestrictRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addConstrain.]
-
- Description [Performs the recursive step of Cudd_addConstrain.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addConstrain]
-
-******************************************************************************/
-DdNode *
-cuddAddConstrainRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
- DdNode *one, *zero;
- unsigned int topf, topc;
- 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);
-
- /* Now f and c are non-constant. */
-
- /* Check the cache. */
- r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c);
- if (r != NULL) {
- 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);
- } else {
- index = c->index;
- Fv = Fnv = f;
- }
- if (topc <= topf) {
- Cv = cuddT(c); Cnv = cuddE(c);
- } else {
- Cv = Cnv = c;
- }
-
- if (!Cudd_IsConstant(Cv)) {
- 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);
- }
- cuddRef(t);
-
- if (!Cudd_IsConstant(Cnv)) {
- 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);
- }
- cuddRef(e);
-
- r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
- if (r == NULL) {
- Cudd_RecursiveDeref(dd, e);
- Cudd_RecursiveDeref(dd, t);
- return(NULL);
- }
- cuddDeref(t);
- cuddDeref(e);
-
- cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r);
- return(r);
-
-} /* end of cuddAddConstrainRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addRestrict.]
-
- Description [Performs the recursive step of Cudd_addRestrict.
- Returns the restricted ADD if successful; otherwise NULL.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addRestrict]
-
-******************************************************************************/
-DdNode *
-cuddAddRestrictRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * c)
-{
- DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
- unsigned int topf, topc;
- 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);
-
- /* Now f and c are non-constant. */
-
- /* Check the cache. */
- r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c);
- if (r != NULL) {
- 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) {
- Cudd_RecursiveDeref(dd, d);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDeref(dd, d);
- 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);
- } else {
- Cv = Cnv = c;
- }
-
- if (!Cudd_IsConstant(Cv)) {
- 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);
- }
- cuddRef(t);
-
- if (!Cudd_IsConstant(Cnv)) {
- 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);
- }
- cuddRef(e);
-
- r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
- if (r == NULL) {
- Cudd_RecursiveDeref(dd, e);
- Cudd_RecursiveDeref(dd, t);
- return(NULL);
- }
- cuddDeref(t);
- cuddDeref(e);
-
- cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r);
- return(r);
-
-} /* end of cuddAddRestrictRecur */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Performs safe minimization of a BDD.]
-
- Description [Performs safe minimization of a BDD. Given the BDD
- <code>f</code> of a function to be minimized and a BDD
- <code>c</code> representing the care set, Cudd_bddLICompaction
- produces the BDD of a function that agrees with <code>f</code>
- wherever <code>c</code> is 1. Safe minimization means that the size
- of the result is guaranteed not to exceed the size of
- <code>f</code>. This function is based on the DAC97 paper by Hong et
- al.. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction]
-
-******************************************************************************/
-DdNode *
-cuddBddLICompaction(
- DdManager * dd /* manager */,
- DdNode * f /* function to be minimized */,
- DdNode * c /* constraint (care set) */)
-{
- st_table *marktable, *markcache, *buildcache;
- DdNode *res, *zero;
-
- zero = Cudd_Not(DD_ONE(dd));
- if (c == zero) return(zero);
-
- /* We need to use local caches for both steps of this operation.
- ** The results of the edge marking step are only valid as long as the
- ** edge markings themselves are available. However, the edge markings
- ** are lost at the end of one invocation of Cudd_bddLICompaction.
- ** Hence, the cache entries for the edge marking step must be
- ** invalidated at the end of this function.
- ** For the result of the building step we argue as follows. The result
- ** for a node and a given constrain depends on the BDD in which the node
- ** appears. Hence, the same node and constrain may give different results
- ** in successive invocations.
- */
- marktable = st_init_table(st_ptrcmp,st_ptrhash);
- if (marktable == NULL) {
- return(NULL);
- }
- markcache = st_init_table(MarkCacheCompare,MarkCacheHash);
- if (markcache == NULL) {
- st_free_table(marktable);
- return(NULL);
- }
- if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) {
- st_foreach(markcache, MarkCacheCleanUp, NULL);
- st_free_table(marktable);
- st_free_table(markcache);
- return(NULL);
- }
- st_foreach(markcache, MarkCacheCleanUp, NULL);
- st_free_table(markcache);
- buildcache = st_init_table(st_ptrcmp,st_ptrhash);
- if (buildcache == NULL) {
- st_free_table(marktable);
- return(NULL);
- }
- res = cuddBddLICBuildResult(dd,f,buildcache,marktable);
- st_free_table(buildcache);
- st_free_table(marktable);
- return(res);
-
-} /* end of cuddBddLICompaction */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddConstrainDecomp.]
-
- Description [Performs the recursive step of Cudd_bddConstrainDecomp.
- Returns f super (i) if successful; otherwise NULL.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddConstrainDecomp]
-
-******************************************************************************/
-static int
-cuddBddConstrainDecomp(
- DdManager * dd,
- DdNode * f,
- DdNode ** decomp)
-{
- DdNode *F, *fv, *fvn;
- DdNode *fAbs;
- DdNode *result;
- int ok;
-
- if (Cudd_IsConstant(f)) return(1);
- /* Compute complements of cofactors. */
- F = Cudd_Regular(f);
- fv = cuddT(F);
- fvn = cuddE(F);
- if (F == f) {
- fv = Cudd_Not(fv);
- fvn = Cudd_Not(fvn);
- }
- /* Compute abstraction of top variable. */
- fAbs = cuddBddAndRecur(dd, fv, fvn);
- if (fAbs == NULL) {
- return(0);
- }
- cuddRef(fAbs);
- fAbs = Cudd_Not(fAbs);
- /* Recursively find the next abstraction and the components of the
- ** decomposition. */
- ok = cuddBddConstrainDecomp(dd, fAbs, decomp);
- if (ok == 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);
- }
- cuddRef(result);
- decomp[F->index] = result;
- Cudd_IterDerefBdd(dd, fAbs);
- return(1);
-
-} /* end of cuddBddConstrainDecomp */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddCharToVect.]
-
- Description [Performs the recursive step of Cudd_bddCharToVect.
- This function maintains the invariant that f is non-zero.
- Returns the i-th component of the vector if successful; otherwise NULL.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddCharToVect]
-
-******************************************************************************/
-static DdNode *
-cuddBddCharToVect(
- DdManager * dd,
- DdNode * f,
- DdNode * x)
-{
- unsigned int topf;
- unsigned int level;
- int comple;
-
- DdNode *one, *zero, *res, *F, *fT, *fE, *T, *E;
-
- statLine(dd);
- /* Check the cache. */
- res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x);
- if (res != NULL) {
- return(res);
- }
-
- F = Cudd_Regular(f);
-
- topf = cuddI(dd,F->index);
- level = dd->perm[x->index];
-
- if (topf > level) return(x);
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- comple = F != f;
- fT = Cudd_NotCond(cuddT(F),comple);
- fE = Cudd_NotCond(cuddE(F),comple);
-
- if (topf == level) {
- if (fT == zero) return(zero);
- if (fE == zero) return(one);
- return(x);
- }
-
- /* Here topf < level. */
- if (fT == zero) return(cuddBddCharToVect(dd, fE, x));
- if (fE == zero) return(cuddBddCharToVect(dd, fT, x));
-
- T = cuddBddCharToVect(dd, fT, x);
- if (T == NULL) {
- return(NULL);
- }
- cuddRef(T);
- E = cuddBddCharToVect(dd, fE, x);
- if (E == 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);
- }
- cuddDeref(T);
- cuddDeref(E);
- cuddCacheInsert2(dd, cuddBddCharToVect, f, x, res);
- return(res);
-
-} /* end of cuddBddCharToVect */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the edge marking step of Cudd_bddLICompaction.]
-
- Description [Performs the edge marking step of Cudd_bddLICompaction.
- Returns the LUB of the markings of the two outgoing edges of <code>f</code>
- if successful; otherwise CUDD_OUT_OF_MEM.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction cuddBddLICBuildResult]
-
-******************************************************************************/
-static int
-cuddBddLICMarkEdges(
- DdManager * dd,
- DdNode * f,
- DdNode * c,
- st_table * table,
- st_table * cache)
-{
- DdNode *Fv, *Fnv, *Cv, *Cnv;
- DdNode *one, *zero;
- unsigned int topf, topc;
- int index;
- int comple;
- int resT, resE, res, retval;
- char **slot;
- MarkCacheKey *key;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- /* Terminal cases. */
- if (c == zero) return(DD_LIC_DC);
- if (f == one) return(DD_LIC_1);
- if (f == zero) return(DD_LIC_0);
-
- /* Make canonical to increase the utilization of the cache. */
- comple = Cudd_IsComplement(f);
- f = Cudd_Regular(f);
- /* Now f is a regular pointer to a non-constant node; c may be
- ** constant, or it may be complemented.
- */
-
- /* Check the cache. */
- key = ALLOC(MarkCacheKey, 1);
- if (key == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- key->f = f; key->c = c;
- if (st_lookup(cache, (char *)key, (char **)&res)) {
- 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);
- } else {
- index = Cudd_Regular(c)->index;
- 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);
- }
- } else {
- Cv = Cnv = c;
- }
-
- resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache);
- if (resT == CUDD_OUT_OF_MEM) {
- FREE(key);
- return(CUDD_OUT_OF_MEM);
- }
- resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache);
- if (resE == CUDD_OUT_OF_MEM) {
- 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 {
- 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) {
- 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;
- }
- return(res);
-
-} /* end of cuddBddLICMarkEdges */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the result of Cudd_bddLICompaction.]
-
- Description [Builds the results of Cudd_bddLICompaction.
- Returns a pointer to the minimized BDD if successful; otherwise NULL.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction cuddBddLICMarkEdges]
-
-******************************************************************************/
-static DdNode *
-cuddBddLICBuildResult(
- DdManager * dd,
- DdNode * f,
- st_table * cache,
- st_table * table)
-{
- DdNode *Fv, *Fnv, *r, *t, *e;
- DdNode *one, *zero;
- unsigned int topf;
- int index;
- int comple;
- int markT, markE, markings;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- if (Cudd_IsConstant(f)) return(f);
- /* Make canonical to increase the utilization of the cache. */
- comple = Cudd_IsComplement(f);
- f = Cudd_Regular(f);
-
- /* Check the cache. */
- if (st_lookup(cache, (char *)f, (char **)&r)) {
- return(Cudd_NotCond(r,comple));
- }
-
- /* Retrieve the edge markings. */
- if (st_lookup(table, (char *)f, (char **)&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);
- }
- } else if (markT == DD_LIC_1) {
- t = one;
- } else {
- t = zero;
- }
- cuddRef(t);
- if (markE == DD_LIC_NL) {
- e = cuddBddLICBuildResult(dd,Fnv,cache,table);
- if (e == NULL) {
- Cudd_IterDerefBdd(dd,t);
- return(NULL);
- }
- } else if (markE == DD_LIC_1) {
- e = one;
- } else {
- e = zero;
- }
- cuddRef(e);
-
- if (markT == DD_LIC_DC && markE != DD_LIC_DC) {
- 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);
- } 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);
- }
-
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddLICBuildResult */
-
-
-/**Function********************************************************************
-
- Synopsis [Hash function for the computed table of cuddBddLICMarkEdges.]
-
- Description [Hash function for the computed table of
- cuddBddLICMarkEdges. Returns the bucket number.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction]
-
-******************************************************************************/
-static int
-MarkCacheHash(
- char * ptr,
- int modulus)
-{
- int val = 0;
- MarkCacheKey *entry;
-
- entry = (MarkCacheKey *) ptr;
-
- val = (int) (ptrint) entry->f;
- val = val * 997 + (int) (ptrint) entry->c;
-
- return ((val < 0) ? -val : val) % modulus;
-
-} /* end of MarkCacheHash */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function for the computed table of
- cuddBddLICMarkEdges.]
-
- Description [Comparison function for the computed table of
- cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction]
-
-******************************************************************************/
-static int
-MarkCacheCompare(
- const char * ptr1,
- const char * ptr2)
-{
- MarkCacheKey *entry1, *entry2;
-
- entry1 = (MarkCacheKey *) ptr1;
- entry2 = (MarkCacheKey *) ptr2;
-
- return((entry1->f != entry2->f) || (entry1->c != entry2->c));
-
-} /* end of MarkCacheCompare */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Frees memory associated with computed table of
- cuddBddLICMarkEdges.]
-
- Description [Frees memory associated with computed table of
- cuddBddLICMarkEdges. Returns ST_CONTINUE.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLICompaction]
-
-******************************************************************************/
-static enum st_retval
-MarkCacheCleanUp(
- char * key,
- char * value,
- char * arg)
-{
- MarkCacheKey *entry;
-
- entry = (MarkCacheKey *) key;
- FREE(entry);
- return ST_CONTINUE;
-
-} /* end of MarkCacheCleanUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddSqueeze.]
-
- Description [Performs the recursive step of Cudd_bddSqueeze. This
- procedure exploits the fact that if we complement and swap the
- bounds of the interval we obtain a valid solution by taking the
- complement of the solution to the original problem. Therefore, we
- can enforce the condition that the upper bound is always regular.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddSqueeze]
-
-******************************************************************************/
-static DdNode *
-cuddBddSqueeze(
- DdManager * dd,
- DdNode * l,
- DdNode * u)
-{
- DdNode *one, *zero, *r, *lt, *le, *ut, *ue, *t, *e;
-#if 0
- DdNode *ar;
-#endif
- int comple = 0;
- unsigned int topu, topl;
- int index;
-
- statLine(dd);
- if (l == u) {
- return(l);
- }
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
- /* The only case when l == zero && u == one is at the top level,
- ** where returning either one or zero is OK. In all other cases
- ** the procedure will detect such a case and will perform
- ** remapping. Therefore the order in which we test l and u at this
- ** point is immaterial. */
- if (l == zero) return(l);
- if (u == one) return(u);
-
- /* 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;
- }
- /* At this point u is regular and non-constant; l is non-constant, but
- ** may be complemented. */
-
- /* Here we could check the relative sizes. */
-
- /* Check the cache. */
- r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u);
- if (r != NULL) {
- 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);
- } else {
- 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);
- }
- } else {
- 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));
- } 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));
- } 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);
- }
- }
- 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);
- }
- } 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));
- }
-
-#if 0
- /* If the two intervals intersect, take a solution from
- ** the intersection of the intervals. This guarantees that the
- ** splitting variable will not appear in the result.
- ** 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) {
- Cudd_IterDerefBdd(dd,au);
- Cudd_IterDerefBdd(dd,al);
- return(NULL);
- }
- cuddRef(ar);
- Cudd_IterDerefBdd(dd,au);
- Cudd_IterDerefBdd(dd,al);
- } else {
- ar = NULL;
- }
-#endif
-
- t = cuddBddSqueeze(dd, lt, ut);
- if (t == NULL) {
- return(NULL);
- }
- cuddRef(t);
- e = cuddBddSqueeze(dd, le, ue);
- if (e == 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);
- } 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 0
- /* Check whether there is a result obtained by abstraction and whether
- ** 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);
- }
- }
- cuddDeref(r);
-#endif
-
- cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r);
- return(Cudd_NotCond(r,comple));
-
-} /* end of cuddBddSqueeze */
diff --git a/src/bdd/cudd/cuddGenetic.c b/src/bdd/cudd/cuddGenetic.c
deleted file mode 100644
index 9fe03dad..00000000
--- a/src/bdd/cudd/cuddGenetic.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddGenetic.c]
-
- PackageName [cudd]
-
- 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>
-
- The genetic algorithm implemented here is as follows. We start with
- the current DD order. We sift this order and use this as the
- reference DD. We only keep 1 DD around for the entire process and
- simply rearrange the order of this DD, storing the various orders
- and their corresponding DD sizes. We generate more random orders to
- build an initial population. This initial population is 3 times the
- number of variables, with a maximum of 120. Each random order is
- built (from the reference DD) and its size stored. Each random
- order is also sifted to keep the DD sizes fairly small. Then a
- crossover is performed between two orders (picked randomly) and the
- two resulting DDs are built and sifted. For each new order, if its
- size is smaller than any DD in the population, it is inserted into
- the population and the DD with the largest number of nodes is thrown
- out. The crossover process happens up to 50 times, and at this point
- the DD in the population with the smallest size is chosen as the
- result. This DD must then be built from the reference DD.]
-
- SeeAlso []
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-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
-** size. The order is stored by storing the indices of variables in the
-** order in which they appear in the order. The table is in reality a
-** one-dimensional array which is accessed via a macro to give the illusion
-** 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 int result;
-static int cross; /* the number of crossovers to perform */
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/* macro used to access the population table as if it were a
-** two-dimensional structure.
-*/
-#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)]
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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((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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Genetic algorithm for DD reordering.]
-
- Description [Genetic algorithm for DD reordering.
- The two children of a crossover will be stored in
- storedd[popsize] and storedd[popsize+1] --- the last two slots in the
- storedd array. (This will make comparisons and replacement easy.)
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddGa(
- DdManager * table /* manager */,
- 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 */
-
- /* Do an initial sifting to produce at least one reasonable individual. */
- if (!cuddSifting(table,lower,upper)) return(0);
-
- /* 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 */
- }
- } else {
- popsize = table->populationSize; /* user specified value */
- }
- if (popsize < 4) popsize = 4; /* enforce minimum population size */
-
- /* Allocate population table. */
- storedd = ALLOC(int,(popsize+2)*(numvars+1));
- if (storedd == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
-
- /* Initialize the computed table. This table is made up of two data
- ** structures: A hash table with the key given by the order, which says
- ** if a given order is present in the population; and the repeat
- ** vector, which says how many copies of a given order are stored in
- ** the population table. If there are multiple copies of an order, only
- ** one has a repeat count greater than 1. This copy is the one pointed
- ** by the computed table.
- */
- repeat = ALLOC(int,popsize);
- if (repeat == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- return(0);
- }
- for (i = 0; i < popsize; i++) {
- repeat[i] = 0;
- }
- computed = st_init_table(array_compare,array_hash);
- if (computed == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- 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,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) {
- FREE(storedd);
- 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 */
- }
-
- /* Now create the random orders. make_random fills the population
- ** table with random permutations. The successive loop builds and sifts
- ** the DDs for the reverse order and each random permutation, and stores
- ** the results in the computed table.
- */
- if (!make_random(table,lower)) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- 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) {
- FREE(storedd);
- 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) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[i]++;
- }
- }
-
-#if 0
-#ifdef DD_STATS
- /* 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]);
- }
-#endif
-#endif
-
- small = find_best();
- average_fitness = find_average_fitness();
-#ifdef DD_STATS
- (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;
- }
- } else {
- 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;
- FREE(storedd);
- 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) {
- FREE(storedd);
- 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) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[index]--;
- if (repeat[index] == 0) {
- int *pointer = &STOREDD(index,0);
- result = st_delete(computed, (char **)&pointer,NULL);
- if (!result) {
- FREE(storedd);
- 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) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[large]++;
- }
- }
- }
- }
-
- /* Find the smallest DD in the population and build it;
- ** that will be the result.
- */
- small = find_best();
-
- /* Print stats on the final population. */
-#ifdef DD_STATS
- average_fitness = find_average_fitness();
- (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
-#endif
-
- /* Clean up, build the result DD, and return. */
- st_free_table(computed);
- computed = NULL;
- result = build_dd(table,small,lower,upper);
- FREE(storedd);
- FREE(repeat);
- return(result);
-
-} /* end of cuddGa */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Generates the random sequences for the initial population.]
-
- Description [Generates the random sequences for the initial population.
- The sequences are permutations of the indices between lower and
- upper in the current order.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-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 */
-
- used = ALLOC(int,numvars);
- if (used == NULL) {
- 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");
- }
-#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];
- }
-#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");
-#endif
-#endif
- }
- FREE(used);
- return(1);
-
-} /* end of make_random */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves one variable up.]
-
- Description [Takes a variable from position x and sifts it up to
- position x_low; x_low should be less than x. Returns 1 if successful;
- 0 otherwise]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-sift_up(
- DdManager * table,
- int x,
- int x_low)
-{
- int y;
- int size;
-
- y = cuddNextLow(table,x);
- while (y >= x_low) {
- size = cuddSwapInPlace(table,y,x);
- if (size == 0) {
- return(0);
- }
- x = y;
- y = cuddNextLow(table,x);
- }
- return(1);
-
-} /* end of sift_up */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds a DD from a given order.]
-
- Description [Builds a DD from a given order. This procedure also
- sifts the final order and inserts into the array the size in nodes
- of the result. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-build_dd(
- DdManager * table,
- int num /* the index of the individual to be built */,
- 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;
-
- /* 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);
-#ifdef DD_STATS
- (void) fprintf(table->out,"\nCache hit for index %d", index);
-#endif
- return(1);
- }
-
- /* Stop if the DD grows 20 times larges than the reference size. */
- limit = 20 * STOREDD(0,numvars);
-
- /* Sift up the variables so as to build the desired permutation.
- ** First the variable that has to be on top is sifted to the top.
- ** Then the variable that has to occupy the secon position is sifted
- ** 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;
- }
-
- /* Sift the DD just built. */
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
-#endif
- result = cuddSifting(table,lower,upper);
- if (!result) return(0);
-
- /* Copy order and size to table. */
- for (j = 0; j < numvars; j++) {
- STOREDD(num,j) = table->invperm[lower+j];
- }
- STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */
- return(1);
-
-} /* end of build_dd */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the largest DD in the population.]
-
- Description [Finds the largest DD in the population. If an order is
- repeated, it avoids choosing the copy that is in the computed table
- (it has repeat[i] > 1).]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-largest(
- )
-{
- 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;
- }
- }
- return(big);
-
-} /* end of largest */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a random number between 0 and the integer a.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-rand_int(
- int a)
-{
- return(Cudd_Random() % (a+1));
-
-} /* end of rand_int */
-
-
-/**Function********************************************************************
-
- Synopsis [Hash function for the computed table.]
-
- Description [Hash function for the computed table. Returns the bucket
- number.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-array_hash(
- char * array,
- int modulus)
-{
- int val = 0;
- int i;
- int *intarray;
-
- intarray = (int *) array;
-
- for (i = 0; i < numvars; i++) {
- val = val * 997 + intarray[i];
- }
-
- return ((val < 0) ? -val : val) % modulus;
-
-} /* end of array_hash */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function for the computed table.]
-
- Description [Comparison function for the computed table. Returns 0 if
- the two arrays are equal; 1 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-array_compare(
- const char * array1,
- const char * array2)
-{
- int i;
- int *intarray1, *intarray2;
-
- intarray1 = (int *) array1;
- intarray2 = (int *) array2;
-
- for (i = 0; i < numvars; i++) {
- if (intarray1[i] != intarray2[i]) return(1);
- }
- return(0);
-
-} /* end of array_compare */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of the fittest individual.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-find_best(
- )
-{
- int i,small;
-
- small = 0;
- for (i = 1; i < popsize; i++) {
- if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
- small = i;
- }
- }
- return(small);
-
-} /* end of find_best */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the average fitness of the population.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double
-find_average_fitness(
- )
-{
- int i;
- int total_fitness = 0;
- double average_fitness;
-
- for (i = 0; i < popsize; i++) {
- total_fitness += STOREDD(i,numvars);
- }
- average_fitness = (double) total_fitness / (double) popsize;
- return(average_fitness);
-
-} /* end of find_average_fitness */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the crossover between two parents.]
-
- Description [Performs the crossover between two randomly chosen
- parents, and creates two children, x1 and x2. Uses the Partially
- Matched Crossover operator.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-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 */
-
- inv1 = ALLOC(int,maxvar);
- if (inv1 == NULL) {
- return(0);
- }
- inv2 = ALLOC(int,maxvar);
- if (inv2 == NULL) {
- FREE(inv1);
- return(0);
- }
-
- /* Choose two orders from the population using roulette wheel. */
- if (!roulette(&mom,&dad)) {
- FREE(inv1);
- FREE(inv2);
- return(0);
- }
-
- /* Choose two random cut positions. A cut in position i means that
- ** the cut immediately precedes position i. If cut1 < cut2, we
- ** exchange the middle of the two orderings; otherwise, we
- ** exchange the beginnings and the ends.
- */
- cut1 = rand_int(numvars-1);
- do {
- 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);
- for (i = 0; i < numvars; 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));
- }
- (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;
- }
-
- /* 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;
- }
-
- /* 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;
- }
-
-#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));
- }
- (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));
- }
- (void) fprintf(table->out,"\n");
-#endif
-
- FREE(inv1);
- FREE(inv2);
- return(1);
-
-} /* end of PMX */
-
-
-/**Function********************************************************************
-
- Synopsis [Selects two parents with the roulette wheel method.]
-
- Description [Selects two distinct parents with the roulette wheel method.]
-
- SideEffects [The indices of the selected parents are returned as side
- effects.]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-roulette(
- int * p1,
- int * p2)
-{
- double *wheel;
- double spin;
- int i;
-
- wheel = ALLOC(double,popsize);
- if (wheel == NULL) {
- 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);
- }
-
- /* Get a random number between 0 and wheel[popsize-1] (that is,
- ** the sum of all fitness values. 2147483561 is the largest number
- ** returned by Cudd_Random.
- */
- spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0;
-
- /* Find the lucky element by scanning the wheel. */
- for (i = 0; i < popsize; i++) {
- if (spin <= wheel[i]) break;
- }
- *p1 = i;
-
- /* Repeat the process for the second parent, making sure it is
- ** 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;
- }
- } while (i == *p1);
- *p2 = i;
-
- FREE(wheel);
- return(1);
-
-} /* end of roulette */
-
diff --git a/src/bdd/cudd/cuddGroup.c b/src/bdd/cudd/cuddGroup.c
deleted file mode 100644
index 81c05d2c..00000000
--- a/src/bdd/cudd/cuddGroup.c
+++ /dev/null
@@ -1,2142 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddGroup.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Constants for lazy sifting */
-#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
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* 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 $";
-#endif
-
-static int *entry;
-extern int ddTotalNumberSwapping;
-#ifdef DD_STATS
-extern int ddTotalNISwaps;
-static int extsymmcalls;
-static int extsymm;
-static int secdiffcalls;
-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 */
-#endif
-static int originalSize;
-static int originalLevel;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int ddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method));
-#ifdef DD_STATS
-static int ddCountInternalMtrNodes ARGS((DdManager *table, MtrNode *treenode));
-#endif
-static int ddReorderChildren ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method));
-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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Creates a new variable group.]
-
- Description [Creates a new variable group. The group starts at
- variable and contains size variables. The parameter low is the index
- of the first variable. If the variable already exists, its current
- position in the order is known to the manager. If the variable does
- not exist yet, the position is assumed to be the same as the index.
- The group tree is created if it does not exist yet.
- Returns a pointer to the group if successful; NULL otherwise.]
-
- SideEffects [The variable tree is changed.]
-
- SeeAlso [Cudd_MakeZddTreeNode]
-
-******************************************************************************/
-MtrNode *
-Cudd_MakeTreeNode(
- DdManager * dd /* manager */,
- unsigned int low /* index of the first group variable */,
- unsigned int size /* number of variables in the group */,
- unsigned int type /* MTR_DEFAULT or MTR_FIXED */)
-{
- MtrNode *group;
- MtrNode *tree;
- unsigned int level;
-
- /* If the variable does not exist yet, the position is assumed to be
- ** the same as the index. Therefore, applications that rely on
- ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
- ** variables have to create the variables before they group them.
- */
- level = (low < (unsigned int) dd->size) ? dd->perm[low] : low;
-
- if (level + size - 1> (int) MTR_MAXHIGH)
- 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];
- }
-
- /* Extend the upper bound of the tree if necessary. This allows the
- ** application to create groups even before the variables are created.
- */
- tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size));
-
- /* Create the group. */
- group = Mtr_MakeGroup(tree, level, size, type);
- if (group == 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
- ** procedure to provide a handle to the group once it has been moved.
- */
- group->index = (MtrHalfWord) low;
-
- return(group);
-
-} /* end of Cudd_MakeTreeNode */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Tree sifting algorithm.]
-
- Description [Tree sifting algorithm. Assumes that a tree representing
- a group hierarchy is passed as a parameter. It then reorders each
- group in postorder fashion by calling ddTreeSiftingAux. Assumes that
- no dead nodes are present. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddTreeSifting(
- DdManager * table /* DD table */,
- Cudd_ReorderingType method /* reordering method for the groups of leaves */)
-{
- int i;
- int nvars;
- int result;
- int tempTree;
-
- /* If no tree is provided we create a temporary one in which all
- ** variables are in a single group. After reordering this tree is
- ** destroyed.
- */
- tempTree = table->tree == NULL;
- if (tempTree) {
- table->tree = Mtr_InitGroupTree(0,table->size);
- table->tree->index = table->invperm[0];
- }
- nvars = table->size;
-
-#ifdef DD_DEBUG
- if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:");
- Mtr_PrintGroups(table->tree,pr <= 0);
-#endif
-
-#ifdef DD_STATS
- extsymmcalls = 0;
- extsymm = 0;
- secdiffcalls = 0;
- secdiff = 0;
- secdiffmisfire = 0;
-
- (void) fprintf(table->out,"\n");
- if (!tempTree)
- (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
- ** there are no groups. Groups are created according to the tree
- ** structure in postorder fashion.
- */
- for (i = 0; i < nvars; i++)
- table->subtables[i].next = i;
-
-
- /* Reorder. */
- result = ddTreeSiftingAux(table, table->tree, method);
-
-#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);
- }
- 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);
- }
-#endif
-
- if (tempTree)
- Cudd_FreeTree(table);
- return(result);
-
-} /* end of cuddTreeSifting */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Visits the group tree and reorders each group.]
-
- Description [Recursively visits the group tree and reorders each
- group in postorder fashion. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddTreeSiftingAux(
- DdManager * table,
- MtrNode * treenode,
- Cudd_ReorderingType method)
-{
- MtrNode *auxnode;
- int res;
- Cudd_AggregationType saveCheck;
-
-#ifdef DD_DEBUG
- Mtr_PrintGroups(treenode,1);
-#endif
-
- auxnode = treenode;
- while (auxnode != NULL) {
- 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);
-
-} /* end of ddTreeSiftingAux */
-
-
-#ifdef DD_STATS
-/**Function********************************************************************
-
- Synopsis [Counts the number of internal nodes of the group tree.]
-
- Description [Counts the number of internal nodes of the group tree.
- Returns the count.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddCountInternalMtrNodes(
- DdManager * table,
- MtrNode * treenode)
-{
- MtrNode *auxnode;
- int count,nodeCount;
-
-
- nodeCount = 0;
- auxnode = treenode;
- while (auxnode != NULL) {
- if (!(MTR_TEST(auxnode,MTR_TERMINAL))) {
- nodeCount++;
- count = ddCountInternalMtrNodes(table,auxnode->child);
- nodeCount += count;
- }
- auxnode = auxnode->younger;
- }
-
- return(nodeCount);
-
-} /* end of ddCountInternalMtrNodes */
-#endif
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders the children of a group tree node according to
- the options.]
-
- Description [Reorders the children of a group tree node according to
- the options. After reordering puts all the variables in the group
- and/or its descendents in a single group. This allows hierarchical
- reordering. If the variables in the group do not exist yet, simply
- does nothing. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddReorderChildren(
- DdManager * table,
- MtrNode * treenode,
- Cudd_ReorderingType method)
-{
- int lower;
- int upper;
- int result;
- unsigned int initialSize;
-
- ddFindNodeHiLo(table,treenode,&lower,&upper);
- /* If upper == -1 these variables do not exist yet. */
- if (upper == -1)
- return(1);
-
- if (treenode->flags == MTR_FIXED) {
- result = 1;
- } else {
-#ifdef DD_STATS
- (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)
- break;
-#ifdef DD_STATS
- else
- (void) fprintf(table->out,"\n");
-#endif
- } 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");
-#endif
- result = cuddWindowReorder(table,lower,upper,
- CUDD_REORDER_WINDOW4);
- if (initialSize <= table->keys - table->isolated)
- break;
-#ifdef DD_STATS
- 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)
- break;
-#ifdef DD_STATS
- 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);
- }
- }
-
- /* Create a single group for all the variables that were sifted,
- ** so that they will be treated as a single block by successive
- ** invocations of ddGroupSifting.
- */
- ddMergeGroups(table,treenode,lower,upper);
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"ddReorderChildren:");
-#endif
-
- return(result);
-
-} /* end of ddReorderChildren */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the lower and upper bounds of the group represented
- by treenode.]
-
- Description [Finds the lower and upper bounds of the group
- represented by treenode. From the index and size fields we need to
- derive the current positions, and find maximum and minimum.]
-
- SideEffects [The bounds are returned as side effects.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddFindNodeHiLo(
- DdManager * table,
- MtrNode * treenode,
- int * lower,
- int * upper)
-{
- int low;
- int high;
-
- /* Check whether no variables in this group already exist.
- ** If so, return immediately. The calling procedure will know from
- ** the values of upper that no reordering is needed.
- */
- if ((int) treenode->low >= table->size) {
- *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.
- */
- 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;
- }
-
-#ifdef DD_DEBUG
- /* Make sure that all variables in group are contiguous. */
- assert(treenode->size >= *upper - *lower + 1);
-#endif
-
- return;
-
-} /* end of ddFindNodeHiLo */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the variables
- according to the number of keys in the subtables. Returns the
- difference in number of keys between the two variables being
- compared.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddUniqueCompareGroup(
- int * ptrX,
- int * ptrY)
-{
-#if 0
- if (entry[*ptrY] == entry[*ptrX]) {
- return((*ptrX) - (*ptrY));
- }
-#endif
- return(entry[*ptrY] - entry[*ptrX]);
-
-} /* end of ddUniqueCompareGroup */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts from treenode->low to treenode->high.]
-
- Description [Sifts from treenode->low to treenode->high. If
- croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the
- end of the initial sifting. If a group is created, it is then sifted
- again. After sifting one variable, the group that contains it is
- dissolved. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupSifting(
- DdManager * table,
- int lower,
- int upper,
- int (*checkFunction)(DdManager *, int, int),
- int lazyFlag)
-{
- 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;
-
- nvars = table->size;
-
- /* Order variables to sift. */
- entry = NULL;
- sifted = NULL;
- var = ALLOC(int,nvars);
- if (var == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto ddGroupSiftingOutOfMem;
- }
- entry = ALLOC(int,nvars);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto ddGroupSiftingOutOfMem;
- }
- sifted = ALLOC(int,nvars);
- if (sifted == NULL) {
- 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++;
- }
- }
-
- qsort((void *)var,classes,sizeof(int),
- (int (*)(const void *, const void *)) ddUniqueCompareGroup);
-
- if (lazyFlag) {
- 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;
- x = table->perm[xindex]; /* find current level of this variable */
-
- if (x < lower || x > upper || table->subtables[x].bindVar == 1)
- continue;
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
-#ifdef DD_DEBUG
- /* 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 (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;
-#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,"+");
- } 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);
- }
- }
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:");
-#endif
-
- if (lazyFlag) ddSetVarHandled(table, xindex);
- } /* for */
-
- FREE(sifted);
- FREE(var);
- FREE(entry);
-
- return(1);
-
-ddGroupSiftingOutOfMem:
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
- if (sifted != NULL) FREE(sifted);
-
- return(0);
-
-} /* end of ddGroupSifting */
-
-
-/**Function********************************************************************
-
- Synopsis [Creates a group encompassing variables from x to y in the
- DD table.]
-
- Description [Creates a group encompassing variables from x to y in the
- DD table. In the current implementation it must be y == x+1.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddCreateGroup(
- DdManager * table,
- int x,
- int y)
-{
- int gybot;
-
-#ifdef DD_DEBUG
- assert(y == x+1);
-#endif
-
- /* Find bottom of second group. */
- gybot = y;
- while ((unsigned) gybot < table->subtables[gybot].next)
- gybot = table->subtables[gybot].next;
-
- /* Link groups. */
- table->subtables[x].next = y;
- table->subtables[gybot].next = x;
-
- return;
-
-} /* ddCreateGroup */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts one variable up and down until it has taken all
- positions. Checks for aggregation.]
-
- Description [Sifts one variable up and down until it has taken all
- positions. Checks for aggregation. There may be at most two sweeps,
- even if the group grows. Assumes that x is either an isolated
- variable, or it is the bottom of a group. All groups may not have
- been found. The variable being moved is returned to the best position
- seen during sifting. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupSiftingAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh,
- int (*checkFunction)(DdManager *, int, int),
- int lazyFlag)
-{
- Move *move;
- Move *moves; /* list of moves */
- int initialSize;
- int result;
- int y;
- int topbot;
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,
- "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 */
-
- /* 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;
- }
- 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 */
-
- if (x == xLow) { /* Sift down */
-#ifdef DD_DEBUG
- /* x must be a singleton */
- assert((unsigned) x == table->subtables[x].next);
-#endif
- 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 */
-
- /* 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);
-#endif
- if (!result) goto ddGroupSiftingAuxOutOfMem;
-
- } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */
-#ifdef DD_DEBUG
- /* x is bottom of group */
- assert((unsigned) x >= table->subtables[x].next);
-#endif
- /* Find top of x's group */
- x = table->subtables[x].next;
-
- if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves))
- goto ddGroupSiftingAuxOutOfMem;
- /* at this point x == xLow, unless early term */
-
- /* 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);
-#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 */
-
- /* Find top of group */
- if (moves) {
- x = moves->y;
- }
- while ((unsigned) 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);
-#endif
-
- 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);
-#ifdef DD_DEBUG
- assert(table->keys - table->isolated <= (unsigned) initialSize);
-#endif
- if (!result) goto ddGroupSiftingAuxOutOfMem;
-
- } else { /* moving up first: shorter */
- /* Find top of x's group */
- x = table->subtables[x].next;
-
- if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves))
- goto ddGroupSiftingAuxOutOfMem;
- /* 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;
-#ifdef DD_DEBUG
- /* x is bottom of a group */
- assert((unsigned) x >= table->subtables[x].next);
-#endif
-
- 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);
-#ifdef DD_DEBUG
- assert(table->keys - table->isolated <= (unsigned) initialSize);
-#endif
- if (!result) goto ddGroupSiftingAuxOutOfMem;
- }
-
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
-
- return(1);
-
-ddGroupSiftingAuxOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
-
- return(0);
-
-} /* end of ddGroupSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts up a variable until either it reaches position xLow
- or the size of the DD heap increases too much.]
-
- Description [Sifts up a variable until either it reaches position
- xLow or the size of the DD heap increases too much. Assumes that y is
- the top of a group (or a singleton). Checks y for aggregation to the
- adjacent variables. Records all the moves that are appended to the
- list of moves received as input and returned as a side effect.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupSiftingUp(
- DdManager * table,
- int y,
- int xLow,
- int (*checkFunction)(DdManager *, int, int),
- Move ** moves)
-{
- Move *move;
- int x;
- int size;
- int i;
- int gxtop,gybot;
- int limitSize;
- int xindex, yindex;
- int zindex;
- int z;
- int isolated;
- int L; /* lower bound on DD size */
-#ifdef DD_DEBUG
- int checkL;
-#endif
-
- yindex = table->invperm[y];
-
- /* Initialize the lower bound.
- ** The part of the DD below the bottom of y's group will not change.
- ** The part of the DD above y that does not interact with any
- ** variable of y's group will not change.
- ** The rest may vanish in the best case, except for
- ** the nodes at level xLow, which will not vanish, regardless.
- ** What we use here is not really a lower bound, because we ignore
- ** the interactions with all variables except y.
- */
- limitSize = L = table->keys - table->isolated;
- gybot = y;
- while ((unsigned) 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;
- }
- }
-
- 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;
- }
- }
- 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;
- } else if (table->subtables[x].next == (unsigned) x &&
- table->subtables[y].next == (unsigned) y) {
- /* x and y are self groups */
- 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;
- }
- move = (Move *)cuddDynamicAllocNode(table);
- if (move == NULL) goto ddGroupSiftingUpOutOfMem;
- move->x = x;
- move->y = y;
- 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");
-#endif
- if ((double) size > (double) limitSize * table->maxGrowth)
- 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 ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
- }
- y = gxtop;
- x = cuddNextLow(table,y);
- }
-
- return(1);
-
-ddGroupSiftingUpOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
- return(0);
-
-} /* end of ddGroupSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts down a variable until it reaches position xHigh.]
-
- Description [Sifts down a variable until it reaches position xHigh.
- Assumes that x is the bottom of a group (or a singleton). Records
- all the moves. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupSiftingDown(
- DdManager * table,
- int x,
- int xHigh,
- int (*checkFunction)(DdManager *, int, int),
- Move ** moves)
-{
- Move *move;
- int y;
- int size;
- int limitSize;
- int gxtop,gybot;
- int R; /* upper bound on node decrease */
- int xindex, yindex;
- int isolated, allVars;
- int z;
- int zindex;
-#ifdef DD_DEBUG
- int checkR;
-#endif
-
- /* If the group consists of simple variables, there is no point in
- ** sifting it down. This check is redundant if the projection functions
- ** do not have external references, because the computation of the
- ** lower bound takes care of the problem. It is necessary otherwise to
- ** prevent the sifting down of simple variables. */
- y = x;
- allVars = 1;
- do {
- 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);
-
- /* 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;
- }
- }
-
- 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;
- }
- }
- assert(R >= checkR);
-#endif
- /* 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;
- } else if (table->subtables[x].next == (unsigned) x &&
- 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;
- }
- 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 ddGroupSiftingDownOutOfMem;
-
- /* Record move. */
- move = (Move *) cuddDynamicAllocNode(table);
- if (move == NULL) goto ddGroupSiftingDownOutOfMem;
- move->x = x;
- move->y = y;
- 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");
-#endif
- if ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
-
- 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);
- size = ddGroupMove(table,x,y,moves);
- if (size == 0) goto ddGroupSiftingDownOutOfMem;
- if ((double) size > (double) limitSize * table->maxGrowth)
- 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;
- }
- }
- }
- x = gybot;
- y = cuddNextHigh(table,x);
- }
-
- return(1);
-
-ddGroupSiftingDownOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
-
- return(0);
-
-} /* end of ddGroupSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two groups and records the move.]
-
- Description [Swaps two groups and records the move. Returns the
- number of keys in the DD table in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupMove(
- DdManager * table,
- int x,
- int y,
- Move ** moves)
-{
- Move *move;
- int size;
- int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
- int swapx,swapy;
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- int initialSize,bestSize;
-#endif
-
-#if DD_DEBUG
- /* We assume that x < y */
- assert(x < y);
-#endif
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtables[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) ybot < table->subtables[ybot].next)
- ybot = table->subtables[ybot].next;
- ytop = y;
- ysize = ybot - ytop + 1;
-
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- initialSize = bestSize = table->keys - table->isolated;
-#endif
- /* 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) goto ddGroupMoveOutOfMem;
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- if (size < bestSize)
- bestSize = size;
-#endif
- swapx = x; swapy = y;
- y = x;
- x = cuddNextLow(table,y);
- }
- y = ytop + i;
- x = cuddNextLow(table,y);
- }
-#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);
-#endif
-
- /* fix groups */
- y = xtop; /* ytop is now where xtop used to be */
- for (i = 0; i < ysize - 1; i++) {
- table->subtables[y].next = cuddNextHigh(table,y);
- y = cuddNextHigh(table,y);
- }
- table->subtables[y].next = xtop; /* y is bottom of its group, join */
- /* it to top of its group */
- x = cuddNextHigh(table,y);
- newxtop = x;
- for (i = 0; i < xsize - 1; i++) {
- table->subtables[x].next = cuddNextHigh(table,x);
- x = cuddNextHigh(table,x);
- }
- table->subtables[x].next = newxtop; /* x is bottom of its group, join */
- /* it to top of its group */
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"ddGroupMove:\n");
-#endif
-
- /* Store group move */
- move = (Move *) cuddDynamicAllocNode(table);
- if (move == NULL) goto ddGroupMoveOutOfMem;
- move->x = swapx;
- move->y = swapy;
- move->flags = MTR_DEFAULT;
- move->size = table->keys - table->isolated;
- move->next = *moves;
- *moves = move;
-
- return(table->keys - table->isolated);
-
-ddGroupMoveOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
- return(0);
-
-} /* end of ddGroupMove */
-
-
-/**Function********************************************************************
-
- Synopsis [Undoes the swap two groups.]
-
- Description [Undoes the swap two groups. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupMoveBackward(
- DdManager * table,
- int x,
- int y)
-{
- int size;
- int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
-
-
-#if DD_DEBUG
- /* We assume that x < y */
- assert(x < y);
-#endif
-
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtables[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) 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 = cuddNextLow(table,y);
- }
-
- /* fix groups */
- y = xtop;
- for (i = 0; i < ysize - 1; i++) {
- table->subtables[y].next = cuddNextHigh(table,y);
- y = cuddNextHigh(table,y);
- }
- table->subtables[y].next = xtop; /* y is bottom of its group, join */
- /* to its top */
- x = cuddNextHigh(table,y);
- newxtop = x;
- for (i = 0; i < xsize - 1; i++) {
- table->subtables[x].next = cuddNextHigh(table,x);
- x = cuddNextHigh(table,x);
- }
- table->subtables[x].next = newxtop; /* x is bottom of its group, join */
- /* to its top */
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"ddGroupMoveBackward:\n");
-#endif
-
- return(1);
-
-} /* end of ddGroupMoveBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines the best position for a variables and returns
- it there.]
-
- Description [Determines the best position for a variables and returns
- it there. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddGroupSiftingBackward(
- DdManager * table,
- Move * moves,
- int size,
- int upFlag,
- int lazyFlag)
-{
- Move *move;
- int res;
- Move *end_move;
- int diff, tmp_diff;
- int index, pairlev;
-
- if (lazyFlag) {
- end_move = NULL;
-
- /* 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 (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;
- }
- }
- }
-
- /* 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 ((table->subtables[move->x].next == move->x) &&
- (table->subtables[move->y].next == move->y)) {
- res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
- if (!res) return(0);
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"ddGroupSiftingBackward:\n");
- assert(table->subtables[move->x].next == move->x);
- 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);
- }
- }
-
- }
-
- return(1);
-
-} /* end of ddGroupSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Merges groups in the DD table.]
-
- Description [Creates a single group from low to high and adjusts the
- index field of the tree node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddMergeGroups(
- DdManager * table,
- MtrNode * treenode,
- int low,
- int high)
-{
- int i;
- MtrNode *auxnode;
- int saveindex;
- int newindex;
-
- /* Merge all variables from low to high in one group, unless
- ** 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;
- }
-
- /* Adjust the index fields of the tree nodes. If a node is the
- ** first child of its parent, then the parent may also need adjustment. */
- saveindex = treenode->index;
- newindex = table->invperm[low];
- auxnode = treenode;
- do {
- auxnode->index = newindex;
- if (auxnode->parent == NULL ||
- (int) auxnode->parent->index != saveindex)
- break;
- auxnode = auxnode->parent;
- } while (1);
- return;
-
-} /* end of ddMergeGroups */
-
-
-/**Function********************************************************************
-
- Synopsis [Dissolves a group in the DD table.]
-
- Description [x and y are variables in a group to be cut in two. The cut
- is to pass between x and y.]
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddDissolveGroup(
- DdManager * table,
- int x,
- int y)
-{
- int topx;
- int boty;
-
- /* find top and bottom of the two groups */
- boty = y;
- while ((unsigned) boty < table->subtables[boty].next)
- boty = table->subtables[boty].next;
-
- topx = table->subtables[boty].next;
-
- table->subtables[boty].next = y;
- table->subtables[x].next = topx;
-
- return;
-
-} /* end of ddDissolveGroup */
-
-
-/**Function********************************************************************
-
- Synopsis [Pretends to check two variables for aggregation.]
-
- Description [Pretends to check two variables for aggregation. Always
- returns 0.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddNoCheck(
- DdManager * table,
- int x,
- int y)
-{
- return(0);
-
-} /* end of ddNoCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks two variables for aggregation.]
-
- Description [Checks two variables for aggregation. The check is based
- on the second difference of the number of nodes as a function of the
- layer. If the second difference is lower than a given threshold
- (typically negative) then the two variables should be aggregated.
- Returns 1 if the two variables pass the test; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSecDiffCheck(
- DdManager * table,
- int x,
- int y)
-{
- double Nx,Nx_1;
- double Sx;
- double threshold;
- int xindex,yindex;
-
- if (x==0) return(0);
-
-#ifdef DD_STATS
- secdiffcalls++;
-#endif
- Nx = (double) table->subtables[x].keys;
- Nx_1 = (double) table->subtables[x-1].keys;
- Sx = (table->subtables[y].keys/Nx) - (Nx/Nx_1);
-
- threshold = table->recomb / 100.0;
- if (Sx < threshold) {
- 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);
-#endif
-#ifdef DD_STATS
- secdiff++;
-#endif
- return(1);
- } else {
-#ifdef DD_STATS
- secdiffmisfire++;
-#endif
- return(0);
- }
-
- }
- return(0);
-
-} /* end of ddSecDiffCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for extended symmetry of x and y.]
-
- Description [Checks for extended symmetry of x and y. Returns 1 in
- case of extended symmetry; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddExtSymmCheck(
- DdManager * table,
- int x,
- int y)
-{
- 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 */
- int i;
- int xindex;
- int yindex;
- int res;
- int slots;
- DdNodePtr *list;
- DdNode *sentinel = &(table->sentinel);
-
- xindex = table->invperm[x];
- yindex = table->invperm[y];
-
- /* If the two variables do not interact, we do not want to merge them. */
- if (!cuddTestInteract(table,xindex,yindex))
- return(0);
-
-#ifdef DD_DEBUG
- /* Checks that x and y do not contain just the projection functions.
- ** With the test on interaction, these test become redundant,
- ** because an isolated projection function does not interact with
- ** any other variable.
- */
- if (table->subtables[x].keys == 1) {
- assert(table->vars[xindex]->ref != 1);
- }
- if (table->subtables[y].keys == 1) {
- assert(table->vars[yindex]->ref != 1);
- }
-#endif
-
-#ifdef DD_STATS
- extsymmcalls++;
-#endif
-
- arccount = 0;
- counter = (int) (table->subtables[x].keys *
- (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.
- */
- 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 (f01 != f10 && f11 != f00) {
- if (counter == 0)
- return(0);
- counter--;
- }
- }
-
- f = f->next;
- } /* while */
- } /* for */
-
- /* Calculate the total reference counts of y */
- 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;
- }
- }
-
- arccounter = (int) (table->subtables[y].keys *
- (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);
- }
-#endif
-
-#ifdef DD_STATS
- if (res)
- extsymm++;
-#endif
- return(res);
-
-} /* end ddExtSymmCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for grouping of x and y.]
-
- Description [Checks for grouping of x and y. Returns 1 in
- case of grouping; 0 otherwise. This function is used for lazy sifting.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddVarGroupCheck(
- DdManager * table,
- int x,
- int y)
-{
- int xindex = table->invperm[x];
- int yindex = table->invperm[y];
-
- 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 <= originalSize) {
- return(1);
- }
- }
- }
- }
-
- return(0);
-
-} /* end of ddVarGroupCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Sets a variable to already handled.]
-
- Description [Sets a variable to already handled. This function is used
- for lazy sifting.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddSetVarHandled(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].varHandled = 1;
- return(1);
-
-} /* end of ddSetVarHandled */
-
-
-/**Function********************************************************************
-
- Synopsis [Resets a variable to be processed.]
-
- Description [Resets a variable to be processed. This function is used
- for lazy sifting.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddResetVarHandled(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(0);
- dd->subtables[dd->perm[index]].varHandled = 0;
- return(1);
-
-} /* end of ddResetVarHandled */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a variables is already handled.]
-
- Description [Checks whether a variables is already handled. This
- function is used for lazy sifting.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddIsVarHandled(
- DdManager *dd,
- int index)
-{
- if (index >= dd->size || index < 0) return(-1);
- return dd->subtables[dd->perm[index]].varHandled;
-
-} /* end of ddIsVarHandled */
diff --git a/src/bdd/cudd/cuddHarwell.c b/src/bdd/cudd/cuddHarwell.c
deleted file mode 100644
index 063f1922..00000000
--- a/src/bdd/cudd/cuddHarwell.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddHarwell.c]
-
- PackageName [cudd]
-
- Synopsis [Function to read a matrix in Harwell format.]
-
- Description [External procedures included in this module:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Reads in a matrix in the format of the Harwell-Boeing
- benchmark suite.]
-
- Description [Reads in a matrix in the format of the Harwell-Boeing
- benchmark suite. The variables are ordered as follows:
- <blockquote>
- x\[0\] y\[0\] x\[1\] y\[1\] ...
- </blockquote>
- 0 is the most significant bit. On input, nx and ny hold the numbers
- of row and column variables already in existence. On output, they
- hold the numbers of row and column variables actually used by the
- matrix. m and n are set to the numbers of rows and columns of the
- matrix. Their values on input are immaterial. Returns 1 on
- success; 0 otherwise. The ADD for the sparse matrix is returned in
- E, and its reference count is > 0.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addRead Cudd_bddRead]
-
-******************************************************************************/
-int
-Cudd_addHarwell(
- FILE * fp /* pointer to the input file */,
- DdManager * dd /* DD manager */,
- DdNode ** E /* characteristic function of the graph */,
- DdNode *** x /* array of row variables */,
- DdNode *** y /* array of column variables */,
- DdNode *** xn /* array of complemented row variables */,
- DdNode *** yn_ /* array of complemented column variables */,
- int * nx /* number or row variables */,
- int * ny /* number or column variables */,
- int * m /* number of rows */,
- int * n /* number of columns */,
- int bx /* first index of row variables */,
- int sx /* step of row variables */,
- int by /* first index of column variables */,
- int sy /* step of column variables */,
- int pr /* verbosity level */)
-{
- DdNode *one, *zero;
- DdNode *w;
- DdNode *cubex, *cubey, *minterm1;
- int u, v, err, i, j, nv;
- double val;
- 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;
- int *colptr, *rowind;
-#if 0
- int nguess, nexact;
- int *rhsptr, *rhsind;
-#endif
-
- if (*nx < 0 || *ny < 0) return(0);
-
- one = DD_ONE(dd);
- zero = DD_ZERO(dd);
-
- /* Read the header */
- err = fscanf(fp, "%72c %8c", title, key);
- if (err == EOF) {
- return(0);
- } else if (err != 2) {
- return(0);
- }
- title[72] = (char) 0;
- key[8] = (char) 0;
-
- err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd,
- &valcrd, &rhscrd);
- if (err == EOF) {
- return(0);
- } else if (err != 5) {
- return(0);
- }
-
- err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol,
- &nnzero, &neltvl);
- if (err == EOF) {
- return(0);
- } else if (err != 5) {
- return(0);
- }
-
- /* Skip FORTRAN formats */
- if (rhscrd == 0) {
- err = fscanf(fp, "%*s %*s %*s \n");
- } else {
- err = fscanf(fp, "%*s %*s %*s %*s \n");
- }
- if (err == EOF) {
- 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);
- }
-
- /* 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);
- }
- 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);
- } else {
- nrhs = 0;
- }
-
- /* Compute the number of variables */
-
- /* row and column numbers start from 0 */
- u = nrow - 1;
- for (i=0; u > 0; i++) {
- u >>= 1;
- }
- lnx = i;
- if (nrhs == 0) {
- v = ncol - 1;
- } else {
- v = 2* (ddMax(ncol, nrhs) - 1);
- }
- for (i=0; v > 0; i++) {
- v >>= 1;
- }
- lny = i;
-
- /* Allocate or reallocate arrays for variables as needed */
- if (*nx == 0) {
- if (lnx > 0) {
- *x = lx = ALLOC(DdNode *,lnx);
- if (lx == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *xn = lxn = ALLOC(DdNode *,lnx);
- if (lxn == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- } else {
- *x = *xn = NULL;
- }
- } else if (lnx > *nx) {
- *x = lx = REALLOC(DdNode *, *x, lnx);
- if (lx == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *xn = lxn = REALLOC(DdNode *, *xn, lnx);
- if (lxn == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- } else {
- lx = *x;
- lxn = *xn;
- }
- if (*ny == 0) {
- if (lny >0) {
- *y = ly = ALLOC(DdNode *,lny);
- if (ly == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *yn_ = lyn = ALLOC(DdNode *,lny);
- if (lyn == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- } else {
- *y = *yn_ = NULL;
- }
- } else if (lny > *ny) {
- *y = ly = REALLOC(DdNode *, *y, lny);
- if (ly == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *yn_ = lyn = REALLOC(DdNode *, *yn_, lny);
- if (lyn == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- } else {
- 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);
- cuddRef(lx[i]);
- 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]);
- }
-
- /* Update matrix parameters */
- *nx = lnx;
- *ny = lny;
- *m = nrow;
- if (nrhs == 0) {
- *n = ncol;
- } else {
- *n = (1 << (lny - 1)) + nrhs;
- }
-
- /* Read structure data */
- colptr = ALLOC(int, ncol+1);
- if (colptr == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- rowind = ALLOC(int, nnzero);
- if (rowind == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
-
- for (i=0; i<ncol+1; i++) {
- err = fscanf(fp, " %d ", &u);
- if (err == EOF){
- FREE(colptr);
- FREE(rowind);
- return(0);
- } else if (err != 1) {
- FREE(colptr);
- 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]);
- FREE(colptr);
- FREE(rowind);
- return(0);
- }
- for (i=0; i<nnzero; i++) {
- err = fscanf(fp, " %d ", &u);
- if (err == EOF){
- FREE(colptr);
- FREE(rowind);
- return(0);
- } else if (err != 1) {
- FREE(colptr);
- 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);
- FREE(colptr);
- 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);
- FREE(colptr);
- FREE(rowind);
- return(0);
- }
- /* Create new Constant node if necessary */
- cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
- if (cubex == NULL) {
- Cudd_RecursiveDeref(dd, cubey);
- FREE(colptr);
- 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);
- FREE(colptr);
- 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);
- FREE(colptr);
- 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);
- FREE(colptr);
- FREE(rowind);
- return(0);
- }
- cuddRef(w);
- Cudd_RecursiveDeref(dd, minterm1);
- Cudd_RecursiveDeref(dd, *E);
- *E = w;
- }
- Cudd_RecursiveDeref(dd, cubey);
- }
- FREE(colptr);
- 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) {
- 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;
- }
- Cudd_RecursiveDeref(dd, cubey);
- }
-
- return(1);
-
-} /* end of Cudd_addHarwell */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddInit.c b/src/bdd/cudd/cuddInit.c
deleted file mode 100644
index 8e06a425..00000000
--- a/src/bdd/cudd/cuddInit.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddInit.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#define CUDD_MAIN
-#include "cuddInt.h"
-#undef CUDD_MAIN
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Creates a new DD manager.]
-
- Description [Creates a new DD manager, initializes the table, the
- basic constants and the projection functions. If maxMemory is 0,
- Cudd_Init decides suitable values for the maximum size of the cache
- and for the limit for fast unique table growth based on the available
- memory. Returns a pointer to the manager if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Quit]
-
-******************************************************************************/
-DdManager *
-Cudd_Init(
- unsigned int numVars /* initial number of BDD variables (i.e., subtables) */,
- unsigned int numVarsZ /* initial number of ZDD variables (i.e., subtables) */,
- unsigned int numSlots /* initial size of the unique tables */,
- unsigned int cacheSize /* initial size of the cache */,
- unsigned long maxMemory /* target maximum memory occupation */)
-{
- DdManager *unique;
- int i,result;
- DdNode *one, *zero;
- unsigned int maxCacheSize;
- unsigned int looseUpTo;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- if (maxMemory == 0) {
- maxMemory = getSoftDataLimit();
- }
- looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) /
- DD_MAX_LOOSE_FRACTION);
- unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo);
- unique->maxmem = (unsigned) maxMemory / 10 * 9;
- if (unique == NULL) return(NULL);
- maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) /
- DD_MAX_CACHE_FRACTION);
- result = cuddInitCache(unique,cacheSize,maxCacheSize);
- if (result == 0) return(NULL);
-
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4);
- MMoutOfMemory = saveHandler;
- if (unique->stash == NULL) {
- (void) fprintf(unique->err,"Unable to set aside memory\n");
- }
-
- /* Initialize constants. */
- unique->one = cuddUniqueConst(unique,1.0);
- if (unique->one == NULL) return(0);
- cuddRef(unique->one);
- unique->zero = cuddUniqueConst(unique,0.0);
- if (unique->zero == NULL) return(0);
- 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");
- }
-#endif
- unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL);
- if (unique->plusinfinity == NULL) return(0);
- cuddRef(unique->plusinfinity);
- unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL);
- if (unique->minusinfinity == NULL) return(0);
- cuddRef(unique->minusinfinity);
- unique->background = unique->zero;
-
- /* The logical zero is different from the CUDD_VALUE_TYPE zero! */
- one = unique->one;
- zero = Cudd_Not(one);
- /* Create the projection functions. */
- unique->vars = ALLOC(DdNodePtr,unique->maxSize);
- if (unique->vars == 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]);
- }
-
- if (unique->sizeZ)
- cuddZddInitUniv(unique);
-
- unique->memused += sizeof(DdNode *) * unique->maxSize;
-
- return(unique);
-
-} /* end of Cudd_Init */
-
-
-/**Function********************************************************************
-
- Synopsis [Deletes resources associated with a DD manager.]
-
- Description [Deletes resources associated with a DD manager and
- resets the global statistical counters. (Otherwise, another manaqger
- subsequently created would inherit the stats of this one.)]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Init]
-
-******************************************************************************/
-void
-Cudd_Quit(
- DdManager * unique)
-{
- if (unique->stash != NULL) FREE(unique->stash);
- cuddFreeTable(unique);
-
-} /* end of Cudd_Quit */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes the ZDD universe.]
-
- Description [Initializes the ZDD universe. Returns 1 if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddFreeUniv]
-
-******************************************************************************/
-int
-cuddZddInitUniv(
- DdManager * zdd)
-{
- DdNode *p, *res;
- int i;
-
- zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ);
- if (zdd->univ == NULL) {
- 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);
- FREE(zdd->univ);
- return(0);
- }
- cuddRef(res);
- cuddDeref(p);
- zdd->univ[i] = res;
- }
-
-#ifdef DD_VERBOSE
- cuddZddP(zdd, zdd->univ[0]);
-#endif
-
- return(1);
-
-} /* end of cuddZddInitUniv */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the ZDD universe.]
-
- Description [Frees the ZDD universe.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddInitUniv]
-
-******************************************************************************/
-void
-cuddZddFreeUniv(
- DdManager * zdd)
-{
- if (zdd->univ) {
- Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
- FREE(zdd->univ);
- }
-
-} /* end of cuddZddFreeUniv */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddInt.h b/src/bdd/cudd/cuddInt.h
deleted file mode 100644
index a5d0cf16..00000000
--- a/src/bdd/cudd/cuddInt.h
+++ /dev/null
@@ -1,1133 +0,0 @@
-/**CHeaderFile*****************************************************************
-
- FileName [cuddInt.h]
-
- PackageName [cudd]
-
- Synopsis [Internal data structures of the CUDD package.]
-
- Description []
-
- 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.]
-
- Revision [$Id: cuddInt.h,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $]
-
-******************************************************************************/
-
-#ifndef _CUDDINT
-#define _CUDDINT
-
-
-/*---------------------------------------------------------------------------*/
-/* Nested includes */
-/*---------------------------------------------------------------------------*/
-
-#ifdef DD_MIS
-#include "array.h"
-#include "list.h"
-#include "st.h"
-#include "espresso.h"
-#include "node.h"
-#ifdef SIS
-#include "graph.h"
-#include "astg.h"
-#endif
-#include "network.h"
-#endif
-
-#include <math.h>
-#include "cudd.h"
-#include "st.h"
-
-#if defined(__GNUC__)
-# define DD_INLINE __inline__
-# if (__GNUC__ >2 || __GNUC_MINOR__ >=7)
-# define DD_UNUSED __attribute__ ((__unused__))
-# else
-# define DD_UNUSED
-# endif
-#else
-# if defined(__cplusplus)
-# define DD_INLINE inline
-# else
-# define DD_INLINE
-# endif
-# define DD_UNUSED
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_MAXREF ((DdHalfWord) ~0)
-
-#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)
-
-/* 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)
-#else
-# 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_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 */
-/* 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_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 */
-
-/* Primes for cache hash functions. */
-#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
-** the following scheme. The tag consists of two hex digits. Both digits
-** must be even, so that they do not interfere with complementation bits.
-** The least significant one is stored in Bits 3:1 of the f operand in the
-** cache entry. Bit 1 is always 1, so that we can differentiate
-** three-operand operations from one- and two-operand operations.
-** Therefore, the least significant digit is one of {2,6,a,e}. The most
-** significant digit occupies Bits 3:1 of the g operand in the cache
-** 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
-
-/* Generator constants. */
-#define CUDD_GEN_CUBES 0
-#define CUDD_GEN_NODES 1
-#define CUDD_GEN_ZDD_PATHS 2
-#define CUDD_GEN_EMPTY 0
-#define CUDD_GEN_NONEMPTY 1
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-struct DdGen {
- DdManager *manager;
- int type;
- int status;
- union {
- struct {
- int *cube;
- CUDD_VALUE_TYPE value;
- } cubes;
- struct {
- st_table *visited;
- st_generator *stGen;
- } nodes;
- } gen;
- struct {
- int sp;
- DdNode **stack;
- } stack;
- DdNode *node;
-};
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Hooks in CUDD are functions that the application registers with the
-** manager so that they are called at appropriate times. The functions
-** 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 */
-} DdHook;
-
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
-typedef long ptrint;
-typedef unsigned long ptruint;
-#else
-typedef int ptrint;
-typedef unsigned int ptruint;
-#endif
-
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
-
-typedef DdNode *DdNodePtr;
-
-/* Generic local cache item. */
-typedef struct DdLocalCacheItem {
- DdNode *value;
-#ifdef DD_CACHE_PROFILE
- ptrint count;
-#endif
- DdNode *key[1];
-} DdLocalCacheItem;
-
-/* Local cache. */
-typedef struct DdLocalCache {
- DdLocalCacheItem *item;
- unsigned int itemsize;
- unsigned int keysize;
- unsigned int slots;
- int shift;
- double lookUps;
- double minHit;
- double hits;
- unsigned int maxslots;
- DdManager *manager;
- struct DdLocalCache *next;
-} DdLocalCache;
-
-/* Generic hash item. */
-typedef struct DdHashItem {
- struct DdHashItem *next;
- ptrint count;
- DdNode *value;
- DdNode *key[1];
-} DdHashItem;
-
-/* Local hash table */
-typedef struct DdHashTable {
- unsigned int keysize;
- unsigned int itemsize;
- DdHashItem **bucket;
- DdHashItem *nextFree;
- DdHashItem **memoryList;
- unsigned int numBuckets;
- int shift;
- unsigned int size;
- unsigned int maxsize;
- DdManager *manager;
-} DdHashTable;
-
-typedef struct DdCache {
- 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 */
- /* 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 */
- Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */
-} DdSubtable;
-
-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 */
- /* 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 */
- /* 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 */
- /* Memory Management */
- 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 */
-#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) */
- 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) */
- 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 */
-#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 */
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- 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 */
- double cacheLastInserts; /* insertions at the last cache resizing */
- 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 */
-#endif
- 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 */
-#endif
-#ifdef DD_COUNT
- double recursiveCalls; /* number of recursive calls */
-#ifdef DD_STATS
- double nextSample; /* when to write next line of stats */
-#endif
- 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 *order; /* copy of order_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*/
-#endif
-};
-
-typedef struct Move {
- DdHalfWord x;
- DdHalfWord y;
- unsigned int flags;
- int size;
- struct Move *next;
-} Move;
-
-/* Generic level queue item. */
-typedef struct DdQueueItem {
- struct DdQueueItem *next;
- struct DdQueueItem *cnext;
- void *key;
-} DdQueueItem;
-
-/* Level queue. */
-typedef struct DdLevelQueue {
- void *first;
- DdQueueItem **last;
- DdQueueItem *freelist;
- DdQueueItem **buckets;
- int levels;
- int itemsize;
- int size;
- int maxsize;
- int numBuckets;
- int shift;
-} DdLevelQueue;
-
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**Macro***********************************************************************
-
- Synopsis [Adds node to the head of the free list.]
-
- Description [Adds node to the head of the free list. Does not
- deallocate memory chunks that become free. This function is also
- used by the dynamic reordering functions.]
-
- SideEffects [None]
-
- SeeAlso [cuddAllocNode cuddDynamicAllocNode]
-
-******************************************************************************/
-#define cuddDeallocNode(unique,node) \
- (node)->next = (unique)->nextFree; \
- (unique)->nextFree = node;
-
-
-/**Macro***********************************************************************
-
- Synopsis [Increases the reference count of a node, if it is not
- saturated.]
-
- Description [Increases the reference count of a node, if it is not
- saturated. This being a macro, it is faster than Cudd_Ref, but it
- cannot be used in constructs like cuddRef(a = b()).]
-
- SideEffects [none]
-
- SeeAlso [Cudd_Ref]
-
-******************************************************************************/
-#define cuddRef(n) cuddSatInc(Cudd_Regular(n)->ref)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Decreases the reference count of a node, if it is not
- saturated.]
-
- Description [Decreases the reference count of node. It is primarily
- used in recursive procedures to decrease the ref count of a result
- node before returning it. This accomplishes the goal of removing the
- protection applied by a previous cuddRef. This being a macro, it is
- faster than Cudd_Deref, but it cannot be used in constructs like
- cuddDeref(a = b()).]
-
- SideEffects [none]
-
- SeeAlso [Cudd_Deref]
-
-******************************************************************************/
-#define cuddDeref(n) cuddSatDec(Cudd_Regular(n)->ref)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns 1 if the node is a constant node.]
-
- Description [Returns 1 if the node is a constant node (rather than an
- internal node). All constant nodes have the same index
- (CUDD_CONST_INDEX). The pointer passed to cuddIsConstant must be regular.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_IsConstant]
-
-******************************************************************************/
-#define cuddIsConstant(node) ((node)->index == CUDD_CONST_INDEX)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the then child of an internal node.]
-
- Description [Returns the then child of an internal node. If
- <code>node</code> is a constant node, the result is unpredictable.
- The pointer passed to cuddT must be regular.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_T]
-
-******************************************************************************/
-#define cuddT(node) ((node)->type.kids.T)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the else child of an internal node.]
-
- Description [Returns the else child of an internal node. If
- <code>node</code> is a constant node, the result is unpredictable.
- The pointer passed to cuddE must be regular.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_E]
-
-******************************************************************************/
-#define cuddE(node) ((node)->type.kids.E)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the value of a constant node.]
-
- Description [Returns the value of a constant node. If
- <code>node</code> is an internal node, the result is unpredictable.
- The pointer passed to cuddV must be regular.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_V]
-
-******************************************************************************/
-#define cuddV(node) ((node)->type.value)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Finds the current position of variable index in the
- order.]
-
- Description [Finds the current position of variable index in the
- order. This macro duplicates the functionality of Cudd_ReadPerm,
- but it does not check for out-of-bounds indices and it is more
- efficient.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ReadPerm]
-
-******************************************************************************/
-#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)])
-
-
-/**Macro***********************************************************************
-
- Synopsis [Finds the current position of ZDD variable index in the
- order.]
-
- Description [Finds the current position of ZDD variable index in the
- order. This macro duplicates the functionality of Cudd_ReadPermZdd,
- but it does not check for out-of-bounds indices and it is more
- efficient.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_ReadPermZdd]
-
-******************************************************************************/
-#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)])
-
-
-/**Macro***********************************************************************
-
- Synopsis [Hash function for the unique table.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [ddCHash ddCHash2]
-
-******************************************************************************/
-#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))
-#else
-#define ddHash(f,g,s) \
-((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Hash function for the cache.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [ddHash ddCHash2]
-
-******************************************************************************/
-#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))
-#else
-#define ddCHash(o,f,g,h,s) \
-((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \
- (unsigned)(h)) * DD_P3) >> (s))
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Hash function for the cache for functions with two
- operands.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [ddHash ddCHash]
-
-******************************************************************************/
-#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))
-#else
-#define ddCHash2(o,f,g,s) \
-(((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Clears the 4 least significant bits of a pointer.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-#define cuddClean(p) ((DdNode *)((ptruint)(p) & ~0xf))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Computes the minimum of two numbers.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [ddMax]
-
-******************************************************************************/
-#define ddMin(x,y) (((y) < (x)) ? (y) : (x))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Computes the maximum of two numbers.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [ddMin]
-
-******************************************************************************/
-#define ddMax(x,y) (((y) > (x)) ? (y) : (x))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Computes the absolute value of a number.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-#define ddAbs(x) (((x)<0) ? -(x) : (x))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns 1 if the absolute value of the difference of the two
- arguments x and y is less than e.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-#define ddEqualVal(x,y,e) (ddAbs((x)-(y))<(e))
-
-
-/**Macro***********************************************************************
-
- Synopsis [Saturating increment operator.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [cuddSatDec]
-
-******************************************************************************/
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
-#define cuddSatInc(x) ((x)++)
-#else
-#define cuddSatInc(x) ((x) += (x) != (DdHalfWord)DD_MAXREF)
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Saturating decrement operator.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [cuddSatInc]
-
-******************************************************************************/
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
-#define cuddSatDec(x) ((x)--)
-#else
-#define cuddSatDec(x) ((x) -= (x) != (DdHalfWord)DD_MAXREF)
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the constant 1 node.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY]
-
-******************************************************************************/
-#define DD_ONE(dd) ((dd)->one)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the arithmetic 0 constant node.]
-
- Description [Returns the arithmetic 0 constant node. This is different
- from the logical zero. The latter is obtained by
- Cudd_Not(DD_ONE(dd)).]
-
- SideEffects [none]
-
- SeeAlso [DD_ONE Cudd_Not DD_PLUS_INFINITY DD_MINUS_INFINITY]
-
-******************************************************************************/
-#define DD_ZERO(dd) ((dd)->zero)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the plus infinity constant node.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [DD_ONE DD_ZERO DD_MINUS_INFINITY]
-
-******************************************************************************/
-#define DD_PLUS_INFINITY(dd) ((dd)->plusinfinity)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Returns the minus infinity constant node.]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [DD_ONE DD_ZERO DD_PLUS_INFINITY]
-
-******************************************************************************/
-#define DD_MINUS_INFINITY(dd) ((dd)->minusinfinity)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.]
-
- Description [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.
- Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to
- DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to
- DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if
- HAVE_IEEE_754 is not defined, it makes sure that a value does not
- get larger than infinity in absolute value, and once it gets to
- infinity, stays there. If the value overflows before this macro is
- applied, no recovery is possible.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-#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)))
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Extract the least significant digit of a double digit.]
-
- Description [Extract the least significant digit of a double digit. Used
- in the manipulation of arbitrary precision integers.]
-
- SideEffects [None]
-
- SeeAlso [DD_MSDIGIT]
-
-******************************************************************************/
-#define DD_LSDIGIT(x) ((x) & DD_APA_MASK)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Extract the most significant digit of a double digit.]
-
- Description [Extract the most significant digit of a double digit. Used
- in the manipulation of arbitrary precision integers.]
-
- SideEffects [None]
-
- SeeAlso [DD_LSDIGIT]
-
-******************************************************************************/
-#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS)
-
-
-/**Macro***********************************************************************
-
- Synopsis [Outputs a line of stats.]
-
- Description [Outputs a line of stats if DD_COUNT and DD_STATS are
- defined. Increments the number of recursive calls if DD_COUNT is
- defined.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-#ifdef DD_COUNT
-#ifdef DD_STATS
-#define statLine(dd) dd->recursiveCalls++; \
-if (dd->recursiveCalls == dd->nextSample) {(void) fprintf(dd->err, \
-"@%.0f: %u nodes %u live %.0f dropped %.0f reclaimed\n", dd->recursiveCalls, \
-dd->keys, dd->keys - dd->dead, dd->nodesDropped, dd->reclaimed); \
-dd->nextSample += 250000;}
-#else
-#define statLine(dd) dd->recursiveCalls++;
-#endif
-#else
-#define statLine(dd)
-#endif
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-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));
-#ifdef DD_CACHE_PROFILE
-EXTERN int cuddLocalCacheProfile ARGS((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));
-#ifdef ST_INCLUDED
-EXTERN DdNode* cuddSplitSetRecur ARGS((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));
-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));
-#ifdef ST_INCLUDED
-EXTERN enum st_retval cuddStCountfree ARGS((char *key, char *value, char *arg));
-EXTERN int cuddCollectNodes ARGS((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));
-
-/**AutomaticEnd***************************************************************/
-
-#endif /* _CUDDINT */
diff --git a/src/bdd/cudd/cuddInteract.c b/src/bdd/cudd/cuddInteract.c
deleted file mode 100644
index 96613639..00000000
--- a/src/bdd/cudd/cuddInteract.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddInteract.c]
-
- PackageName [cudd]
-
- Synopsis [Functions to manipulate the variable interaction matrix.]
-
- Description [Internal procedures included in this file:
- <ul>
- <li> cuddSetInteract()
- <li> cuddTestInteract()
- <li> cuddInitInteract()
- </ul>
- Static procedures included in this file:
- <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
- variables do not interact, there is no arc connecting the two layers;
- therefore, the swap can be performed in constant time, without
- scanning the subtables. Another use of the interaction matrix is in
- the computation of the lower bounds for sifting. Finally, the
- interaction matrix can be used to speed up aggregation checks in
- symmetric and group sifting.<p>
- The computation of the interaction matrix is done with a series of
- depth-first searches. The searches start from those nodes that have
- only external references. The matrix is stored as a packed array of bits;
- since it is symmetric, only the upper triangle is kept in memory.
- As a final remark, we note that there may be variables that do
- intercat, but that for a given variable order have no arc connecting
- their layers when they are adjacent.]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#if SIZEOF_LONG == 8
-#define BPL 64
-#define LOGBPL 6
-#else
-#define BPL 32
-#define LOGBPL 5
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Set interaction matrix entries.]
-
- Description [Given a pair of variables 0 <= x < y < table->size,
- sets the corresponding bit of the interaction matrix to 1.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddSetInteract(
- DdManager * table,
- int x,
- int y)
-{
- int posn, word, bit;
-
-#ifdef DD_DEBUG
- assert(x < y);
- assert(y < table->size);
- assert(x >= 0);
-#endif
-
- posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
- word = posn >> LOGBPL;
- bit = posn & (BPL-1);
- table->interact[word] |= 1L << bit;
-
-} /* end of cuddSetInteract */
-
-
-/**Function********************************************************************
-
- Synopsis [Test interaction matrix entries.]
-
- Description [Given a pair of variables 0 <= x < y < table->size,
- tests whether the corresponding bit of the interaction matrix is 1.
- Returns the value of the bit.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddTestInteract(
- DdManager * table,
- int x,
- int y)
-{
- int posn, word, bit, result;
-
- if (x > y) {
- int tmp = x;
- x = y;
- y = tmp;
- }
-#ifdef DD_DEBUG
- assert(x < y);
- assert(y < table->size);
- assert(x >= 0);
-#endif
-
- posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
- word = posn >> LOGBPL;
- bit = posn & (BPL-1);
- result = (table->interact[word] >> bit) & 1L;
- return(result);
-
-} /* end of cuddTestInteract */
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes the interaction matrix.]
-
- Description [Initializes the interaction matrix. The interaction
- matrix is implemented as a bit vector storing the upper triangle of
- the symmetric interaction matrix. The bit vector is kept in an array
- of long integers. The computation is based on a series of depth-first
- searches, one for each root of the DAG. Two flags are needed: The
- local visited flag uses the LSB of the then pointer. The global
- visited flag uses the LSB of the next pointer.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddInitInteract(
- DdManager * table)
-{
- int i,j,k;
- int words;
- long *interact;
- int *support;
- DdNode *f;
- DdNode *sentinel = &(table->sentinel);
- DdNodePtr *nodelist;
- int slots;
- int n = table->size;
-
- words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
- table->interact = interact = ALLOC(long,words);
- if (interact == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (i = 0; i < words; i++) {
- interact[i] = 0;
- }
-
- support = ALLOC(int,n);
- if (support == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- 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;
- }
- ddSuppInteract(f,support);
- ddClearLocal(f);
- ddUpdateInteract(table,support);
- }
- f = Cudd_Regular(f->next);
- }
- }
- }
- ddClearGlobal(table);
-
- FREE(support);
- return(1);
-
-} /* end of cuddInitInteract */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Find the support of f.]
-
- Description [Performs a DFS from f. Uses the LSB of the then pointer
- as visited flag.]
-
- SideEffects [Accumulates in support the variables on which f depends.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddSuppInteract(
- DdNode * f,
- int * support)
-{
- if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) {
- return;
- }
-
- support[f->index] = 1;
- ddSuppInteract(cuddT(f),support);
- ddSuppInteract(Cudd_Regular(cuddE(f)),support);
- /* mark as visited */
- cuddT(f) = Cudd_Complement(cuddT(f));
- f->next = Cudd_Complement(f->next);
- return;
-
-} /* end of ddSuppInteract */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddClearLocal(
- DdNode * f)
-{
- if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) {
- return;
- }
- /* clear visited flag */
- cuddT(f) = Cudd_Regular(cuddT(f));
- ddClearLocal(cuddT(f));
- ddClearLocal(Cudd_Regular(cuddE(f)));
- return;
-
-} /* end of ddClearLocal */
-
-
-/**Function********************************************************************
-
- Synopsis [Marks as interacting all pairs of variables that appear in
- support.]
-
- Description [If support[i] == support[j] == 1, sets the (i,j) entry
- of the interaction matrix to 1.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddUpdateInteract(
- DdManager * table,
- int * support)
-{
- int i,j;
- 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);
- }
- }
- }
- }
-
-} /* end of ddUpdateInteract */
-
-
-/**Function********************************************************************
-
- Synopsis [Scans the DD and clears the LSB of the next pointers.]
-
- Description [The LSB of the next pointers are used as markers to tell
- whether a node was reached by at least one DFS. Once the interaction
- matrix is built, these flags are reset.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddClearGlobal(
- DdManager * table)
-{
- int i,j;
- DdNode *f;
- DdNode *sentinel = &(table->sentinel);
- DdNodePtr *nodelist;
- 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;
- }
- }
- }
-
-} /* end of ddClearGlobal */
-
diff --git a/src/bdd/cudd/cuddLCache.c b/src/bdd/cudd/cuddLCache.c
deleted file mode 100644
index 8bd37ba0..00000000
--- a/src/bdd/cudd/cuddLCache.c
+++ /dev/null
@@ -1,1428 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddLCache.c]
-
- PackageName [cudd]
-
- 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> ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**Macro***********************************************************************
-
- Synopsis [Computes hash function for keys of two operands.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [ddLCHash3 ddLCHash]
-
-******************************************************************************/
-#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))
-#else
-#define ddLCHash2(f,g,shift) \
-((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
-#endif
-
-
-/**Macro***********************************************************************
-
- Synopsis [Computes hash function for keys of three operands.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [ddLCHash2 ddLCHash]
-
-******************************************************************************/
-#define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift)
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes a local computed table.]
-
- Description [Initializes a computed table. Returns a pointer the
- the new local cache in case of success; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddInitCache]
-
-******************************************************************************/
-DdLocalCache *
-cuddLocalCacheInit(
- DdManager * manager /* manager */,
- unsigned int keySize /* size of the key (number of operands) */,
- unsigned int cacheSize /* Initial size of the cache */,
- unsigned int maxCacheSize /* Size of the cache beyond which no resizing occurs */)
-{
- DdLocalCache *cache;
- int logSize;
-
- cache = ALLOC(DdLocalCache,1);
- if (cache == NULL) {
- manager->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- cache->manager = manager;
- cache->keysize = keySize;
- cache->itemsize = (keySize + 1) * sizeof(DdNode *);
-#ifdef DD_CACHE_PROFILE
- cache->itemsize += sizeof(ptrint);
-#endif
- logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
- cacheSize = 1 << logSize;
- cache->item = (DdLocalCacheItem *)
- ALLOC(char, cacheSize * cache->itemsize);
- if (cache->item == NULL) {
- manager->errorCode = CUDD_MEMORY_OUT;
- FREE(cache);
- return(NULL);
- }
- cache->slots = cacheSize;
- cache->shift = sizeof(int) * 8 - logSize;
- cache->maxslots = ddMin(maxCacheSize,manager->slots);
- cache->minHit = manager->minHit;
- /* Initialize to avoid division by 0 and immediate resizing. */
- cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1);
- cache->hits = 0;
- manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache);
-
- /* Initialize the cache. */
- memset(cache->item, 0, cacheSize * cache->itemsize);
-
- /* Add to manager's list of local caches for GC. */
- cuddLocalCacheAddToList(cache);
-
- return(cache);
-
-} /* end of cuddLocalCacheInit */
-
-
-/**Function********************************************************************
-
- Synopsis [Shuts down a local computed table.]
-
- Description [Initializes the computed table. It is called by
- Cudd_Init. Returns a pointer the the new local cache in case of
- success; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddLocalCacheInit]
-
-******************************************************************************/
-void
-cuddLocalCacheQuit(
- DdLocalCache * cache /* cache to be shut down */)
-{
- cache->manager->memused -=
- cache->slots * cache->itemsize + sizeof(DdLocalCache);
- cuddLocalCacheRemoveFromList(cache);
- FREE(cache->item);
- FREE(cache);
-
- return;
-
-} /* end of cuddLocalCacheQuit */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a result in a local cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddLocalCacheInsert(
- DdLocalCache * cache,
- DdNodePtr * key,
- DdNode * value)
-{
- unsigned int posn;
- DdLocalCacheItem *entry;
-
- posn = ddLCHash(key,cache->keysize,cache->shift);
- entry = (DdLocalCacheItem *) ((char *) cache->item +
- posn * cache->itemsize);
- memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
- entry->value = value;
-#ifdef DD_CACHE_PROFILE
- entry->count++;
-#endif
-
-} /* end of cuddLocalCacheInsert */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up in a local cache.]
-
- Description [Looks up in a local cache. Returns the result if found;
- it returns NULL if no result is found.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddLocalCacheLookup(
- DdLocalCache * cache,
- DdNodePtr * key)
-{
- unsigned int posn;
- DdLocalCacheItem *entry;
- DdNode *value;
-
- cache->lookUps++;
- posn = ddLCHash(key,cache->keysize,cache->shift);
- entry = (DdLocalCacheItem *) ((char *) cache->item +
- 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);
- }
-
- /* Cache miss: decide whether to resize */
-
- if (cache->slots < cache->maxslots &&
- cache->hits > cache->lookUps * cache->minHit) {
- cuddLocalCacheResize(cache);
- }
-
- return(NULL);
-
-} /* end of cuddLocalCacheLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Clears the dead entries of the local caches of a manager.]
-
- Description [Clears the dead entries of the local caches of a manager.
- Used during garbage collection.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddLocalCacheClearDead(
- DdManager * manager)
-{
- DdLocalCache *cache = manager->localCaches;
- unsigned int keysize;
- unsigned int itemsize;
- unsigned int slots;
- DdLocalCacheItem *item;
- DdNodePtr *key;
- 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;
- }
- }
- }
- item = (DdLocalCacheItem *) ((char *) item + itemsize);
- }
- cache = cache->next;
- }
- return;
-
-} /* end of cuddLocalCacheClearDead */
-
-
-/**Function********************************************************************
-
- Synopsis [Clears the local caches of a manager.]
-
- Description [Clears the local caches of a manager.
- Used before reordering.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddLocalCacheClearAll(
- DdManager * manager)
-{
- DdLocalCache *cache = manager->localCaches;
-
- while (cache != NULL) {
- memset(cache->item, 0, cache->slots * cache->itemsize);
- cache = cache->next;
- }
- return;
-
-} /* end of cuddLocalCacheClearAll */
-
-
-#ifdef DD_CACHE_PROFILE
-
-#define DD_HYSTO_BINS 8
-
-/**Function********************************************************************
-
- Synopsis [Computes and prints a profile of a local cache usage.]
-
- Description [Computes and prints a profile of a local cache usage.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddLocalCacheProfile(
- DdLocalCache * cache)
-{
- double count, mean, meansq, stddev, expected;
- long max, min;
- int imax, imin;
- int i, retval, slots;
- long *hystogram;
- int nbins = DD_HYSTO_BINS;
- int bin;
- long thiscount;
- double totalcount;
- int nzeroes;
- DdLocalCacheItem *entry;
- FILE *fp = cache->manager->out;
-
- slots = cache->slots;
-
- meansq = mean = expected = 0.0;
- max = min = (long) cache->item[0].count;
- imax = imin = nzeroes = 0;
- totalcount = 0.0;
-
- hystogram = ALLOC(long, nbins);
- if (hystogram == NULL) {
- return(0);
- }
- for (i = 0; i < nbins; i++) {
- 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;
- }
- mean /= (double) slots;
- meansq /= (double) slots;
- stddev = sqrt(meansq - mean*mean);
-
- retval = fprintf(fp,"Cache stats: slots = %d average = %g ", slots, mean);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"standard deviation = %g\n", stddev);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
- if (retval == EOF) return(0);
- retval = fprintf(fp,"Cache unused slots = %d\n", nzeroes);
- 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]);
- if (retval == EOF) return(0);
- }
- retval = fprintf(fp,"\n");
- if (retval == EOF) return(0);
- }
-
- FREE(hystogram);
- return(1);
-
-} /* end of cuddLocalCacheProfile */
-#endif
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes a hash table.]
-
- Description [Initializes a hash table. Returns a pointer to the new
- table if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableQuit]
-
-******************************************************************************/
-DdHashTable *
-cuddHashTableInit(
- DdManager * manager,
- unsigned int keySize,
- unsigned int initSize)
-{
- DdHashTable *hash;
- int logSize;
-
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- hash = ALLOC(DdHashTable, 1);
- if (hash == 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 *);
- /* We have to guarantee that the shift be < 32. */
- if (initSize < 2) initSize = 2;
- logSize = cuddComputeFloorLog2(initSize);
- hash->numBuckets = 1 << logSize;
- hash->shift = sizeof(int) * 8 - logSize;
- hash->bucket = ALLOC(DdHashItem *, hash->numBuckets);
- if (hash->bucket == NULL) {
- manager->errorCode = CUDD_MEMORY_OUT;
- FREE(hash);
- return(NULL);
- }
- memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
- hash->size = 0;
- hash->maxsize = hash->numBuckets * DD_MAX_HASHTABLE_DENSITY;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- return(hash);
-
-} /* end of cuddHashTableInit */
-
-
-/**Function********************************************************************
-
- Synopsis [Shuts down a hash table.]
-
- Description [Shuts down a hash table, dereferencing all the values.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableInit]
-
-******************************************************************************/
-void
-cuddHashTableQuit(
- DdHashTable * hash)
-{
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- unsigned int i;
- DdManager *dd = hash->manager;
- DdHashItem *bucket;
- DdHashItem **memlist, **nextmem;
- 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;
- }
- }
-
- memlist = hash->memoryList;
- while (memlist != NULL) {
- nextmem = (DdHashItem **) memlist[0];
- FREE(memlist);
- memlist = nextmem;
- }
-
- FREE(hash->bucket);
- FREE(hash);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-
- return;
-
-} /* end of cuddHashTableQuit */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts an item in a hash table.]
-
- Description [Inserts an item in a hash table when the key has more than
- three pointers. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3
- cuddHashTableLookup]
-
-******************************************************************************/
-int
-cuddHashTableInsert(
- DdHashTable * hash,
- DdNodePtr * key,
- DdNode * value,
- ptrint count)
-{
- int result;
- unsigned int posn;
- DdHashItem *item;
- unsigned int i;
-
-#ifdef DD_DEBUG
- assert(hash->keysize > 3);
-#endif
-
- if (hash->size > hash->maxsize) {
- result = cuddHashTableResize(hash);
- if (result == 0) return(0);
- }
- item = cuddHashTableAlloc(hash);
- if (item == NULL) return(0);
- hash->size++;
- item->value = value;
- cuddRef(value);
- item->count = count;
- for (i = 0; i < hash->keysize; i++) {
- item->key[i] = key[i];
- }
- posn = ddLCHash(key,hash->keysize,hash->shift);
- item->next = hash->bucket[posn];
- hash->bucket[posn] = item;
-
- return(1);
-
-} /* end of cuddHashTableInsert */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up a key in a hash table.]
-
- Description [Looks up a key consisting of more than three pointers
- in a hash table. Returns the value associated to the key if there
- is an entry for the given key in the table; NULL otherwise. If the
- entry is present, its reference counter is decremented if not
- saturated. If the counter reaches 0, the value of the entry is
- dereferenced, and the entry is returned to the free list.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3
- cuddHashTableInsert]
-
-******************************************************************************/
-DdNode *
-cuddHashTableLookup(
- DdHashTable * hash,
- DdNodePtr * key)
-{
- unsigned int posn;
- DdHashItem *item, *prev;
- unsigned int i, keysize;
-
-#ifdef DD_DEBUG
- assert(hash->keysize > 3);
-#endif
-
- posn = ddLCHash(key,hash->keysize,hash->shift);
- item = hash->bucket[posn];
- prev = NULL;
-
- 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;
- }
- item->next = hash->nextFree;
- hash->nextFree = item;
- hash->size--;
- }
- return(value);
- }
- prev = item;
- item = item->next;
- }
- return(NULL);
-
-} /* end of cuddHashTableLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts an item in a hash table.]
-
- Description [Inserts an item in a hash table when the key is one pointer.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3
- cuddHashTableLookup1]
-
-******************************************************************************/
-int
-cuddHashTableInsert1(
- DdHashTable * hash,
- DdNode * f,
- DdNode * value,
- ptrint count)
-{
- int result;
- unsigned int posn;
- DdHashItem *item;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 1);
-#endif
-
- if (hash->size > hash->maxsize) {
- result = cuddHashTableResize(hash);
- if (result == 0) return(0);
- }
- item = cuddHashTableAlloc(hash);
- if (item == NULL) return(0);
- hash->size++;
- item->value = value;
- cuddRef(value);
- item->count = count;
- item->key[0] = f;
- posn = ddLCHash2(f,f,hash->shift);
- item->next = hash->bucket[posn];
- hash->bucket[posn] = item;
-
- return(1);
-
-} /* end of cuddHashTableInsert1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up a key consisting of one pointer in a hash table.]
-
- Description [Looks up a key consisting of one pointer in a hash table.
- Returns the value associated to the key if there is an entry for the given
- key in the table; NULL otherwise. If the entry is present, its reference
- counter is decremented if not saturated. If the counter reaches 0, the
- value of the entry is dereferenced, and the entry is returned to the free
- list.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3
- cuddHashTableInsert1]
-
-******************************************************************************/
-DdNode *
-cuddHashTableLookup1(
- DdHashTable * hash,
- DdNode * f)
-{
- unsigned int posn;
- DdHashItem *item, *prev;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 1);
-#endif
-
- posn = ddLCHash2(f,f,hash->shift);
- item = hash->bucket[posn];
- 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--;
- }
- return(value);
- }
- prev = item;
- item = item->next;
- }
- return(NULL);
-
-} /* end of cuddHashTableLookup1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts an item in a hash table.]
-
- Description [Inserts an item in a hash table when the key is
- composed of two pointers. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3
- cuddHashTableLookup2]
-
-******************************************************************************/
-int
-cuddHashTableInsert2(
- DdHashTable * hash,
- DdNode * f,
- DdNode * g,
- DdNode * value,
- ptrint count)
-{
- int result;
- unsigned int posn;
- DdHashItem *item;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 2);
-#endif
-
- if (hash->size > hash->maxsize) {
- result = cuddHashTableResize(hash);
- if (result == 0) return(0);
- }
- item = cuddHashTableAlloc(hash);
- if (item == NULL) return(0);
- hash->size++;
- item->value = value;
- cuddRef(value);
- item->count = count;
- item->key[0] = f;
- item->key[1] = g;
- posn = ddLCHash2(f,g,hash->shift);
- item->next = hash->bucket[posn];
- hash->bucket[posn] = item;
-
- return(1);
-
-} /* end of cuddHashTableInsert2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up a key consisting of two pointers in a hash table.]
-
- Description [Looks up a key consisting of two pointer in a hash table.
- Returns the value associated to the key if there is an entry for the given
- key in the table; NULL otherwise. If the entry is present, its reference
- counter is decremented if not saturated. If the counter reaches 0, the
- value of the entry is dereferenced, and the entry is returned to the free
- list.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3
- cuddHashTableInsert2]
-
-******************************************************************************/
-DdNode *
-cuddHashTableLookup2(
- DdHashTable * hash,
- DdNode * f,
- DdNode * g)
-{
- unsigned int posn;
- DdHashItem *item, *prev;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 2);
-#endif
-
- posn = ddLCHash2(f,g,hash->shift);
- item = hash->bucket[posn];
- 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--;
- }
- return(value);
- }
- prev = item;
- item = item->next;
- }
- return(NULL);
-
-} /* end of cuddHashTableLookup2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts an item in a hash table.]
-
- Description [Inserts an item in a hash table when the key is
- composed of three pointers. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2
- cuddHashTableLookup3]
-
-******************************************************************************/
-int
-cuddHashTableInsert3(
- DdHashTable * hash,
- DdNode * f,
- DdNode * g,
- DdNode * h,
- DdNode * value,
- ptrint count)
-{
- int result;
- unsigned int posn;
- DdHashItem *item;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 3);
-#endif
-
- if (hash->size > hash->maxsize) {
- result = cuddHashTableResize(hash);
- if (result == 0) return(0);
- }
- item = cuddHashTableAlloc(hash);
- if (item == NULL) return(0);
- hash->size++;
- item->value = value;
- cuddRef(value);
- item->count = count;
- item->key[0] = f;
- item->key[1] = g;
- item->key[2] = h;
- posn = ddLCHash3(f,g,h,hash->shift);
- item->next = hash->bucket[posn];
- hash->bucket[posn] = item;
-
- return(1);
-
-} /* end of cuddHashTableInsert3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up a key consisting of three pointers in a hash table.]
-
- Description [Looks up a key consisting of three pointers in a hash table.
- Returns the value associated to the key if there is an entry for the given
- key in the table; NULL otherwise. If the entry is present, its reference
- counter is decremented if not saturated. If the counter reaches 0, the
- value of the entry is dereferenced, and the entry is returned to the free
- list.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2
- cuddHashTableInsert3]
-
-******************************************************************************/
-DdNode *
-cuddHashTableLookup3(
- DdHashTable * hash,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- unsigned int posn;
- DdHashItem *item, *prev;
-
-#ifdef DD_DEBUG
- assert(hash->keysize == 3);
-#endif
-
- posn = ddLCHash3(f,g,h,hash->shift);
- item = hash->bucket[posn];
- 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--;
- }
- return(value);
- }
- prev = item;
- item = item->next;
- }
- return(NULL);
-
-} /* end of cuddHashTableLookup3 */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Resizes a local cache.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-cuddLocalCacheResize(
- DdLocalCache * cache)
-{
- DdLocalCacheItem *item, *olditem, *entry, *old;
- int i, shift;
- unsigned int posn;
- unsigned int slots, oldslots;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- olditem = cache->item;
- oldslots = cache->slots;
- slots = cache->slots = oldslots << 1;
-
-#ifdef DD_VERBOSE
- (void) fprintf(cache->manager->err,
- "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);
-#endif
-
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- cache->item = item =
- (DdLocalCacheItem *) 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");
-#endif
- 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;
-
- /* Clear new cache. */
- memset(item, 0, slots * cache->itemsize);
-
- /* 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;
- }
- }
-
- FREE(olditem);
-
- /* Reinitialize measurements so as to avoid division by 0 and
- ** immediate resizing.
- */
- cache->lookUps = (double) (int) (slots * cache->minHit + 1);
- cache->hits = 0;
-
-} /* end of cuddLocalCacheResize */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the hash value for a local cache.]
-
- Description [Computes the hash value for a local cache. Returns the
- bucket index.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DD_INLINE
-static unsigned int
-ddLCHash(
- DdNodePtr * key,
- unsigned int keysize,
- int shift)
-{
- unsigned int val = (unsigned int) (ptrint) key[0];
- unsigned int i;
-
- for (i = 1; i < keysize; i++) {
- val = val * DD_P1 + (int) (ptrint) key[i];
- }
-
- return(val >> shift);
-
-} /* end of ddLCHash */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a local cache in the manager list.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-cuddLocalCacheAddToList(
- DdLocalCache * cache)
-{
- DdManager *manager = cache->manager;
-
- cache->next = manager->localCaches;
- manager->localCaches = cache;
- return;
-
-} /* end of cuddLocalCacheAddToList */
-
-
-/**Function********************************************************************
-
- Synopsis [Removes a local cache from the manager list.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-cuddLocalCacheRemoveFromList(
- DdLocalCache * cache)
-{
- DdManager *manager = cache->manager;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- DdLocalCache **prevCache, *nextCache;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-
- prevCache = &(manager->localCaches);
- nextCache = manager->localCaches;
-
- while (nextCache != NULL) {
- if (nextCache == cache) {
- *prevCache = nextCache->next;
- return;
- }
- prevCache = &(nextCache->next);
- nextCache = nextCache->next;
- }
- return; /* should never get here */
-
-} /* end of cuddLocalCacheRemoveFromList */
-
-
-/**Function********************************************************************
-
- Synopsis [Resizes a hash table.]
-
- Description [Resizes a hash table. Returns 1 if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddHashTableInsert]
-
-******************************************************************************/
-static int
-cuddHashTableResize(
- DdHashTable * hash)
-{
- int j;
- unsigned int posn;
- DdHashItem *item;
- DdHashItem *next;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- DdNode **key;
- int numBuckets;
- DdHashItem **buckets;
- DdHashItem **oldBuckets = hash->bucket;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- int shift;
- int oldNumBuckets = hash->numBuckets;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- /* Compute the new size of the table. */
- numBuckets = oldNumBuckets << 1;
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- buckets = ALLOC(DdHashItem *, numBuckets);
- MMoutOfMemory = saveHandler;
- if (buckets == NULL) {
- hash->maxsize <<= 1;
- return(1);
- }
-
- hash->bucket = buckets;
- hash->numBuckets = numBuckets;
- shift = --(hash->shift);
- hash->maxsize <<= 1;
- memset(buckets, 0, numBuckets * sizeof(DdHashItem *));
-#ifdef __osf__
-#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;
- }
- }
- } 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;
- }
- }
- } 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;
- }
- }
- } 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;
- }
- }
- }
- FREE(oldBuckets);
- return(1);
-
-} /* end of cuddHashTableResize */
-
-
-/**Function********************************************************************
-
- Synopsis [Fast storage allocation for items in a hash table.]
-
- Description [Fast storage allocation for items in a hash table. The
- first 4 bytes of a chunk contain a pointer to the next block; the
- rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to
- a new item if successful; NULL is memory is full.]
-
- SideEffects [None]
-
- SeeAlso [cuddAllocNode cuddDynamicAllocNode]
-
-******************************************************************************/
-DD_INLINE
-static DdHashItem *
-cuddHashTableAlloc(
- DdHashTable * hash)
-{
- int i;
- unsigned int itemsize = hash->itemsize;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- DdHashItem **mem, *thisOne, *next, *item;
-
- if (hash->nextFree == NULL) {
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
- MMoutOfMemory = saveHandler;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- if (mem == NULL) {
- if (hash->manager->stash != NULL) {
- FREE(hash->manager->stash);
- hash->manager->stash = NULL;
- /* Inhibit resizing of tables. */
- hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
- hash->manager->cacheSlack = -(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 **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- }
- 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;
-
- 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;
-
- }
- item = hash->nextFree;
- hash->nextFree = item->next;
- return(item);
-
-} /* end of cuddHashTableAlloc */
diff --git a/src/bdd/cudd/cuddLevelQ.c b/src/bdd/cudd/cuddLevelQ.c
deleted file mode 100644
index 3cc8e8d8..00000000
--- a/src/bdd/cudd/cuddLevelQ.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddLevelQ.c]
-
- PackageName [cudd]
-
- Synopsis [Procedure to manage level queues.]
-
- Description [The functions in this file allow an application to
- easily manipulate a queue where nodes are prioritized by level. The
- emphasis is on efficiency. Therefore, the queue items can have
- variable size. If the application does not need to attach
- information to the nodes, it can declare the queue items to be of
- type DdQueueItem. Otherwise, it can declare them to be of a
- structure type such that the first three fields are data
- pointers. The third pointer points to the node. The first two
- pointers are used by the level queue functions. The remaining fields
- are initialized to 0 when a new item is created, and are then left
- to the exclusive use of the application. On the DEC Alphas the three
- pointers must be 32-bit pointers when CUDD is compiled with 32-bit
- pointers. The level queue functions make sure that each node
- appears at most once in the queue. They do so by keeping a hash
- table where the node is used as key. Queue items are recycled via a
- free list for efficiency.
-
- Internal procedures provided by this module:
- <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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**Macro***********************************************************************
-
- Synopsis [Hash function for the table of a level queue.]
-
- Description [Hash function for the table of a level queue.]
-
- SideEffects [None]
-
- SeeAlso [hashInsert hashLookup hashDelete]
-
-******************************************************************************/
-#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
-#define lqHash(key,shift) \
-(((unsigned)(unsigned long)(key) * DD_P1) >> (shift))
-#else
-#define lqHash(key,shift) \
-(((unsigned)(key) * DD_P1) >> (shift))
-#endif
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Initializes a level queue.]
-
- Description [Initializes a level queue. A level queue is a queue
- where inserts are based on the levels of the nodes. Within each
- level the policy is FIFO. Level queues are useful in traversing a
- BDD top-down. Queue items are kept in a free list when dequeued for
- efficiency. Returns a pointer to the new queue if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue]
-
-******************************************************************************/
-DdLevelQueue *
-cuddLevelQueueInit(
- int levels /* number of levels */,
- int itemSize /* size of the item */,
- int numBuckets /* initial number of hash buckets */)
-{
- DdLevelQueue *queue;
- int logSize;
-
- queue = ALLOC(DdLevelQueue,1);
- if (queue == NULL)
- return(NULL);
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- /* Keep pointers to the insertion points for all levels. */
- queue->last = ALLOC(DdQueueItem *, levels);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- if (queue->last == NULL) {
- FREE(queue);
- return(NULL);
- }
- /* Use a hash table to test for uniqueness. */
- if (numBuckets < 2) numBuckets = 2;
- logSize = cuddComputeFloorLog2(numBuckets);
- queue->numBuckets = 1 << logSize;
- queue->shift = sizeof(int) * 8 - logSize;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- if (queue->buckets == NULL) {
- FREE(queue->last);
- FREE(queue);
- return(NULL);
- }
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- memset(queue->last, 0, levels * sizeof(DdQueueItem *));
- memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- queue->first = NULL;
- queue->freelist = NULL;
- queue->levels = levels;
- queue->itemsize = itemSize;
- queue->size = 0;
- queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
- return(queue);
-
-} /* end of cuddLevelQueueInit */
-
-
-/**Function********************************************************************
-
- Synopsis [Shuts down a level queue.]
-
- Description [Shuts down a level queue and releases all the
- associated memory.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueInit]
-
-******************************************************************************/
-void
-cuddLevelQueueQuit(
- DdLevelQueue * queue)
-{
- DdQueueItem *item;
-
- while (queue->freelist != NULL) {
- item = queue->freelist;
- queue->freelist = item->next;
- FREE(item);
- }
- while (queue->first != NULL) {
- item = (DdQueueItem *) queue->first;
- queue->first = item->next;
- FREE(item);
- }
- FREE(queue->buckets);
- FREE(queue->last);
- FREE(queue);
- return;
-
-} /* end of cuddLevelQueueQuit */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts a new key in a level queue.]
-
- Description [Inserts a new key in a level queue. A new entry is
- created in the queue only if the node is not already
- enqueued. Returns a pointer to the queue item if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueInit cuddLevelQueueDequeue]
-
-******************************************************************************/
-void *
-cuddLevelQueueEnqueue(
- DdLevelQueue * queue /* level queue */,
- void * key /* key to be enqueued */,
- int level /* level at which to insert */)
-{
- int plevel;
- DdQueueItem *item;
-
-#ifdef DD_DEBUG
- assert(level < queue->levels);
-#endif
- /* Check whether entry for this node exists. */
- item = hashLookup(queue,key);
- if (item != NULL) return(item);
-
- /* Get a free item from either the free list or the memory manager. */
- if (queue->freelist == NULL) {
- item = (DdQueueItem *) ALLOC(char, queue->itemsize);
- if (item == NULL)
- return(NULL);
- } else {
- item = queue->freelist;
- queue->freelist = item->next;
- }
- /* Initialize. */
- memset(item, 0, queue->itemsize);
- item->key = key;
- /* Update stats. */
- 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;
- } 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(item);
-
-} /* end of cuddLevelQueueEnqueue */
-
-
-/**Function********************************************************************
-
- Synopsis [Remove an item from the front of a level queue.]
-
- Description [Remove an item from the front of a level queue.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueEnqueue]
-
-******************************************************************************/
-void
-cuddLevelQueueDequeue(
- DdLevelQueue * queue,
- int level)
-{
- DdQueueItem *item = (DdQueueItem *) queue->first;
-
- /* Delete from the hash table. */
- hashDelete(queue,item);
-
- /* 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->first = item->next;
- /* Put item on the free list. */
- item->next = queue->freelist;
- queue->freelist = item;
- /* Update stats. */
- queue->size--;
- return;
-
-} /* end of cuddLevelQueueDequeue */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Looks up a key in the hash table of a level queue.]
-
- Description [Looks up a key in the hash table of a level queue. Returns
- a pointer to the item with the given key if the key is found; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueEnqueue hashInsert]
-
-******************************************************************************/
-static DdQueueItem *
-hashLookup(
- DdLevelQueue * queue,
- void * key)
-{
- int posn;
- DdQueueItem *item;
-
- posn = lqHash(key,queue->shift);
- item = queue->buckets[posn];
-
- while (item != NULL) {
- if (item->key == key) {
- return(item);
- }
- item = item->cnext;
- }
- return(NULL);
-
-} /* end of hashLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts an item in the hash table of a level queue.]
-
- Description [Inserts an item in the hash table of a level queue. Returns
- 1 if successful; 0 otherwise. No check is performed to see if an item with
- the same key is already in the hash table.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueEnqueue]
-
-******************************************************************************/
-static int
-hashInsert(
- DdLevelQueue * queue,
- DdQueueItem * item)
-{
- int result;
- int posn;
-
- if (queue->size > queue->maxsize) {
- result = hashResize(queue);
- if (result == 0) return(0);
- }
-
- posn = lqHash(item->key,queue->shift);
- item->cnext = queue->buckets[posn];
- queue->buckets[posn] = item;
-
- return(1);
-
-} /* end of hashInsert */
-
-
-/**Function********************************************************************
-
- Synopsis [Removes an item from the hash table of a level queue.]
-
- Description [Removes an item from the hash table of a level queue.
- Nothing is done if the item is not in the table.]
-
- SideEffects [None]
-
- SeeAlso [cuddLevelQueueDequeue hashInsert]
-
-******************************************************************************/
-static void
-hashDelete(
- DdLevelQueue * queue,
- DdQueueItem * item)
-{
- int posn;
- DdQueueItem *prevItem;
-
- posn = lqHash(item->key,queue->shift);
- prevItem = queue->buckets[posn];
-
- if (prevItem == NULL) return;
- if (prevItem == item) {
- queue->buckets[posn] = prevItem->cnext;
- return;
- }
-
- while (prevItem->cnext != NULL) {
- if (prevItem->cnext == item) {
- prevItem->cnext = item->cnext;
- return;
- }
- prevItem = prevItem->cnext;
- }
- return;
-
-} /* end of hashDelete */
-
-
-/**Function********************************************************************
-
- Synopsis [Resizes the hash table of a level queue.]
-
- Description [Resizes the hash table of a level queue. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [hashInsert]
-
-******************************************************************************/
-static int
-hashResize(
- DdLevelQueue * queue)
-{
- int j;
- int posn;
- DdQueueItem *item;
- DdQueueItem *next;
- int numBuckets;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- DdQueueItem **buckets;
- DdQueueItem **oldBuckets = queue->buckets;
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
- int shift;
- int oldNumBuckets = queue->numBuckets;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- /* Compute the new size of the subtable. */
- numBuckets = oldNumBuckets << 1;
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets);
- if (buckets == NULL) {
- queue->maxsize <<= 1;
- return(1);
- }
-
- queue->numBuckets = numBuckets;
- shift = --(queue->shift);
- queue->maxsize <<= 1;
- memset(buckets, 0, numBuckets * sizeof(DdQueueItem *));
-#ifdef __osf__
-#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;
- }
- }
- FREE(oldBuckets);
- return(1);
-
-} /* end of hashResize */
diff --git a/src/bdd/cudd/cuddLinear.c b/src/bdd/cudd/cuddLinear.c
deleted file mode 100644
index 7f6b3678..00000000
--- a/src/bdd/cudd/cuddLinear.c
+++ /dev/null
@@ -1,1333 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddLinear.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define CUDD_SWAP_MOVE 0
-#define CUDD_LINEAR_TRANSFORM_MOVE 1
-#define CUDD_INVERSE_TRANSFORM_MOVE 2
-#if SIZEOF_LONG == 8
-#define BPL 64
-#define LOGBPL 6
-#else
-#define BPL 32
-#define LOGBPL 5
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-static int *entry;
-
-#ifdef DD_STATS
-extern int ddTotalNumberSwapping;
-extern int ddTotalNISwaps;
-static int ddTotalNumberLinearTr;
-#endif
-
-#ifdef DD_DEBUG
-static int zero = 0;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the linear transform matrix.]
-
- Description [Prints the linear transform matrix. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_PrintLinear(
- DdManager * table)
-{
- int i,j,k;
- int retval;
- int nvars = table->linearSize;
- int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
- 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;
- }
- }
- retval = fprintf(table->out,"\n");
- if (retval == 0) return(0);
- }
- return(1);
-
-} /* end of Cudd_PrintLinear */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads an entry of the linear transform matrix.]
-
- Description [Reads an entry of the linear transform matrix.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_ReadLinear(
- DdManager * table /* CUDD manager */,
- int x /* row index */,
- int y /* column index */)
-{
- int nvars = table->size;
- int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
- long word;
- int bit;
- int result;
-
- assert(table->size == table->linearSize);
-
- word = wordsPerRow * x + (y >> LOGBPL);
- bit = y & (BPL-1);
- result = (int) ((table->linear[word] >> bit) & 1);
- return(result);
-
-} /* end of Cudd_ReadLinear */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [BDD reduction based on combination of sifting and linear
- transformations.]
-
- Description [BDD reduction based on combination of sifting and linear
- transformations. Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries
- in each unique table.
- <li> Sift the variable up and down, remembering each time the
- total size of the DD heap. At each position, linear transformation
- of the two adjacent variables is tried and is accepted if it reduces
- the size of the DD.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddLinearAndSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
-#ifdef DD_STATS
- ddTotalNumberLinearTr = 0;
-#endif
-
- size = table->size;
-
- var = NULL;
- entry = NULL;
- if (table->linear == NULL) {
- result = cuddInitLinear(table);
- if (result == 0) goto cuddLinearAndSiftingOutOfMem;
-#if 0
- (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;
-#if 0
- (void) fprintf(table->out,"\n");
- result = Cudd_PrintLinear(table);
- if (result == 0) goto cuddLinearAndSiftingOutOfMem;
-#endif
- }
-
- /* Find order in which to sift variables. */
- entry = ALLOC(int,size);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddLinearAndSiftingOutOfMem;
- }
- var = ALLOC(int,size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddLinearUniqueCompare);
-
- /* Now sift. */
- for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
- x = table->perm[var[i]];
- if (x < lower || x > upper) continue;
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
- 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);
-#endif
-#ifdef DD_DEBUG
- (void) Cudd_DebugCheck(table);
-#endif
- }
-
- FREE(var);
- FREE(entry);
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
- ddTotalNumberLinearTr);
-#endif
-
- return(1);
-
-cuddLinearAndSiftingOutOfMem:
-
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddLinearAndSifting */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the
- variables according to the number of keys in the subtables.
- Returns the difference in number of keys between the two
- variables being compared.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddLinearUniqueCompare(
- int * ptrX,
- int * ptrY)
-{
-#if 0
- if (entry[*ptrY] == entry[*ptrX]) {
- return((*ptrX) - (*ptrY));
- }
-#endif
- return(entry[*ptrY] - entry[*ptrX]);
-
-} /* end of ddLinearUniqueCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. At each step a linear transformation is tried, and, if it
- decreases the size of the DD, it is accepted. Finds the best position
- and does the required changes. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddLinearAndSiftingAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
-
- Move *move;
- Move *moveUp; /* list of up moves */
- Move *moveDown; /* list of down moves */
- int initialSize;
- int result;
-
- initialSize = table->keys - table->isolated;
-
- moveDown = NULL;
- 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;
-
- } 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;
-
- } 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);
-#ifdef DD_DEBUG
- 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;
-
- } 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);
-#ifdef DD_DEBUG
- 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;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
-
- return(1);
-
-ddLinearAndSiftingAuxOutOfMem:
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
-
- return(0);
-
-} /* end of ddLinearAndSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable up and applies linear transformations.]
-
- Description [Sifts a variable up and applies linear transformations.
- Moves y up until either it reaches the bound (xLow) or the size of
- the DD heap increases too much. Returns the set of moves in case of
- success; NULL if memory is full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddLinearAndSiftingUp(
- DdManager * table,
- int y,
- 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 */
-#ifdef DD_DEBUG
- int checkL;
- int z;
- int zindex;
-#endif
-
- moves = prevMoves;
- yindex = table->invperm[y];
-
- /* Initialize the lower bound.
- ** The part of the DD below y will not change.
- ** The part of the DD above y that does not interact with y will not
- ** change. The rest may vanish in the best case, except for
- ** the nodes at level xLow, which will not vanish, regardless.
- */
- 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;
- }
- }
- 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];
-#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;
- }
- }
- 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.
- */
- 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);
- }
-#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);
- }
- return(moves);
-
-ddLinearAndSiftingUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of ddLinearAndSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable down and applies linear transformations.]
-
- Description [Sifts a variable down and applies linear
- transformations. Moves x down until either it reaches the bound
- (xHigh) or the size of the DD heap increases too much. Returns the
- set of moves in case of success; NULL if memory is full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddLinearAndSiftingDown(
- DdManager * table,
- int x,
- 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;
-#ifdef DD_DEBUG
- int checkR;
- int z;
- int zindex;
-#endif
-
- moves = prevMoves;
- /* Initialize R */
- xindex = table->invperm[x];
- 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;
- }
- }
-
- 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;
- }
- }
- 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.
- */
- 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;
- 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);
- }
- return(moves);
-
-ddLinearAndSiftingDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of ddLinearAndSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the DD heap to the order
- giving the minimum size.]
-
- Description [Given a set of moves, returns the DD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddLinearAndSiftingBackward(
- DdManager * table,
- int size,
- Move * moves)
-{
- Move *move;
- int res;
-
- for (move = moves; move != NULL; move = move->next) {
- 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 (!res) return(0);
- }
- }
-
- return(1);
-
-} /* end of ddLinearAndSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the DD heap to the order
- in effect before the moves.]
-
- Description [Given a set of moves, returns the DD heap to the
- order in effect before the moves. Returns 1 in case of success;
- 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move*
-ddUndoMoves(
- DdManager * table,
- Move * moves)
-{
- Move *invmoves = NULL;
- Move *move;
- Move *invmove;
- 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 */
-#ifdef DD_DEBUG
- (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;
- }
-
- return(invmoves);
-
-ddUndoMovesOutOfMem:
- while (invmoves != NULL) {
- move = invmoves->next;
- cuddDeallocNode(table, (DdNode *) invmoves);
- invmoves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of ddUndoMoves */
-
-
-/**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 &lt;
- 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;
- 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 = 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 = 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];
- }
- }
- 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
- the first row with the result.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-cuddXorLinear(
- DdManager * table,
- int x,
- int y)
-{
- int i;
- int nvars = table->size;
- int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
- int xstart = wordsPerRow * x;
- int ystart = wordsPerRow * y;
- long *linear = table->linear;
-
- for (i = 0; i < wordsPerRow; i++) {
- linear[xstart+i] ^= linear[ystart+i];
- }
-
-} /* end of cuddXorLinear */
-
diff --git a/src/bdd/cudd/cuddLiteral.c b/src/bdd/cudd/cuddLiteral.c
deleted file mode 100644
index 43740690..00000000
--- a/src/bdd/cudd/cuddLiteral.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddLiteral.c]
-
- PackageName [cudd]
-
- Synopsis [Functions for manipulation of literal sets represented by
- BDDs.]
-
- Description [External procedures included in this file:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the intesection of two sets of literals
- represented as BDDs.]
-
- Description [Computes the intesection of two sets of literals
- represented as BDDs. Each set is represented as a cube of the
- literals in the set. The empty set is represented by the constant 1.
- No variable can be simultaneously present in both phases in a set.
- Returns a pointer to the BDD representing the intersected sets, if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-Cudd_bddLiteralSetIntersection(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddLiteralSetIntersectionRecur(dd,f,g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddLiteralSetIntersection */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of
- Cudd_bddLiteralSetIntersection.]
-
- Description [Performs the recursive step of
- Cudd_bddLiteralSetIntersection. Scans the cubes for common variables,
- and checks whether they agree in phase. Returns a pointer to the
- resulting cube if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-cuddBddLiteralSetIntersectionRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res, *tmp;
- DdNode *F, *G;
- DdNode *fc, *gc;
- DdNode *one;
- DdNode *zero;
- unsigned int topf, topg, comple;
- int phasef, phaseg;
-
- statLine(dd);
- if (f == g) return(f);
-
- F = Cudd_Regular(f);
- G = Cudd_Regular(g);
- one = DD_ONE(dd);
-
- /* Here f != g. If F == G, then f and g are complementary.
- ** Since they are two cubes, this case only occurs when f == v,
- ** g == v', and v is a variable or its complement.
- */
- if (F == G) return(one);
-
- zero = Cudd_Not(one);
- topf = cuddI(dd,F->index);
- topg = cuddI(dd,G->index);
- /* Look for a variable common to both cubes. If there are none, this
- ** 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);
- }
- G = Cudd_Regular(g);
- topg = cuddI(dd,G->index);
- }
- }
-
- /* At this point, f == one <=> g == 1. It suffices to test one of them. */
- if (f == one) return(one);
-
- res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g);
- if (res != NULL) {
- return(res);
- }
-
- /* Here f and g are both non constant and have the same top variable. */
- comple = f != F;
- fc = cuddT(F);
- phasef = 1;
- if (comple) fc = Cudd_Not(fc);
- if (fc == zero) {
- 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);
- }
-
- tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc);
- if (tmp == NULL) {
- return(NULL);
- }
-
- if (phasef != phaseg) {
- res = tmp;
- } else {
- 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);
-
- return(res);
-
-} /* end of cuddBddLiteralSetIntersectionRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddMatMult.c b/src/bdd/cudd/cuddMatMult.c
deleted file mode 100644
index 345e7921..00000000
--- a/src/bdd/cudd/cuddMatMult.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddMatMult.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Calculates the product of two matrices represented as
- ADDs.]
-
- Description [Calculates the product of two matrices, A and B,
- represented as ADDs. This procedure implements the quasiring multiplication
- algorithm. A is assumed to depend on variables x (rows) and z
- (columns). B is assumed to depend on variables z (rows) and y
- (columns). The product of A and B then depends on x (rows) and y
- (columns). Only the z variables have to be explicitly identified;
- they are the "summation" variables. Returns a pointer to the
- result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_addMatrixMultiply(
- DdManager * dd,
- DdNode * A,
- DdNode * B,
- DdNode ** z,
- int nz)
-{
- int i, nvars, *vars;
- DdNode *res;
-
- /* Array vars says what variables are "summation" variables. */
- nvars = dd->size;
- vars = ALLOC(int,nvars);
- if (vars == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < nvars; i++) {
- vars[i] = 0;
- }
- for (i = 0; i < nz; i++) {
- vars[z[i]->index] = 1;
- }
-
- do {
- dd->reordered = 0;
- res = addMMRecur(dd,A,B,-1,vars);
- } while (dd->reordered == 1);
- FREE(vars);
- return(res);
-
-} /* end of Cudd_addMatrixMultiply */
-
-
-/**Function********************************************************************
-
- Synopsis [Calculates the product of two matrices represented as
- ADDs.]
-
- Description [Calculates the product of two matrices, A and B,
- represented as ADDs, using the CMU matrix by matrix multiplication
- procedure by Clarke et al.. Matrix A has x's as row variables and z's
- as column variables, while matrix B has z's as row variables and y's
- as column variables. Returns the pointer to the result if successful;
- NULL otherwise. The resulting matrix has x's as row variables and y's
- as column variables.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addMatrixMultiply]
-
-******************************************************************************/
-DdNode *
-Cudd_addTimesPlus(
- DdManager * dd,
- DdNode * A,
- DdNode * B,
- DdNode ** z,
- int nz)
-{
- DdNode *w, *cube, *tmp, *res;
- int i;
- tmp = Cudd_addApply(dd,Cudd_addTimes,A,B);
- if (tmp == NULL) return(NULL);
- 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;
- }
- res = Cudd_addExistAbstract(dd,tmp,cube);
- if (res == NULL) {
- Cudd_RecursiveDeref(dd,tmp);
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- Cudd_Ref(res);
- Cudd_RecursiveDeref(dd,cube);
- Cudd_RecursiveDeref(dd,tmp);
- Cudd_Deref(res);
- return(res);
-
-} /* end of Cudd_addTimesPlus */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the triangulation step for the shortest path
- computation.]
-
- Description [Implements the semiring multiplication algorithm used in
- the triangulation step for the shortest path computation. f
- is assumed to depend on variables x (rows) and z (columns). g is
- assumed to depend on variables z (rows) and y (columns). The product
- of f and g then depends on x (rows) and y (columns). Only the z
- variables have to be explicitly identified; they are the
- "abstraction" variables. Returns a pointer to the result if
- successful; NULL otherwise. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract]
-
-******************************************************************************/
-DdNode *
-Cudd_addTriangle(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode ** z,
- int nz)
-{
- int i, nvars, *vars;
- DdNode *res, *cube;
-
- nvars = dd->size;
- vars = ALLOC(int, nvars);
- if (vars == 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) {
- FREE(vars);
- return(NULL);
- }
- cuddRef(cube);
-
- do {
- dd->reordered = 0;
- res = addTriangleRecur(dd, f, g, vars, cube);
- } while (dd->reordered == 1);
- if (res != NULL) cuddRef(res);
- Cudd_RecursiveDeref(dd,cube);
- if (res != NULL) cuddDeref(res);
- FREE(vars);
- return(res);
-
-} /* end of Cudd_addTriangle */
-
-
-/**Function********************************************************************
-
- Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.]
-
- Description [Takes the pointwise minimum of a matrix and the outer
- sum of two vectors. This procedure is used in the Floyd-Warshall
- all-pair shortest path algorithm. Returns a pointer to the result if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_addOuterSum(
- DdManager *dd,
- DdNode *M,
- DdNode *r,
- DdNode *c)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddAddOuterSumRecur(dd, M, r, c);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_addOuterSum */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.]
-
- Description [Performs the recursive step of Cudd_addMatrixMultiply.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-addMMRecur(
- DdManager * dd,
- DdNode * A,
- DdNode * B,
- int topP,
- 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 */
- CUDD_VALUE_TYPE value;
- unsigned int topA, topB, topV;
- DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
-
- statLine(dd);
- zero = DD_ZERO(dd);
-
- if (A == zero || B == zero) {
- return(zero);
- }
-
- 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;
- }
- }
- }
- res = cuddUniqueConst(dd, value);
- return(res);
- }
-
- /* Standardize to increase cache efficiency. Clearly, A*B != B*A
- ** in matrix multiplication. However, which matrix is which is
- ** determined by the variables appearing in the ADDs and not by
- ** which one is passed as first argument.
- */
- if (A > B) {
- 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;
- 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);
- }
- 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);
- }
- return(res);
- }
-
- /* compute the cofactors */
- if (topV == topA) {
- At = cuddT(A);
- Ae = cuddE(A);
- } else {
- At = Ae = A;
- }
- if (topV == topB) {
- Bt = cuddT(B);
- Be = cuddE(B);
- } else {
- Bt = Be = B;
- }
-
- t = addMMRecur(dd, At, Bt, (int)topV, vars);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = addMMRecur(dd, Ae, Be, (int)topV, vars);
- if (e == 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);
- } 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) {
- 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);
-
- /* We have computed (and stored in the computed table) a minimal
- ** result; that is, a result that assumes no summation variables
- ** between the current depth of the recursion and its top
- ** variable. We now take into account the z variables by properly
- ** 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);
- }
- 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;
- }
- }
- cuddDeref(res);
- return(res);
-
-} /* end of addMMRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addTriangle.]
-
- Description [Performs the recursive step of Cudd_addTriangle. Returns
- a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-addTriangleRecur(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- int * vars,
- DdNode *cube)
-{
- DdNode *fv, *fvn, *gv, *gvn, *t, *e, *res;
- CUDD_VALUE_TYPE value;
- int top, topf, topg, index;
-
- statLine(dd);
- if (f == DD_PLUS_INFINITY(dd) || g == 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);
- }
- if (f < g) {
- 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);
- }
- }
-
- topf = cuddI(dd,f->index); topg = cuddI(dd,g->index);
- top = ddMin(topf,topg);
-
- if (top == topf) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
- if (top == topg) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
-
- t = addTriangleRecur(dd, fv, gv, vars, cube);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = addTriangleRecur(dd, fvn, gvn, vars, cube);
- if (e == 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);
- } else {
- 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);
- cuddDeref(res);
- }
-
- if (f->ref != 1 || g->ref != 1) {
- cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res);
- }
-
- return(res);
-
-} /* end of addTriangleRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_addOuterSum.]
-
- Description [Performs the recursive step of Cudd_addOuterSum.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-cuddAddOuterSumRecur(
- DdManager *dd,
- DdNode *M,
- DdNode *r,
- DdNode *c)
-{
- DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re;
- int topM, topc, topr;
- int v, index;
-
- statLine(dd);
- /* Check special cases. */
- 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);
- } else {
- Cudd_RecursiveDeref(dd,R);
- return(M);
- }
- } else {
- P = Cudd_addApply(dd,Cudd_addMinimum,R,M);
- cuddRef(P);
- Cudd_RecursiveDeref(dd,R);
- cuddDeref(P);
- return(P);
- }
- }
-
- /* Check the cache. */
- R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c);
- if (R != NULL) return(R);
-
- topM = cuddI(dd,M->index); topr = cuddI(dd,r->index);
- topc = cuddI(dd,c->index);
- v = ddMin(topM,ddMin(topr,topc));
-
- /* Compute cofactors. */
- if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; }
- if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; }
- if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; }
-
- /* Recursively solve. */
- Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct);
- if (Rt == NULL) return(NULL);
- cuddRef(Rt);
- Re = cuddAddOuterSumRecur(dd,Me,re,ce);
- if (Re == 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);
- }
- cuddDeref(Rt);
- cuddDeref(Re);
-
- /* Store the result in the cache. */
- cuddCacheInsert(dd,DD_ADD_OUT_SUM_TAG,M,r,c,R);
-
- return(R);
-
-} /* end of cuddAddOuterSumRecur */
diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c
deleted file mode 100644
index 788fc712..00000000
--- a/src/bdd/cudd/cuddPriority.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddPriority.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Selects pairs from R using a priority function.]
-
- Description [Selects pairs from a relation R(x,y) (given as a BDD)
- in such a way that a given x appears in one pair only. Uses a
- priority function to determine which y should be paired to a given x.
- Cudd_PrioritySelect returns a pointer to
- the selected function if successful; NULL otherwise.
- Three of the arguments--x, y, and z--are vectors of BDD variables.
- The first two are the variables on which R depends. The third vectore
- is a vector of auxiliary variables, used during the computation. This
- vector is optional. If a NULL value is passed instead,
- Cudd_PrioritySelect will create the working variables on the fly.
- The sizes of x and y (and z if it is not NULL) should equal n.
- The priority function Pi can be passed as a BDD, or can be built by
- Cudd_PrioritySelect. If NULL is passed instead of a DdNode *,
- parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the
- priority function. (Pifunc is a pointer to a C function.) If Pi is not
- NULL, then Pifunc is ignored. Pifunc should have the same interface as
- the standard priority functions (e.g., Cudd_Dxygtdxz).
- Cudd_PrioritySelect and Cudd_CProjection can sometimes be used
- interchangeably. Specifically, calling Cudd_PrioritySelect with
- Cudd_Xgty as Pifunc produces the same result as calling
- Cudd_CProjection with the all-zero minterm as reference minterm.
- However, depending on the application, one or the other may be
- preferable:
- <ul>
- <li> When extracting representatives from an equivalence relation,
- Cudd_CProjection has the advantage of nor requiring the auxiliary
- variables.
- <li> When computing matchings in general bipartite graphs,
- Cudd_PrioritySelect normally obtains better results because it can use
- more powerful matching schemes (e.g., Cudd_Dxygtdxz).
- </ul>
- ]
-
- SideEffects [If called with z == NULL, will create new variables in
- the manager.]
-
- SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty
- Cudd_bddAdjPermuteX Cudd_CProjection]
-
-******************************************************************************/
-DdNode *
-Cudd_PrioritySelect(
- DdManager * dd /* manager */,
- DdNode * R /* BDD of the relation */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */,
- 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 */)
-{
- DdNode *res = NULL;
- DdNode *zcube = NULL;
- DdNode *Rxz, *Q;
- int createdZ = 0;
- int createdPi = 0;
- int i;
-
- /* Create z variables if needed. */
- if (z == NULL) {
- if (Pi != NULL) return(NULL);
- z = 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);
- }
-
- /* 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;
- }
-
- /* Compute subset of (x,y) pairs. */
- Rxz = Cudd_bddSwapVariables(dd,R,y,z,n);
- if (Rxz == NULL) goto endgame;
- cuddRef(Rxz);
- Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube);
- if (Q == NULL) {
- 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;
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd,Q);
-
-endgame:
- if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube);
- if (createdZ) {
- FREE(z);
- }
- if (createdPi) {
- Cudd_RecursiveDeref(dd,Pi);
- }
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* Cudd_PrioritySelect */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a BDD for the function x &gt; y.]
-
- Description [This function generates a BDD for the function x &gt; y.
- Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
- y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
- The BDD is built bottom-up.
- It has 3*N-1 internal nodes, if the variables are ordered as follows:
- x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].
- Argument z is not used by Cudd_Xgty: it is included to make it
- call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz]
-
-******************************************************************************/
-DdNode *
-Cudd_Xgty(
- DdManager * dd /* DD manager */,
- int N /* number of x and y variables */,
- DdNode ** z /* array of z variables: unused */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */)
-{
- DdNode *u, *v, *w;
- int i;
-
- /* Build bottom part of BDD outside loop. */
- u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1]));
- if (u == NULL) return(NULL);
- cuddRef(u);
-
- /* 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) {
- 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) {
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
- return(NULL);
- }
- cuddRef(u);
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
-
- }
- cuddDeref(u);
- return(u);
-
-} /* end of Cudd_Xgty */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a BDD for the function x==y.]
-
- Description [This function generates a BDD for the function x==y.
- Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
- y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
- The BDD is built bottom-up.
- It has 3*N-1 internal nodes, if the variables are ordered as follows:
- x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addXeqy]
-
-******************************************************************************/
-DdNode *
-Cudd_Xeqy(
- DdManager * dd /* DD manager */,
- int N /* number of x and y variables */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */)
-{
- DdNode *u, *v, *w;
- int i;
-
- /* Build bottom part of BDD outside loop. */
- u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1]));
- if (u == NULL) return(NULL);
- cuddRef(u);
-
- /* 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) {
- 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) {
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
- return(NULL);
- }
- cuddRef(u);
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
- }
- cuddDeref(u);
- return(u);
-
-} /* end of Cudd_Xeqy */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates an ADD for the function x==y.]
-
- Description [This function generates an ADD for the function x==y.
- Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
- y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
- The ADD is built bottom-up.
- It has 3*N-1 internal nodes, if the variables are ordered as follows:
- x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Xeqy]
-
-******************************************************************************/
-DdNode *
-Cudd_addXeqy(
- DdManager * dd /* DD manager */,
- int N /* number of x and y variables */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */)
-{
- DdNode *one, *zero;
- DdNode *u, *v, *w;
- int i;
-
- one = DD_ONE(dd);
- zero = DD_ZERO(dd);
-
- /* Build bottom part of ADD outside loop. */
- v = Cudd_addIte(dd, y[N-1], one, zero);
- if (v == NULL) return(NULL);
- cuddRef(v);
- w = Cudd_addIte(dd, y[N-1], zero, one);
- if (w == 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);
- }
- cuddRef(u);
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
-
- /* 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) {
- 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) {
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
- return(NULL);
- }
- cuddRef(u);
- Cudd_RecursiveDeref(dd, v);
- Cudd_RecursiveDeref(dd, w);
- }
- cuddDeref(u);
- return(u);
-
-} /* end of Cudd_addXeqy */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a BDD for the function d(x,y) &gt; d(x,z).]
-
- Description [This function generates a BDD for the function d(x,y)
- &gt; d(x,z);
- x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
- y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\],
- with 0 the most significant bit.
- The distance d(x,y) is defined as:
- \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:
- x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX]
-
-******************************************************************************/
-DdNode *
-Cudd_Dxygtdxz(
- DdManager * dd /* DD manager */,
- int N /* number of x, y, and z variables */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */,
- DdNode ** z /* array of z variables */)
-{
- DdNode *one, *zero;
- DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
- int i;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- /* Build bottom part of BDD outside loop. */
- y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1]));
- if (y1_ == NULL) return(NULL);
- cuddRef(y1_);
- y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one);
- if (y2 == 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);
- }
- cuddRef(x1);
- Cudd_RecursiveDeref(dd, y1_);
- Cudd_RecursiveDeref(dd, y2);
-
- /* 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) {
- 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) {
- 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) {
- 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));
-
-} /* end of Cudd_Dxygtdxz */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a BDD for the function d(x,y) &gt; d(y,z).]
-
- Description [This function generates a BDD for the function d(x,y)
- &gt; d(y,z);
- x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
- y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\],
- with 0 the most significant bit.
- The distance d(x,y) is defined as:
- \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:
- x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX]
-
-******************************************************************************/
-DdNode *
-Cudd_Dxygtdyz(
- DdManager * dd /* DD manager */,
- int N /* number of x, y, and z variables */,
- DdNode ** x /* array of x variables */,
- DdNode ** y /* array of y variables */,
- DdNode ** z /* array of z variables */)
-{
- DdNode *one, *zero;
- DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
- int i;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- /* Build bottom part of BDD outside loop. */
- y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]);
- if (y1_ == NULL) return(NULL);
- cuddRef(y1_);
- y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero);
- if (y2 == 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);
- }
- cuddRef(x1);
- Cudd_RecursiveDeref(dd, y1_);
- Cudd_RecursiveDeref(dd, y2);
-
- /* 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) {
- 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) {
- 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) {
- 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));
-
-} /* end of Cudd_Dxygtdyz */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the compatible projection of R w.r.t. cube Y.]
-
- Description [Computes the compatible projection of relation R with
- respect to cube Y. Returns a pointer to the c-projection if
- successful; NULL otherwise. For a comparison between Cudd_CProjection
- and Cudd_PrioritySelect, see the documentation of the latter.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrioritySelect]
-
-******************************************************************************/
-DdNode *
-Cudd_CProjection(
- DdManager * dd,
- DdNode * R,
- DdNode * Y)
-{
- DdNode *res;
- 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);
- }
-
- /* Compute the support of Y, which is used by the abstraction step
- ** in cuddCProjectionRecur.
- */
- support = Cudd_Support(dd,Y);
- if (support == NULL) return(NULL);
- cuddRef(support);
-
- do {
- dd->reordered = 0;
- res = cuddCProjectionRecur(dd,R,Y,support);
- } while (dd->reordered == 1);
-
- if (res == NULL) {
- Cudd_RecursiveDeref(dd,support);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd,support);
- cuddDeref(res);
-
- return(res);
-
-} /* end of Cudd_CProjection */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the Hamming distance ADD.]
-
- Description [Computes the Hamming distance ADD. Returns an ADD that
- gives the Hamming distance between its two arguments if successful;
- NULL otherwise. The two vectors xVars and yVars identify the variables
- that form the two arguments.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_addHamming(
- DdManager * dd,
- DdNode ** xVars,
- DdNode ** yVars,
- int nVars)
-{
- DdNode *result,*tempBdd;
- DdNode *tempAdd,*temp;
- int i;
-
- result = DD_ZERO(dd);
- 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) {
- 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) {
- Cudd_RecursiveDeref(dd,tempAdd);
- Cudd_RecursiveDeref(dd,result);
- return(NULL);
- }
- cuddRef(temp);
- Cudd_RecursiveDeref(dd,tempAdd);
- Cudd_RecursiveDeref(dd,result);
- result = temp;
- }
-
- cuddDeref(result);
- return(result);
-
-} /* end of Cudd_addHamming */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the minimum Hamming distance between f and minterm.]
-
- Description [Returns the minimum Hamming distance between the
- minterms of a function f and a reference minterm. The function is
- given as a BDD; the minterm is given as an array of integers, one
- for each variable in the manager. Returns the minimum distance if
- it is less than the upper bound; the upper bound if the minimum
- distance is at least as large; CUDD_OUT_OF_MEM in case of failure.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addHamming Cudd_bddClosestCube]
-
-******************************************************************************/
-int
-Cudd_MinHammingDist(
- DdManager *dd /* DD manager */,
- DdNode *f /* function to examine */,
- int *minterm /* reference minterm */,
- int upperBound /* distance above which an approximate answer is OK */)
-{
- DdHashTable *table;
- CUDD_VALUE_TYPE epsilon;
- int res;
-
- table = cuddHashTableInit(dd,1,2);
- if (table == NULL) {
- return(CUDD_OUT_OF_MEM);
- }
- epsilon = Cudd_ReadEpsilon(dd);
- Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0);
- res = cuddMinHammingDistRecur(f,minterm,table,upperBound);
- cuddHashTableQuit(table);
- Cudd_SetEpsilon(dd,epsilon);
-
- return(res);
-
-} /* end of Cudd_MinHammingDist */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a cube of f at minimum Hamming distance from g.]
-
- Description [Finds a cube of f at minimum Hamming distance from the
- minterms of g. All the minterms of the cube are at the minimum
- distance. If the distance is 0, the cube belongs to the
- intersection of f and g. Returns the cube if successful; NULL
- otherwise.]
-
- SideEffects [The distance is returned as a side effect.]
-
- SeeAlso [Cudd_MinHammingDist]
-
-******************************************************************************/
-DdNode *
-Cudd_bddClosestCube(
- DdManager *dd,
- DdNode * f,
- DdNode *g,
- int *distance)
-{
- DdNode *res, *acube;
- CUDD_VALUE_TYPE rdist;
-
- /* Compute the cube and distance as a single ADD. */
- do {
- 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);
- } while (dd->reordered == 1);
- if (acube == 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);
- } while (dd->reordered == 1);
- if (res == NULL) {
- Cudd_RecursiveDeref(dd, acube);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, acube);
-
- *distance = (int) rdist;
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_bddClosestCube */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CProjection.]
-
- Description [Performs the recursive step of Cudd_CProjection. Returns
- the projection if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CProjection]
-
-******************************************************************************/
-DdNode *
-cuddCProjectionRecur(
- DdManager * dd,
- DdNode * R,
- DdNode * Y,
- DdNode * Ysupp)
-{
- DdNode *res, *res1, *res2, *resA;
- DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha;
- unsigned int topR, topY, top, index;
- DdNode *one = DD_ONE(dd);
-
- statLine(dd);
- if (Y == one) return(R);
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsConstant(Y));
-#endif
-
- if (R == Cudd_Not(one)) return(R);
-
- res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y);
- if (res != NULL) return(res);
-
- r = Cudd_Regular(R);
- topR = cuddI(dd,r->index);
- y = Cudd_Regular(Y);
- topY = cuddI(dd,y->index);
-
- top = ddMin(topR, topY);
-
- /* 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);
- }
- } else {
- 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));
- 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);
- }
- }
-
- cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res);
-
- return(res);
-
-} /* end of cuddCProjectionRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddClosestCube.]
-
- Description [Performs the recursive step of Cudd_bddClosestCube.
- Returns the cube if succesful; NULL otherwise. The procedure uses a
- four-way recursion to examine all four combinations of cofactors of
- f and g. 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).]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddClosestCube]
-
-******************************************************************************/
-DdNode *
-cuddBddClosestCube(
- DdManager *dd,
- DdNode *f,
- DdNode *g,
- CUDD_VALUE_TYPE bound)
-{
- DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee;
- DdNode *ctt, *cee, *cte, *cet;
- CUDD_VALUE_TYPE minD, dtt, dee, dte, det;
- DdNode *one = DD_ONE(dd);
- DdNode *lzero = Cudd_Not(one);
- DdNode *azero = DD_ZERO(dd);
- unsigned int topf, topg, index;
-
- statLine(dd);
- if (bound < (f == Cudd_Not(g))) return(azero);
- /* Terminal cases. */
- if (g == lzero || f == lzero) return(azero);
- if (f == one && g == one) return(one);
-
- /* Check cache. */
- 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);
- }
-
- topf = cuddI(dd,F->index);
- topg = cuddI(dd,G->index);
-
- /* 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);
- }
- } else {
- 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);
- }
- } else {
- gt = ge = g;
- }
-
- tt = cuddBddClosestCube(dd,ft,gt,bound);
- if (tt == NULL) return(NULL);
- cuddRef(tt);
- ctt = separateCube(dd,tt,&dtt);
- if (ctt == NULL) {
- Cudd_RecursiveDeref(dd, tt);
- return(NULL);
- }
- cuddRef(ctt);
- Cudd_RecursiveDeref(dd, tt);
- minD = dtt;
- bound = ddMin(bound,minD);
-
- ee = cuddBddClosestCube(dd,fe,ge,bound);
- if (ee == 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);
- }
- cuddRef(cee);
- Cudd_RecursiveDeref(dd, ee);
- minD = ddMin(dtt, dee);
- 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);
- Cudd_RecursiveDeref(dd, te);
- return(NULL);
- }
- cuddRef(cte);
- Cudd_RecursiveDeref(dd, te);
- dte += 1.0;
- minD = ddMin(minD, dte);
- } else {
- cte = azero;
- cuddRef(cte);
- dte = CUDD_CONST_INDEX + 1.0;
- }
- 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);
- Cudd_RecursiveDeref(dd, et);
- return(NULL);
- }
- cuddRef(cet);
- Cudd_RecursiveDeref(dd, et);
- det += 1.0;
- minD = ddMin(minD, det);
- } else {
- 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);
- }
- } else if (minD == dee) {
- res = createResult(dd,index,0,cee,dee);
- } else if (minD == dte) {
- res = createResult(dd,index,(topf <= topg),cte,dte);
- } else {
- res = createResult(dd,index,(topf > topg),cet,det);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd, ctt);
- Cudd_RecursiveDeref(dd, cee);
- 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);
-
- cuddDeref(res);
- return(res);
-
-} /* end of cuddBddClosestCube */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_MinHammingDist.]
-
- Description [Performs the recursive step of Cudd_MinHammingDist.
- It is based on the following identity. Let H(f) be the
- minimum Hamming distance of the minterms of f from the reference
- minterm. Then:
- <xmp>
- H(f) = min(H(f0)+h0,H(f1)+h1)
- </xmp>
- where f0 and f1 are the two cofactors of f with respect to its top
- variable; h0 is 1 if the minterm assigns 1 to the top variable of f;
- h1 is 1 if the minterm assigns 0 to the top variable of f.
- The upper bound on the distance is used to bound the depth of the
- recursion.
- Returns the minimum distance unless it exceeds the upper bound or
- computation fails.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_MinHammingDist]
-
-******************************************************************************/
-static int
-cuddMinHammingDistRecur(
- DdNode * f,
- int *minterm,
- DdHashTable * table,
- int upperBound)
-{
- DdNode *F, *Ft, *Fe;
- double h, hT, hE;
- DdNode *zero, *res;
- DdManager *dd = table->manager;
-
- statLine(dd);
- if (upperBound == 0) return(0);
-
- F = Cudd_Regular(f);
-
- if (cuddIsConstant(F)) {
- 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);
- }
-
- Ft = cuddT(F); Fe = cuddE(F);
- if (Cudd_IsComplement(f)) {
- Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe);
- }
- if (minterm[F->index] == 0) {
- 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;
- } else {
- 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);
- }
- }
-
- return((int) h);
-
-} /* end of cuddMinHammingDistRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Separates cube from distance.]
-
- Description [Separates cube from distance. Returns the cube if
- successful; NULL otherwise.]
-
- SideEffects [The distance is returned as a side effect.]
-
- SeeAlso [cuddBddClosestCube createResult]
-
-******************************************************************************/
-static DdNode *
-separateCube(
- DdManager *dd,
- DdNode *f,
- CUDD_VALUE_TYPE *distance)
-{
- DdNode *cube, *t;
-
- /* 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);
- }
-
- /* Find out which branch points to the distance and replace the top
- ** node with one pointing to zero instead. */
- t = cuddT(f);
- if (Cudd_IsConstant(t) && cuddV(t) <= 0) {
-#ifdef DD_DEBUG
- assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd));
-#endif
- *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));
-#endif
- *distance = -cuddV(cuddE(f));
- cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd));
- }
-
- return(cube);
-
-} /* end of separateCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds a result for cache storage.]
-
- Description [Builds a result for cache storage. Returns a pointer
- to the resulting ADD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddBddClosestCube separateCube]
-
-******************************************************************************/
-static DdNode *
-createResult(
- DdManager *dd,
- unsigned int index,
- unsigned int phase,
- DdNode *cube,
- CUDD_VALUE_TYPE distance)
-{
- DdNode *res, *constant;
-
- /* 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. */
- if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube);
-
- constant = cuddUniqueConst(dd,-distance);
- if (constant == NULL) return(NULL);
- 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);
- }
- } else {
- /* Add a new top node. */
-#ifdef DD_DEBUG
- 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 (res == NULL) {
- Cudd_RecursiveDeref(dd, constant);
- return(NULL);
- }
- cuddDeref(constant); /* safe because constant is part of res */
-
- return(res);
-
-} /* end of createResult */
diff --git a/src/bdd/cudd/cuddRead.c b/src/bdd/cudd/cuddRead.c
deleted file mode 100644
index 2c4a86d8..00000000
--- a/src/bdd/cudd/cuddRead.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddRead.c]
-
- PackageName [cudd]
-
- Synopsis [Functions to read in a matrix]
-
- Description [External procedures included in this module:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Reads in a sparse matrix.]
-
- Description [Reads in a sparse matrix specified in a simple format.
- The first line of the input contains the numbers of rows and columns.
- The remaining lines contain the elements of the matrix, one per line.
- Given a background value
- (specified by the background field of the manager), only the values
- different from it are explicitly listed. Each foreground element is
- described by two integers, i.e., the row and column number, and a
- real number, i.e., the value.<p>
- Cudd_addRead produces an ADD that depends on two sets of variables: x
- and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and
- the y variables (y\[0\] ... y\[ny-1\]) encode the column index.
- x\[0\] and y\[0\] are the most significant bits in the indices.
- The variables may already exist or may be created by the function.
- The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.<p>
- On input, nx and ny hold the numbers
- of row and column variables already in existence. On output, they
- hold the numbers of row and column variables actually used by the
- matrix. When Cudd_addRead creates the variable arrays,
- the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.
- When some variables already exist Cudd_addRead expects the indices
- of the existing x variables to be bx+i*sx, and the indices of the
- existing y variables to be by+i*sy.<p>
- m and n are set to the numbers of rows and columns of the
- matrix. Their values on input are immaterial.
- The ADD for the
- sparse matrix is returned in E, and its reference count is > 0.
- Cudd_addRead returns 1 in case of success; 0 otherwise.]
-
- SideEffects [nx and ny are set to the numbers of row and column
- variables. m and n are set to the numbers of rows and columns. x and y
- are possibly extended to represent the array of row and column
- variables. Similarly for xn and yn_, which hold on return from
- Cudd_addRead the complements of the row and column variables.]
-
- SeeAlso [Cudd_addHarwell Cudd_bddRead]
-
-******************************************************************************/
-int
-Cudd_addRead(
- FILE * fp /* input file pointer */,
- DdManager * dd /* DD manager */,
- DdNode ** E /* characteristic function of the graph */,
- DdNode *** x /* array of row variables */,
- DdNode *** y /* array of column variables */,
- DdNode *** xn /* array of complemented row variables */,
- DdNode *** yn_ /* array of complemented column variables */,
- int * nx /* number or row variables */,
- int * ny /* number or column variables */,
- int * m /* number of rows */,
- int * n /* number of columns */,
- int bx /* first index of row variables */,
- int sx /* step of row variables */,
- int by /* first index of column variables */,
- int sy /* step of column variables */)
-{
- DdNode *one, *zero;
- DdNode *w, *neW;
- DdNode *minterm1;
- int u, v, err, i, nv;
- int lnx, lny;
- CUDD_VALUE_TYPE val;
- DdNode **lx, **ly, **lxn, **lyn;
-
- one = DD_ONE(dd);
- zero = DD_ZERO(dd);
-
- err = fscanf(fp, "%d %d", &u, &v);
- if (err == EOF) {
- return(0);
- } else if (err != 2) {
- return(0);
- }
-
- *m = u;
- /* Compute the number of x variables. */
- lx = *x; lxn = *xn;
- u--; /* row and column numbers start from 0 */
- for (lnx=0; u > 0; lnx++) {
- u >>= 1;
- }
- /* Here we rely on the fact that REALLOC of a null pointer is
- ** translates to an ALLOC.
- */
- if (lnx > *nx) {
- *x = lx = REALLOC(DdNode *, *x, lnx);
- if (lx == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *xn = lxn = 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 */
- for (lny=0; v > 0; lny++) {
- v >>= 1;
- }
- /* Here we rely on the fact that REALLOC of a null pointer is
- ** translates to an ALLOC.
- */
- if (lny > *ny) {
- *y = ly = REALLOC(DdNode *, *y, lny);
- if (ly == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- *yn_ = lyn = 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);
- cuddRef(lx[i]);
- 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]);
- }
- *nx = lnx;
- *ny = lny;
-
- *E = dd->background; /* this call will never cause reordering */
- 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);
- }
-
- 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;
- }
- 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;
- }
- /* 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;
- }
- return(1);
-
-} /* end of Cudd_addRead */
-
-
-/**Function********************************************************************
-
- Synopsis [Reads in a graph (without labels) given as a list of arcs.]
-
- Description [Reads in a graph (without labels) given as an adjacency
- matrix. The first line of the input contains the numbers of rows and
- columns of the adjacency matrix. The remaining lines contain the arcs
- of the graph, one per line. Each arc is described by two integers,
- i.e., the row and column number, or the indices of the two endpoints.
- Cudd_bddRead produces a BDD that depends on two sets of variables: x
- and y. The x variables (x\[0\] ... x\[nx-1\]) encode
- the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the
- column index. x\[0\] and y\[0\] are the most significant bits in the
- indices.
- The variables may already exist or may be created by the function.
- The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.<p>
- On input, nx and ny hold the numbers of row and column variables already
- in existence. On output, they hold the numbers of row and column
- variables actually used by the matrix. When Cudd_bddRead creates the
- variable arrays, the index of x\[i\] is bx+i*sx, and the index of
- y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead
- expects the indices of the existing x variables to be bx+i*sx, and the
- indices of the existing y variables to be by+i*sy.<p>
- m and n are set to the numbers of rows and columns of the
- matrix. Their values on input are immaterial. The BDD for the graph
- is returned in E, and its reference count is > 0. Cudd_bddRead returns
- 1 in case of success; 0 otherwise.]
-
- SideEffects [nx and ny are set to the numbers of row and column
- variables. m and n are set to the numbers of rows and columns. x and y
- are possibly extended to represent the array of row and column
- variables.]
-
- SeeAlso [Cudd_addHarwell Cudd_addRead]
-
-******************************************************************************/
-int
-Cudd_bddRead(
- FILE * fp /* input file pointer */,
- DdManager * dd /* DD manager */,
- DdNode ** E /* characteristic function of the graph */,
- DdNode *** x /* array of row variables */,
- DdNode *** y /* array of column variables */,
- int * nx /* number or row variables */,
- int * ny /* number or column variables */,
- int * m /* number of rows */,
- int * n /* number of columns */,
- int bx /* first index of row variables */,
- int sx /* step of row variables */,
- int by /* first index of column variables */,
- int sy /* step of column variables */)
-{
- DdNode *one, *zero;
- DdNode *w;
- DdNode *minterm1;
- int u, v, err, i, nv;
- int lnx, lny;
- DdNode **lx, **ly;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- err = fscanf(fp, "%d %d", &u, &v);
- if (err == EOF) {
- return(0);
- } else if (err != 2) {
- return(0);
- }
-
- *m = u;
- /* Compute the number of x variables. */
- lx = *x;
- u--; /* row and column numbers start from 0 */
- for (lnx=0; u > 0; lnx++) {
- u >>= 1;
- }
- if (lnx > *nx) {
- *x = lx = 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 */
- for (lny=0; v > 0; lny++) {
- v >>= 1;
- }
- if (lny > *ny) {
- *y = ly = 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);
- 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]);
- }
- *nx = lnx;
- *ny = lny;
-
- *E = zero; /* this call will never cause reordering */
- 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]));
- }
- if (w == NULL) {
- Cudd_RecursiveDeref(dd, minterm1);
- return(0);
- }
- 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]));
- }
- 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);
- }
- w = Cudd_Not(w);
- cuddRef(w);
- Cudd_RecursiveDeref(dd, minterm1);
- Cudd_RecursiveDeref(dd, *E);
- *E = w;
- }
- return(1);
-
-} /* end of Cudd_bddRead */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddRef.c b/src/bdd/cudd/cuddRef.c
deleted file mode 100644
index a9241f3d..00000000
--- a/src/bdd/cudd/cuddRef.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddRef.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Increases the reference count of a node, if it is not
- saturated.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_RecursiveDeref Cudd_Deref]
-
-******************************************************************************/
-void
-Cudd_Ref(
- DdNode * n)
-{
-
- n = Cudd_Regular(n);
-
- cuddSatInc(n->ref);
-
-} /* end of Cudd_Ref */
-
-
-/**Function********************************************************************
-
- Synopsis [Decreases the reference count of node n.]
-
- Description [Decreases the reference count of node n. If n dies,
- recursively decreases the reference counts of its children. It is
- used to dispose of a DD that is no longer needed.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd]
-
-******************************************************************************/
-void
-Cudd_RecursiveDeref(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack = table->stack;
- int SP = 1;
-
- unsigned int live = table->keys - table->dead;
- if (live > table->peakLiveNodes) {
- table->peakLiveNodes = live;
- }
-
- N = Cudd_Regular(n);
-
- do {
-#ifdef DD_DEBUG
- assert(N->ref != 0);
-#endif
-
- if (N->ref == 1) {
- N->ref = 0;
- table->dead++;
-#ifdef DD_STATS
- table->nodesDropped++;
-#endif
- 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 {
- cuddSatDec(N->ref);
- N = stack[--SP];
- }
- } while (SP != 0);
-
-} /* end of Cudd_RecursiveDeref */
-
-
-/**Function********************************************************************
-
- Synopsis [Decreases the reference count of BDD node n.]
-
- Description [Decreases the reference count of node n. If n dies,
- recursively decreases the reference counts of its children. It is
- used to dispose of a BDD that is no longer needed. It is more
- efficient than Cudd_RecursiveDeref, but it cannot be used on
- ADDs. The greater efficiency comes from being able to assume that no
- constant node will ever die as a result of a call to this
- procedure.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd]
-
-******************************************************************************/
-void
-Cudd_IterDerefBdd(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack = table->stack;
- int SP = 1;
-
- unsigned int live = table->keys - table->dead;
- if (live > table->peakLiveNodes) {
- table->peakLiveNodes = live;
- }
-
- N = Cudd_Regular(n);
-
- do {
-#ifdef DD_DEBUG
- assert(N->ref != 0);
-#endif
-
- if (N->ref == 1) {
- N->ref = 0;
- table->dead++;
-#ifdef DD_STATS
- 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);
-
-} /* end of Cudd_IterDerefBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Decreases the reference count of BDD node n.]
-
- Description [Enqueues node n for later dereferencing. If the queue
- is full decreases the reference count of the oldest node N to make
- room for n. If N dies, recursively decreases the reference counts of
- its children. It is used to dispose of a BDD that is currently not
- needed, but may be useful again in the near future. The dereferencing
- proper is done as in Cudd_IterDerefBdd.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd]
-
-******************************************************************************/
-void
-Cudd_DelayedDerefBdd(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack;
- int SP;
-
- unsigned int live = table->keys - table->dead;
- if (live > table->peakLiveNodes) {
- table->peakLiveNodes = live;
- }
-
- n = Cudd_Regular(n);
-#ifdef DD_DEBUG
- assert(n->ref != 0);
-#endif
-
-#ifdef DD_NO_DEATH_ROW
- N = n;
-#else
- if (cuddIsConstant(n) || n->ref > 1) {
-#ifdef DD_DEBUG
- assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
-#endif
- cuddSatDec(n->ref);
- return;
- }
-
- N = table->deathRow[table->nextDead];
-
- if (N != NULL) {
-#endif
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(N));
-#endif
- stack = table->stack;
- SP = 1;
- do {
-#ifdef DD_DEBUG
- assert(N->ref != 0);
-#endif
- if (N->ref == 1) {
- N->ref = 0;
- table->dead++;
-#ifdef DD_STATS
- 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);
-#ifndef DD_NO_DEATH_ROW
- }
- table->deathRow[table->nextDead] = n;
-
- /* Udate insertion point. */
- table->nextDead++;
- 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 = 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 {
- table->nextDead = 0;
- }
- }
-#endif
-#endif
-
-} /* end of Cudd_DelayedDerefBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Decreases the reference count of ZDD node n.]
-
- Description [Decreases the reference count of ZDD node n. If n dies,
- recursively decreases the reference counts of its children. It is
- used to dispose of a ZDD that is no longer needed.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref]
-
-******************************************************************************/
-void
-Cudd_RecursiveDerefZdd(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack = table->stack;
- int SP = 1;
-
- N = n;
-
- do {
-#ifdef DD_DEBUG
- assert(N->ref != 0);
-#endif
-
- cuddSatDec(N->ref);
-
- if (N->ref == 0) {
- table->deadZ++;
-#ifdef DD_STATS
- table->nodesDropped++;
-#endif
-#ifdef DD_DEBUG
- assert(!cuddIsConstant(N));
-#endif
- 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 */
-
-
-/**Function********************************************************************
-
- Synopsis [Decreases the reference count of node.]
-
- Description [Decreases the reference count of node. It is primarily
- used in recursive procedures to decrease the ref count of a result
- node before returning it. This accomplishes the goal of removing the
- protection applied by a previous Cudd_Ref.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref]
-
-******************************************************************************/
-void
-Cudd_Deref(
- DdNode * node)
-{
- node = Cudd_Regular(node);
- cuddSatDec(node->ref);
-
-} /* end of Cudd_Deref */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the unique table for nodes with non-zero reference
- counts.]
-
- Description [Checks the unique table for nodes with non-zero
- reference counts. It is normally called before Cudd_Quit to make sure
- that there are no memory leaks due to missing Cudd_RecursiveDeref's.
- Takes into account that reference counts may saturate and that the
- basic constants and the projection functions are referenced by the
- manager. Returns the number of nodes with non-zero reference count.
- (Except for the cases mentioned above.)]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_CheckZeroRef(
- DdManager * manager)
-{
- int size;
- int i, j;
- int remain; /* the expected number of remaining references to one */
- DdNodePtr *nodelist;
- DdNode *node;
- DdNode *sentinel = &(manager->sentinel);
- DdSubtable *subtable;
- int count = 0;
- int index;
-
-#ifndef DD_NO_DEATH_ROW
- cuddClearDeathRow(manager);
-#endif
-
- /* 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 */
-
- 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++;
- }
- }
- }
- node = node->next;
- }
- }
- }
-
- /* Then look at the ZDD subtables. */
- size = manager->sizeZ;
- if (size) /* references from ZDD universe */
- 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++;
- }
- }
- node = node->next;
- }
- }
- }
-
- /* Now examine the constant table. Plusinfinity, minusinfinity, and
- ** zero are referenced by the manager. One is referenced by the
- ** manager, by the ZDD universe, and by all projection functions.
- ** All other nodes should have no references.
- */
- 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++;
- }
- } else {
- count++;
- }
- }
- node = node->next;
- }
- }
- return(count);
-
-} /* end of Cudd_CheckZeroRef */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Brings children of a dead node back.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddReclaimZdd]
-
-******************************************************************************/
-void
-cuddReclaim(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack = table->stack;
- int SP = 1;
- double initialDead = table->dead;
-
- N = Cudd_Regular(n);
-
-#ifdef DD_DEBUG
- assert(N->ref == 0);
-#endif
-
- do {
- 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 {
- cuddSatInc(N->ref);
- N = stack[--SP];
- }
- } while (SP != 0);
-
- N = Cudd_Regular(n);
- cuddSatDec(N->ref);
- table->reclaimed += initialDead - table->dead;
-
-} /* end of cuddReclaim */
-
-
-/**Function********************************************************************
-
- Synopsis [Brings children of a dead ZDD node back.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddReclaim]
-
-******************************************************************************/
-void
-cuddReclaimZdd(
- DdManager * table,
- DdNode * n)
-{
- DdNode *N;
- int ord;
- DdNodePtr *stack = table->stack;
- int SP = 1;
-
- N = n;
-
-#ifdef DD_DEBUG
- assert(N->ref == 0);
-#endif
-
- do {
- cuddSatInc(N->ref);
-
- if (N->ref == 1) {
- table->deadZ--;
- table->reclaimed++;
-#ifdef DD_DEBUG
- assert(!cuddIsConstant(N));
-#endif
- 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);
-
-} /* end of cuddReclaimZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Shrinks the death row.]
-
- Description [Shrinks the death row by a factor of four.]
-
- SideEffects [None]
-
- SeeAlso [cuddClearDeathRow]
-
-******************************************************************************/
-void
-cuddShrinkDeathRow(
- DdManager *table)
-{
-#ifndef DD_NO_DEATH_ROW
- 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 = REALLOC(DdNodePtr, table->deathRow,
- table->deathRowDepth);
- }
-#endif
-
-} /* end of cuddShrinkDeathRow */
-
-
-/**Function********************************************************************
-
- Synopsis [Clears the death row.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef
- cuddGarbageCollect]
-
-******************************************************************************/
-void
-cuddClearDeathRow(
- DdManager *table)
-{
-#ifndef DD_NO_DEATH_ROW
- 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;
- }
-#ifdef DD_DEBUG
- for (; i < table->deathRowDepth; i++) {
- assert(table->deathRow[i] == NULL);
- }
-#endif
- table->nextDead = 0;
-#endif
-
-} /* end of cuddClearDeathRow */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks whether a node is in the death row.]
-
- Description [Checks whether a node is in the death row. Returns the
- position of the first occurrence if the node is present; -1
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow]
-
-******************************************************************************/
-int
-cuddIsInDeathRow(
- DdManager *dd,
- DdNode *f)
-{
-#ifndef DD_NO_DEATH_ROW
- int i;
-
- for (i = 0; i < dd->deathRowDepth; i++) {
- if (f == dd->deathRow[i]) {
- return(i);
- }
- }
-#endif
-
- return(-1);
-
-} /* end of cuddIsInDeathRow */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts how many times a node is in the death row.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow]
-
-******************************************************************************/
-int
-cuddTimesInDeathRow(
- DdManager *dd,
- DdNode *f)
-{
- int count = 0;
-#ifndef DD_NO_DEATH_ROW
- int i;
-
- for (i = 0; i < dd->deathRowDepth; i++) {
- count += f == dd->deathRow[i];
- }
-#endif
-
- return(count);
-
-} /* end of cuddTimesInDeathRow */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
diff --git a/src/bdd/cudd/cuddReorder.c b/src/bdd/cudd/cuddReorder.c
deleted file mode 100644
index 1387196f..00000000
--- a/src/bdd/cudd/cuddReorder.c
+++ /dev/null
@@ -1,2090 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddReorder.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_MAX_SUBTABLE_SPARSITY 8
-#define DD_SHRINK_FACTOR 2
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static int *entry;
-
-int ddTotalNumberSwapping;
-#ifdef DD_STATS
-int ddTotalNISwaps;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Main dynamic reordering routine.]
-
- Description [Main dynamic reordering routine.
- Calls one of the possible reordering procedures:
- <ul>
- <li>Swapping
- <li>Sifting
- <li>Symmetric Sifting
- <li>Group Sifting
- <li>Window Permutation
- <li>Simulated Annealing
- <li>Genetic Algorithm
- <li>Dynamic Programming (exact)
- </ul>
-
- For sifting, symmetric sifting, group sifting, and window
- permutation it is possible to request reordering to convergence.<p>
-
- The core of all methods is the reordering procedure
- cuddSwapInPlace() which swaps two adjacent variables and is based
- on Rudell's paper.
- Returns 1 in case of success; 0 otherwise. In the case of symmetric
- sifting (with and without convergence) returns 1 plus the number of
- symmetric variables, in case of success.]
-
- SideEffects [Changes the variable order for all diagrams and clears
- the cache.]
-
-******************************************************************************/
-int
-Cudd_ReduceHeap(
- DdManager * table /* DD manager */,
- Cudd_ReorderingType heuristic /* method used for reordering */,
- int minsize /* bound below which no reordering occurs */)
-{
- DdHook *hook;
- int result;
- unsigned int nextDyn;
-#ifdef DD_STATS
- unsigned int initialSize;
- unsigned int finalSize;
-#endif
- long localTime;
-
- /* Don't reorder if there are too many dead nodes. */
- if (table->keys - table->dead < (unsigned) minsize)
- return(1);
-
- if (heuristic == CUDD_REORDER_SAME) {
- heuristic = table->autoMethod;
- }
- if (heuristic == CUDD_REORDER_NONE) {
- return(1);
- }
-
- /* This call to Cudd_ReduceHeap does initiate reordering. Therefore
- ** we count it.
- */
- table->reorderings++;
-
- localTime = util_cpu_time();
-
- /* 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;
- }
-
- if (!ddReorderPreprocess(table)) return(0);
- ddTotalNumberSwapping = 0;
-
- if (table->keys > table->peakLiveNodes) {
- table->peakLiveNodes = table->keys;
- }
-#ifdef DD_STATS
- initialSize = table->keys - table->isolated;
- ddTotalNISwaps = 0;
-
- switch(heuristic) {
- case CUDD_REORDER_RANDOM:
- case CUDD_REORDER_RANDOM_PIVOT:
- (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;
- 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;
- case CUDD_REORDER_ANNEALING:
- (void) fprintf(table->out,"#:I_ANNEAL ");
- break;
- case CUDD_REORDER_GENETIC:
- (void) fprintf(table->out,"#:I_GENETIC ");
- break;
- case CUDD_REORDER_LINEAR:
- case CUDD_REORDER_LINEAR_CONVERGE:
- (void) fprintf(table->out,"#:I_LINSIFT ");
- break;
- case CUDD_REORDER_EXACT:
- (void) fprintf(table->out,"#:I_EXACT ");
- break;
- default:
- return(0);
- }
- (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);
- table->maxGrowth = saveGrowth;
- } else {
- 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,"#:T_REORDER %8g: total time (sec)\n",
- ((double)(util_cpu_time() - localTime)/1000.0));
- (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
- ddTotalNumberSwapping);
- (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps);
-#endif
-
- if (result == 0)
- return(0);
-
- if (!ddReorderPostprocess(table))
- return(0);
-
- if (table->realign) {
- if (!cuddZddAlignToBdd(table))
- return(0);
- }
-
- nextDyn = (table->keys - table->constants.keys + 1) *
- DD_DYN_RATIO + table->constants.keys;
- if (table->reorderings < 20 || nextDyn > table->nextDyn)
- table->nextDyn = nextDyn;
- else
- 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;
- }
- /* Update cumulative reordering time. */
- table->reordTime += util_cpu_time() - localTime;
-
- return(result);
-
-} /* end of Cudd_ReduceHeap */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders variables according to given permutation.]
-
- Description [Reorders variables according to given permutation.
- The i-th entry of the permutation array contains the index of the variable
- that should be brought to the i-th level. The size of the array should be
- equal or greater to the number of variables currently in use.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [Changes the variable order for all diagrams and clears
- the cache.]
-
- SeeAlso [Cudd_ReduceHeap]
-
-******************************************************************************/
-int
-Cudd_ShuffleHeap(
- DdManager * table /* DD manager */,
- int * permutation /* required variable permutation */)
-{
-
- 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 (identity == 1) {
- return(1);
- }
- if (!ddReorderPreprocess(table)) return(0);
- if (table->keys > table->peakLiveNodes) {
- table->peakLiveNodes = table->keys;
- }
-
- perm = ALLOC(int, table->size);
- for (i = 0; i < table->size; i++)
- perm[permutation[i]] = i;
- if (!ddCheckPermuation(table,table->tree,perm,permutation)) {
- FREE(perm);
- return(0);
- }
- if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) {
- FREE(perm);
- return(0);
- }
- FREE(perm);
-
- result = ddShuffle(table,permutation);
-
- if (!ddReorderPostprocess(table)) return(0);
-
- return(result);
-
-} /* end of Cudd_ShuffleHeap */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Dynamically allocates a Node.]
-
- Description [Dynamically allocates a Node. This procedure is similar
- to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage
- collection, because during reordering there are no dead nodes.
- Returns a pointer to a new node if successful; NULL is memory is
- full.]
-
- SideEffects [None]
-
- SeeAlso [cuddAllocNode]
-
-******************************************************************************/
-DdNode *
-cuddDynamicAllocNode(
- DdManager * table)
-{
- int i;
- DdNodePtr *mem;
- DdNode *list, *node;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- if (table->nextFree == NULL) { /* free list is empty */
- /* Try to allocate a new block. */
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1);
- MMoutOfMemory = saveHandler;
- if (mem == NULL && table->stash != NULL) {
- FREE(table->stash);
- table->stash = NULL;
- /* Inhibit resizing of tables. */
- table->maxCacheHard = table->cacheSlots - 1;
- table->cacheSlack = -(table->cacheSlots + 1);
- for (i = 0; i < table->size; i++) {
- table->subtables[i].maxKeys <<= 2;
- }
- mem = (DdNodePtr *) 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;
-#ifdef DD_VERBOSE
- (void) fprintf(table->err,
- "cuddDynamicAllocNode: out of memory");
- (void) fprintf(table->err,"Memory in use = %ld\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);
-#ifdef DD_DEBUG
- assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0);
-#endif
- list = (DdNode *) mem;
-
- i = 1;
- do {
- list[i - 1].next = &list[i];
- } while (++i < DD_MEM_CHUNK);
-
- list[DD_MEM_CHUNK - 1].next = NULL;
-
- table->nextFree = &list[0];
- }
- } /* if free list empty */
-
- node = table->nextFree;
- table->nextFree = node->next;
- return (node);
-
-} /* end of cuddDynamicAllocNode */
-
-
-/**Function********************************************************************
-
- Synopsis [Implementation of Rudell's sifting algorithm.]
-
- Description [Implementation of Rudell's sifting algorithm.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries
- in each unique table.
- <li> Sift the variable up and down, remembering each time the
- total size of the DD heap.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- size = table->size;
-
- /* Find order in which to sift variables. */
- var = NULL;
- entry = ALLOC(int,size);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddSiftingOutOfMem;
- }
- var = ALLOC(int,size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))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;
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
- 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);
-#endif
- }
-
- FREE(var);
- FREE(entry);
-
- return(1);
-
-cuddSiftingOutOfMem:
-
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddSifting */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]
-
- Description [Implementation of Plessier's algorithm that reorders
- variables by a sequence of (non-adjacent) swaps.
- <ol>
- <li> Select two variables (RANDOM or HEURISTIC).
- <li> Permute these variables.
- <li> If the nodes have decreased accept the permutation.
- <li> Otherwise reconstruct the original heap.
- <li> Loop.
- </ol>
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddSwapping(
- DdManager * table,
- int lower,
- int upper,
- Cudd_ReorderingType heuristic)
-{
- int i, j;
- int max, keys;
- int nvars;
- int x, y;
- int iterate;
- int previousSize;
- Move *moves, *move;
- int pivot;
- int modulo;
- int result;
-
-#ifdef DD_DEBUG
- /* Sanity check */
- assert(lower >= 0 && upper < table->size && lower <= upper);
-#endif
-
- nvars = upper - lower + 1;
- 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;
- }
- }
-
- 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);
- }
- } 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);
-#endif
-#if 0
- (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n",
- table->keys - table->isolated);
-#endif
- }
-
- return(1);
-
-cuddSwappingOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
-
- return(0);
-
-} /* end of cuddSwapping */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the next subtable with a larger index.]
-
- Description [Finds the next subtable with a larger index. Returns the
- index.]
-
- SideEffects [None]
-
- SeeAlso [cuddNextLow]
-
-******************************************************************************/
-int
-cuddNextHigh(
- DdManager * table,
- int x)
-{
- return(x+1);
-
-} /* end of cuddNextHigh */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the next subtable with a smaller index.]
-
- Description [Finds the next subtable with a smaller index. Returns the
- index.]
-
- SideEffects [None]
-
- SeeAlso [cuddNextHigh]
-
-******************************************************************************/
-int
-cuddNextLow(
- DdManager * table,
- int x)
-{
- return(x-1);
-
-} /* end of cuddNextLow */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two adjacent variables.]
-
- Description [Swaps two adjacent variables. It assumes that no dead
- nodes are present on entry to this procedure. The procedure then
- guarantees that no dead nodes will be present when it terminates.
- cuddSwapInPlace assumes that x &lt; y. Returns the number of keys in
- the table if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddSwapInPlace(
- 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;
- Cudd_VariableType varType;
- Cudd_LazyGroupType groupType;
- int posn;
- int isolated;
- DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
- DdNode *g,*next;
- DdNodePtr *previousP;
- DdNode *tmp;
- DdNode *sentinel = &(table->sentinel);
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
-#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
-
- ddTotalNumberSwapping++;
-
- /* Get parameters of x subtable. */
- xindex = table->invperm[x];
- 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. */
- yindex = table->invperm[y];
- ylist = table->subtables[y].nodelist;
- oldykeys = table->subtables[y].keys;
- yslots = table->subtables[y].slots;
- yshift = table->subtables[y].shift;
-
- if (!cuddTestInteract(table,xindex,yindex)) {
-#ifdef DD_STATS
- ddTotalNISwaps++;
-#endif
- 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));
-
- /* 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. */
- 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 = 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);
- 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;
-#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);
-#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 == 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)));
-#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));
- cuddSatDec(tmp->ref);
- cuddDeallocNode(table,f);
- newykeys--;
- } else {
- *previousP = f;
- previousP = &(f->next);
- }
- f = next;
- } /* while f */
- *previousP = sentinel;
- } /* for i */
-
-#if DD_DEBUG
-#if 0
- (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;
- }
- }
- 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 != 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;
- }
-
- /* Set the appropriate fields in table. */
- table->subtables[x].nodelist = ylist;
- table->subtables[x].slots = yslots;
- table->subtables[x].shift = yshift;
- table->subtables[x].keys = newykeys;
- table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
- i = table->subtables[x].bindVar;
- table->subtables[x].bindVar = table->subtables[y].bindVar;
- table->subtables[y].bindVar = i;
- /* Adjust filds for lazy sifting. */
- varType = table->subtables[x].varType;
- table->subtables[x].varType = table->subtables[y].varType;
- table->subtables[y].varType = varType;
- i = table->subtables[x].pairIndex;
- table->subtables[x].pairIndex = table->subtables[y].pairIndex;
- table->subtables[y].pairIndex = i;
- i = table->subtables[x].varHandled;
- table->subtables[x].varHandled = table->subtables[y].varHandled;
- table->subtables[y].varHandled = i;
- groupType = table->subtables[x].varToBeGrouped;
- table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped;
- table->subtables[y].varToBeGrouped = groupType;
-
- table->subtables[y].nodelist = xlist;
- table->subtables[y].slots = xslots;
- table->subtables[y].shift = xshift;
- table->subtables[y].keys = newxkeys;
- table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
-
- table->perm[xindex] = y; table->perm[yindex] = x;
- table->invperm[x] = yindex; table->invperm[y] = xindex;
-
- table->keys += newxkeys + newykeys - oldxkeys - oldykeys;
-
- return(table->keys - table->isolated);
-
-cuddSwapOutOfMem:
- (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n");
-
- return (0);
-
-} /* end of cuddSwapInPlace */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders BDD variables according to the order of the ZDD
- variables.]
-
- Description [Reorders BDD variables according to the order of the
- ZDD variables. This function can be called at the end of ZDD
- reordering to insure that the order of the BDD variables is
- consistent with the order of the ZDD variables. The number of ZDD
- variables must be a multiple of the number of BDD variables. Let
- <code>M</code> be the ratio of the two numbers. cuddBddAlignToZdd
- then considers the ZDD variables from <code>M*i</code> to
- <code>(M+1)*i-1</code> as corresponding to BDD variable
- <code>i</code>. This function should be normally called from
- Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [Changes the BDD variable order for all diagrams and performs
- garbage collection of the BDD unique table.]
-
- SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap]
-
-******************************************************************************/
-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 */
-
- /* We assume that a ratio of 0 is OK. */
- if (table->size == 0)
- 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);
- /* Create and initialize the inverse permutation array. */
- invperm = ALLOC(int,table->size);
- if (invperm == NULL) {
- 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;
- }
- /* Eliminate dead nodes. Do not scan the cache again, because we
- ** assume that Cudd_zddReduceHeap has already cleared it.
- */
- cuddGarbageCollect(table,0);
-
- /* Initialize number of isolated projection functions. */
- table->isolated = 0;
- for (i = 0; i < table->size; i++) {
- if (table->vars[i]->ref == 1) table->isolated++;
- }
-
- /* Initialize the interaction matrix. */
- result = cuddInitInteract(table);
- if (result == 0) return(0);
-
- result = ddShuffle(table, invperm);
- FREE(invperm);
- /* Free interaction matrix. */
- FREE(table->interact);
- /* Fix the BDD variable group tree. */
- bddFixTree(table,table->tree);
- return(result);
-
-} /* end of cuddBddAlignToZdd */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the
- variables according to the number of keys in the subtables.
- Returns the difference in number of keys between the two
- variables being compared.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddUniqueCompare(
- int * ptrX,
- int * ptrY)
-{
-#if 0
- if (entry[*ptrY] == entry[*ptrX]) {
- return((*ptrX) - (*ptrY));
- }
-#endif
- return(entry[*ptrY] - entry[*ptrX]);
-
-} /* end of ddUniqueCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps any two variables.]
-
- Description [Swaps any two variables. Returns the set of moves.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddSwapAny(
- DdManager * table,
- int x,
- int y)
-{
- Move *move, *moves;
- int xRef,yRef;
- int xNext,yNext;
- int size;
- int limitSize;
- int tmp;
-
- if (x >y) {
- tmp = x; x = y; y = tmp;
- }
-
- xRef = x; yRef = y;
-
- xNext = cuddNextHigh(table,x);
- yNext = cuddNextLow(table,y);
- moves = NULL;
- 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;
-
- 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;
- }
-
- 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;
- }
- return(NULL);
-
-} /* end of ddSwapAny */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSiftingAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
-
- Move *move;
- Move *moveUp; /* list of up moves */
- Move *moveDown; /* list of down moves */
- int initialSize;
- int result;
-
- initialSize = table->keys - table->isolated;
-
- moveDown = NULL;
- 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;
-
- } 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;
-
- } 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;
-
- } 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;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) 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;
- }
- }
- if (moveUp != (Move *) CUDD_OUT_OF_MEM) {
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
- }
-
- return(0);
-
-} /* end of ddSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable up.]
-
- Description [Sifts a variable up. Moves y up until either it reaches
- the bound (xLow) or the size of the DD heap increases too much.
- Returns the set of moves in case of success; NULL if memory is full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddSiftingUp(
- DdManager * table,
- 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 */
-#ifdef DD_DEBUG
- int checkL;
- int z;
- int zindex;
-#endif
-
- moves = NULL;
- yindex = table->invperm[y];
-
- /* Initialize the lower bound.
- ** The part of the DD below y will not change.
- ** The part of the DD above y that does not interact with y will not
- ** change. The rest may vanish in the best case, except for
- ** the nodes at level xLow, which will not vanish, regardless.
- */
- 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;
- }
- }
- 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];
-#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;
- }
- }
- 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);
- }
- return(moves);
-
-ddSiftingUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of ddSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable down.]
-
- Description [Sifts a variable down. Moves x down until either it
- reaches the bound (xHigh) or the size of the DD heap increases too
- much. Returns the set of moves in case of success; NULL if memory is
- full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddSiftingDown(
- DdManager * table,
- 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;
-#ifdef DD_DEBUG
- int checkR;
- int z;
- int zindex;
-#endif
-
- moves = NULL;
- /* Initialize R */
- xindex = table->invperm[x];
- 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;
- }
- }
-
- 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;
- }
- }
- 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);
- }
- return(moves);
-
-ddSiftingDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of ddSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the DD heap to the position
- giving the minimum size.]
-
- Description [Given a set of moves, returns the DD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSiftingBackward(
- DdManager * table,
- int size,
- Move * moves)
-{
- Move *move;
- int res;
-
- for (move = moves; move != NULL; move = move->next) {
- 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);
- }
-
- return(1);
-
-} /* end of ddSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Prepares the DD heap for dynamic reordering.]
-
- Description [Prepares the DD heap for dynamic reordering. Does
- garbage collection, to guarantee that there are no dead nodes;
- clears the cache, which is invalidated by dynamic reordering; initializes
- the number of isolated projection functions; and initializes the
- interaction matrix. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddReorderPreprocess(
- DdManager * table)
-{
- int i;
- int res;
-
- /* Clear the cache. */
- cuddCacheFlush(table);
- cuddLocalCacheClearAll(table);
-
- /* Eliminate dead nodes. Do not scan the cache again. */
- cuddGarbageCollect(table,0);
-
- /* Initialize number of isolated projection functions. */
- table->isolated = 0;
- for (i = 0; i < table->size; i++) {
- if (table->vars[i]->ref == 1) table->isolated++;
- }
-
- /* Initialize the interaction matrix. */
- res = cuddInitInteract(table);
- if (res == 0) return(0);
-
- return(1);
-
-} /* end of ddReorderPreprocess */
-
-
-/**Function********************************************************************
-
- Synopsis [Cleans up at the end of reordering.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddReorderPostprocess(
- DdManager * table)
-{
-
-#ifdef DD_VERBOSE
- (void) fflush(table->out);
-#endif
-
- /* Free interaction matrix. */
- FREE(table->interact);
-
- return(1);
-
-} /* end of ddReorderPostprocess */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders variables according to a given permutation.]
-
- Description [Reorders variables according to a given permutation.
- The i-th permutation array contains the index of the variable that
- should be brought to the i-th level. ddShuffle assumes that no
- dead nodes are present and that the interaction matrix is properly
- initialized. The reordering is achieved by a series of upward sifts.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddShuffle(
- DdManager * table,
- int * permutation)
-{
- int index;
- int level;
- int position;
- int numvars;
- int result;
-#ifdef DD_STATS
- long localTime;
- int initialSize;
- int finalSize;
- int previousSize;
-#endif
-
- ddTotalNumberSwapping = 0;
-#ifdef DD_STATS
- localTime = util_cpu_time();
- initialSize = table->keys - table->isolated;
- (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n",
- initialSize);
- ddTotalNISwaps = 0;
-#endif
-
- numvars = table->size;
-
- for (level = 0; level < numvars; level++) {
- index = permutation[level];
- position = table->perm[index];
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
- 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);
-#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,"#:T_SHUFFLE %8g: total time (sec)\n",
- ((double)(util_cpu_time() - localTime)/1000.0));
- (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n",
- ddTotalNumberSwapping);
- (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps);
-#endif
-
- return(1);
-
-} /* end of ddShuffle */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves one variable up.]
-
- Description [Takes a variable from position x and sifts it up to
- position xLow; xLow should be less than or equal to x.
- Returns 1 if successful; 0 otherwise]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddSiftUp(
- DdManager * table,
- int x,
- int xLow)
-{
- int y;
- int size;
-
- y = cuddNextLow(table,x);
- while (y >= xLow) {
- size = cuddSwapInPlace(table,y,x);
- if (size == 0) {
- return(0);
- }
- x = y;
- y = cuddNextLow(table,x);
- }
- return(1);
-
-} /* end of ddSiftUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Fixes the BDD variable group tree after a shuffle.]
-
- Description [Fixes the BDD variable group tree after a
- shuffle. Assumes that the order of the variables in a terminal node
- has not been changed.]
-
- SideEffects [Changes the BDD variable group tree.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-bddFixTree(
- DdManager * table,
- MtrNode * treenode)
-{
- if (treenode == NULL) return;
- treenode->low = ((int) treenode->index < table->size) ?
- table->perm[treenode->index] : treenode->index;
- if (treenode->child != NULL) {
- bddFixTree(table, treenode->child);
- }
- if (treenode->younger != NULL)
- bddFixTree(table, treenode->younger);
- if (treenode->parent != NULL && treenode->low < treenode->parent->low) {
- treenode->parent->low = treenode->low;
- treenode->parent->index = treenode->index;
- }
- return;
-
-} /* end of bddFixTree */
-
-
-/**Function********************************************************************
-
- Synopsis [Updates the BDD variable group tree before a shuffle.]
-
- Description [Updates the BDD variable group tree before a shuffle.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [Changes the BDD variable group tree.]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddUpdateMtrTree(
- DdManager * table,
- MtrNode * treenode,
- int * perm,
- int * invperm)
-{
- int i, size, index, level;
- int minLevel, maxLevel, minIndex;
-
- if (treenode == NULL) return(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;
- }
- size = maxLevel - minLevel + 1;
- if (size == treenode->size) {
- treenode->low = minLevel;
- treenode->index = minIndex;
- } else
- return(0);
-
- if (treenode->child != NULL) {
- if (!ddUpdateMtrTree(table, treenode->child, perm, invperm))
- return(0);
- }
- if (treenode->younger != NULL) {
- if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm))
- return(0);
- }
- return(1);
-}
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the BDD variable group tree before a shuffle.]
-
- Description [Checks the BDD variable group tree before a shuffle.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [Changes the BDD variable group tree.]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-ddCheckPermuation(
- DdManager * table,
- MtrNode * treenode,
- int * perm,
- int * invperm)
-{
- int i, size, index, level;
- int minLevel, maxLevel;
-
- if (treenode == NULL) return(1);
-
- minLevel = table->size;
- 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;
- }
- size = maxLevel - minLevel + 1;
- if (size != treenode->size)
- return(0);
-
- if (treenode->child != NULL) {
- if (!ddCheckPermuation(table, treenode->child, perm, invperm))
- return(0);
- }
- if (treenode->younger != NULL) {
- if (!ddCheckPermuation(table, treenode->younger, perm, invperm))
- return(0);
- }
- return(1);
-}
diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c
deleted file mode 100644
index 1755a1c1..00000000
--- a/src/bdd/cudd/cuddSat.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSat.c]
-
- PackageName [cudd]
-
- Synopsis [Functions for the solution of satisfiability related
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_BIGGY 1000000
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-typedef struct cuddPathPair {
- int pos;
- int neg;
-} cuddPathPair;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static DdNode *one, *zero;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col])
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the value of a DD for a given variable assignment.]
-
- Description [Finds the value of a DD for a given variable
- assignment. The variable assignment is passed in an array of int's,
- that should specify a zero or a one for each variable in the support
- of the function. Returns a pointer to a constant node. No new nodes
- are produced.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLeq Cudd_addEvalConst]
-
-******************************************************************************/
-DdNode *
-Cudd_Eval(
- DdManager * dd,
- DdNode * f,
- int * inputs)
-{
- int comple;
- DdNode *ptr;
-
- comple = Cudd_IsComplement(f);
- 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));
- }
- }
- return(Cudd_NotCond(ptr,comple));
-
-} /* end of Cudd_Eval */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a shortest path in a DD.]
-
- Description [Finds a shortest path in a DD. f is the DD we want to
- get the shortest path for; weight\[i\] is the weight of the THEN arc
- coming from the node whose index is i. If weight is NULL, then unit
- weights are assumed for all THEN arcs. All ELSE arcs have 0 weight.
- If non-NULL, both weight and support should point to arrays with at
- least as many entries as there are variables in the manager.
- Returns the shortest path as the BDD of a cube.]
-
- SideEffects [support contains on return the true support of f.
- If support is NULL on entry, then Cudd_ShortestPath does not compute
- the true support info. length contains the length of the path.]
-
- SeeAlso [Cudd_ShortestLength Cudd_LargestCube]
-
-******************************************************************************/
-DdNode *
-Cudd_ShortestPath(
- DdManager * manager,
- DdNode * f,
- int * weight,
- int * support,
- int * length)
-{
- register DdNode *F;
- st_table *visited;
- DdNode *sol;
- cuddPathPair *rootPair;
- int complement, cost;
- int i;
-
- one = DD_ONE(manager);
- zero = DD_ZERO(manager);
-
- /* Initialize support. */
- if (support) {
- for (i = 0; i < manager->size; i++) {
- support[i] = 0;
- }
- }
-
- if (f == Cudd_Not(one) || f == zero) {
- *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);
-
- /* Now get the length of the shortest path(s) from f to 1. */
- (void) getShortest(f, weight, support, visited);
-
- complement = Cudd_IsComplement(f);
-
- F = Cudd_Regular(f);
-
- st_lookup(visited, (char *)F, (char **)&rootPair);
-
- if (complement) {
- cost = rootPair->neg;
- } else {
- cost = rootPair->pos;
- }
-
- /* Recover an actual shortest path. */
- do {
- manager->reordered = 0;
- sol = getPath(manager,visited,f,weight,cost);
- } while (manager->reordered == 1);
-
- st_foreach(visited, freePathPair, NULL);
- st_free_table(visited);
-
- *length = cost;
- return(sol);
-
-} /* end of Cudd_ShortestPath */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a largest cube in a DD.]
-
- Description [Finds a largest cube in a DD. f is the DD we want to
- get the largest cube for. The problem is translated into the one of
- finding a shortest path in f, when both THEN and ELSE arcs are assumed to
- have unit length. This yields a largest cube in the disjoint cover
- corresponding to the DD. Therefore, it is not necessarily the largest
- implicant of f. Returns the largest cube as a BDD.]
-
- SideEffects [The number of literals of the cube is returned in length.]
-
- SeeAlso [Cudd_ShortestPath]
-
-******************************************************************************/
-DdNode *
-Cudd_LargestCube(
- DdManager * manager,
- DdNode * f,
- int * length)
-{
- register DdNode *F;
- st_table *visited;
- DdNode *sol;
- cuddPathPair *rootPair;
- 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));
- }
- /* From this point on, a path exists. */
-
- /* Initialize visited table. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
-
- /* Now get the length of the shortest path(s) from f to 1. */
- (void) getLargest(f, visited);
-
- complement = Cudd_IsComplement(f);
-
- F = Cudd_Regular(f);
-
- st_lookup(visited, (char *)F, (char **)&rootPair);
-
- if (complement) {
- cost = rootPair->neg;
- } else {
- cost = rootPair->pos;
- }
-
- /* Recover an actual shortest path. */
- do {
- manager->reordered = 0;
- sol = getCube(manager,visited,f,cost);
- } while (manager->reordered == 1);
-
- st_foreach(visited, freePathPair, NULL);
- st_free_table(visited);
-
- *length = cost;
- return(sol);
-
-} /* end of Cudd_LargestCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Find the length of the shortest path(s) in a DD.]
-
- Description [Find the length of the shortest path(s) in a DD. f is
- the DD we want to get the shortest path for; weight\[i\] is the
- weight of the THEN edge coming from the node whose index is i. All
- ELSE edges have 0 weight. Returns the length of the shortest
- path(s) if successful; CUDD_OUT_OF_MEM otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ShortestPath]
-
-******************************************************************************/
-int
-Cudd_ShortestLength(
- DdManager * manager,
- DdNode * f,
- int * weight)
-{
- register DdNode *F;
- st_table *visited;
- cuddPathPair *my_pair;
- int complement, cost;
-
- one = DD_ONE(manager);
- zero = DD_ZERO(manager);
-
- if (f == Cudd_Not(one) || f == zero) {
- return(DD_BIGGY);
- }
-
- /* From this point on, a path exists. */
- /* Initialize visited table and support. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
-
- /* Now get the length of the shortest path(s) from f to 1. */
- (void) getShortest(f, weight, NULL, visited);
-
- complement = Cudd_IsComplement(f);
-
- F = Cudd_Regular(f);
-
- st_lookup(visited, (char *)F, (char **)&my_pair);
-
- if (complement) {
- cost = my_pair->neg;
- } else {
- cost = my_pair->pos;
- }
-
- st_foreach(visited, freePathPair, NULL);
- st_free_table(visited);
-
- return(cost);
-
-} /* end of Cudd_ShortestLength */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines whether a BDD is negative unate in a
- variable.]
-
- Description [Determines whether the function represented by BDD f is
- negative unate (monotonic decreasing) in variable i. Returns the
- constant one is f is unate and the (logical) constant zero if it is not.
- This function does not generate any new nodes.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Increasing]
-
-******************************************************************************/
-DdNode *
-Cudd_Decreasing(
- DdManager * dd,
- DdNode * f,
- int i)
-{
- unsigned int topf, level;
- DdNode *F, *fv, *fvn, *res;
- DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
-
- statLine(dd);
-#ifdef DD_DEBUG
- assert(0 <= i && i < dd->size);
-#endif
-
- F = Cudd_Regular(f);
- topf = cuddI(dd,F->index);
-
- /* Check terminal case. If topf > i, f does not depend on var.
- ** Therefore, f is unate in i.
- */
- level = (unsigned) dd->perm[i];
- if (topf > level) {
- return(DD_ONE(dd));
- }
-
- /* From now on, f is not constant. */
-
- /* Check cache. */
- cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_Decreasing;
- res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
- if (res != NULL) {
- return(res);
- }
-
- /* Compute cofactors. */
- fv = cuddT(F); fvn = cuddE(F);
- if (F != f) {
- 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));
- } else {
- 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);
- return(res);
-
-} /* end of Cudd_Decreasing */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines whether a BDD is positive unate in a
- variable.]
-
- Description [Determines whether the function represented by BDD f is
- positive unate (monotonic decreasing) in variable i. It is based on
- Cudd_Decreasing and the fact that f is monotonic increasing in i if
- and only if its complement is monotonic decreasing in i.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Decreasing]
-
-******************************************************************************/
-DdNode *
-Cudd_Increasing(
- DdManager * dd,
- DdNode * f,
- int i)
-{
- return(Cudd_Decreasing(dd,Cudd_Not(f),i));
-
-} /* end of Cudd_Increasing */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether F and G are identical wherever D is 0.]
-
- Description [Tells whether F and G are identical wherever D is 0. F
- and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a
- BDD. The function returns 1 if F and G are equivalent, and 0
- otherwise. No new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddLeqUnless]
-
-******************************************************************************/
-int
-Cudd_EquivDC(
- DdManager * dd,
- DdNode * F,
- DdNode * G,
- DdNode * D)
-{
- DdNode *tmp, *One, *Gr, *Dr;
- DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
- int res;
- unsigned int flevel, glevel, dlevel, top;
-
- One = DD_ONE(dd);
-
- statLine(dd);
- /* Check terminal cases. */
- if (D == One || F == G) return(1);
- if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
-
- /* From now on, D is non-constant. */
-
- /* Normalize call to increase cache efficiency. */
- if (F > G) {
- tmp = F;
- F = G;
- G = tmp;
- }
- if (Cudd_IsComplement(F)) {
- F = Cudd_Not(F);
- G = Cudd_Not(G);
- }
-
- /* From now on, F is regular. */
-
- /* Check cache. */
- tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
- if (tmp != NULL) return(tmp == One);
-
- /* Find splitting variable. */
- flevel = cuddI(dd,F->index);
- Gr = Cudd_Regular(G);
- glevel = cuddI(dd,Gr->index);
- top = ddMin(flevel,glevel);
- Dr = Cudd_Regular(D);
- dlevel = dd->perm[Dr->index];
- top = ddMin(top,dlevel);
-
- /* Compute cofactors. */
- if (top == flevel) {
- Fv = cuddT(F);
- Fvn = cuddE(F);
- } else {
- Fv = Fvn = F;
- }
- if (top == glevel) {
- Gv = cuddT(Gr);
- Gvn = cuddE(Gr);
- if (G != Gr) {
- Gv = Cudd_Not(Gv);
- Gvn = Cudd_Not(Gvn);
- }
- } else {
- Gv = Gvn = G;
- }
- if (top == dlevel) {
- Dv = cuddT(Dr);
- Dvn = cuddE(Dr);
- if (D != Dr) {
- Dv = Cudd_Not(Dv);
- Dvn = Cudd_Not(Dvn);
- }
- } else {
- Dv = Dvn = D;
- }
-
- /* Solve recursively. */
- res = Cudd_EquivDC(dd,Fv,Gv,Dv);
- if (res != 0) {
- res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
- }
- cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
-
- return(res);
-
-} /* end of Cudd_EquivDC */
-
-
-/**Function********************************************************************
-
- Synopsis [Tells whether f is less than of equal to G unless D is 1.]
-
- Description [Tells whether f is less than of equal to G unless D is
- 1. f, g, and D are BDDs. The function returns 1 if f is less than
- of equal to G, and 0 otherwise. No new nodes are created.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]
-
-******************************************************************************/
-int
-Cudd_bddLeqUnless(
- DdManager *dd,
- DdNode *f,
- DdNode *g,
- DdNode *D)
-{
- DdNode *tmp, *One, *F, *G;
- DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
- int res;
- unsigned int flevel, glevel, dlevel, top;
-
- statLine(dd);
-
- One = DD_ONE(dd);
-
- /* Check terminal cases. */
- if (f == g || g == One || f == Cudd_Not(One) || D == One ||
- 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));
- 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));
-
- /* From now on, f, g, and D are non-constant, distinct, and
- ** non-complementary. */
-
- /* Normalize call to increase cache efficiency. We rely on the
- ** fact that f <= g unless D is equivalent to not(g) <= not(f)
- ** unless D and to f <= D unless g. We make sure that D is
- ** regular, and that at most one of f and g is complemented. We also
- ** ensure that when two operands can be swapped, the one with the
- ** 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;
- } else {
- f = Cudd_Not(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);
- } 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(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. */
-
- /* Check cache. */
- tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
- if (tmp != NULL) return(tmp == One);
-
- /* Find splitting variable. */
- F = Cudd_Regular(f);
- flevel = dd->perm[F->index];
- G = Cudd_Regular(g);
- glevel = dd->perm[G->index];
- top = ddMin(flevel,glevel);
- dlevel = dd->perm[D->index];
- top = ddMin(top,dlevel);
-
- /* Compute cofactors. */
- if (top == flevel) {
- Ft = cuddT(F);
- Fe = cuddE(F);
- if (F != f) {
- Ft = Cudd_Not(Ft);
- Fe = Cudd_Not(Fe);
- }
- } else {
- Ft = Fe = f;
- }
- if (top == glevel) {
- Gt = cuddT(G);
- Ge = cuddE(G);
- if (G != g) {
- Gt = Cudd_Not(Gt);
- Ge = Cudd_Not(Ge);
- }
- } else {
- Gt = Ge = g;
- }
- if (top == dlevel) {
- Dt = cuddT(D);
- De = cuddE(D);
- } else {
- Dt = De = D;
- }
-
- /* Solve recursively. */
- res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
- if (res != 0) {
- res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
- }
- cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res));
-
- return(res);
-
-} /* end of Cudd_bddLeqUnless */
-
-
-/**Function********************************************************************
-
- Synopsis [Compares two ADDs for equality within tolerance.]
-
- Description [Compares two ADDs for equality within tolerance. Two
- ADDs are reported to be equal if the maximum difference between them
- (the sup norm of their difference) is less than or equal to the
- tolerance parameter. Returns 1 if the two ADDs are equal (within
- tolerance); 0 otherwise. If parameter <code>pr</code> is positive
- the first failure is reported to the standard output.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_EqualSupNorm(
- DdManager * dd /* manager */,
- DdNode * f /* first ADD */,
- DdNode * g /* second ADD */,
- CUDD_VALUE_TYPE tolerance /* maximum allowed difference */,
- int pr /* verbosity level */)
-{
- DdNode *fv, *fvn, *gv, *gvn, *r;
- unsigned int topf, topg;
-
- statLine(dd);
- /* 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
- }
- 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);
- if (r != NULL) {
- return(1);
- }
-
- /* Compute the cofactors and solve the recursive subproblems. */
- topf = cuddI(dd,f->index);
- topg = cuddI(dd,g->index);
-
- if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
- if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
-
- 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));
-
- return(1);
-
-} /* end of Cudd_EqualSupNorm */
-
-
-/**Function********************************************************************
-
- Synopsis [Expands cube to a prime implicant of f.]
-
- Description [Expands cube to a prime implicant of f. Returns the prime
- if successful; NULL otherwise. In particular, NULL is returned if cube
- is not a real cube or is not an implicant of f.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_bddMakePrime(
- DdManager *dd /* manager */,
- DdNode *cube /* cube to be expanded */,
- DdNode *f /* function of which the cube is to be made a prime */)
-{
- DdNode *res;
-
- if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
-
- do {
- dd->reordered = 0;
- res = cuddBddMakePrime(dd,cube,f);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddMakePrime */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddMakePrime.]
-
- Description [Performs the recursive step of Cudd_bddMakePrime.
- Returns the prime if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddBddMakePrime(
- DdManager *dd /* manager */,
- DdNode *cube /* cube to be expanded */,
- DdNode *f /* function of which the cube is to be made a prime */)
-{
- DdNode *scan;
- DdNode *t, *e;
- DdNode *res = cube;
- DdNode *zero = Cudd_Not(DD_ONE(dd));
-
- 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 */
- }
- }
-
- if (scan == DD_ONE(dd)) {
- Cudd_Deref(res);
- return(res);
- } else {
- Cudd_RecursiveDeref(dd,res);
- return(NULL);
- }
-
-} /* end of cuddBddMakePrime */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the entries of the visited symbol table.]
-
- Description [Frees the entries of the visited symbol table. Returns
- ST_CONTINUE.]
-
- SideEffects [None]
-
-******************************************************************************/
-static enum st_retval
-freePathPair(
- char * key,
- char * value,
- char * arg)
-{
- cuddPathPair *pair;
-
- pair = (cuddPathPair *) value;
- FREE(pair);
- return(ST_CONTINUE);
-
-} /* end of freePathPair */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the length of the shortest path(s) in a DD.]
-
- Description [Finds the length of the shortest path(s) in a DD.
- Uses a local symbol table to store the lengths for each
- node. Only the lengths for the regular nodes are entered in the table,
- because those for the complement nodes are simply obtained by swapping
- the two lenghts.
- Returns a pair of lengths: the length of the shortest path to 1;
- and the length of the shortest path to 0. This is done so as to take
- complement arcs into account.]
-
- SideEffects [Accumulates the support of the DD in support.]
-
- SeeAlso []
-
-******************************************************************************/
-static cuddPathPair
-getShortest(
- DdNode * root,
- int * cost,
- int * support,
- st_table * visited)
-{
- cuddPathPair *my_pair, res_pair, pair_T, pair_E;
- 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);
- }
-
- /* In the case of a BDD the following test is equivalent to
- ** testing whether the BDD is the constant 1. This formulation,
- ** however, works for ADDs as well, by assuming the usual
- ** 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;
- }
- } 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;
- }
- }
-
- my_pair = 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);
- }
- 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;
- } else {
- res_pair.pos = my_pair->pos;
- res_pair.neg = my_pair->neg;
- }
- return(res_pair);
-
-} /* end of getShortest */
-
-
-/**Function********************************************************************
-
- Synopsis [Build a BDD for a shortest path of f.]
-
- Description [Build a BDD for a shortest path of f.
- Given the minimum length from the root, and the minimum
- lengths for each node (in visited), apply triangulation at each node.
- Of the two children of each node on a shortest path, at least one is
- on a shortest path. In case of ties the procedure chooses the THEN
- children.
- Returns a pointer to the cube BDD representing the path if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-getPath(
- DdManager * manager,
- st_table * visited,
- DdNode * f,
- int * weight,
- int cost)
-{
- DdNode *sol, *tmp;
- DdNode *my_dd, *T, *E;
- cuddPathPair *T_pair, *E_pair;
- int Tcost, Ecost;
- int complement;
-
- my_dd = Cudd_Regular(f);
- complement = Cudd_IsComplement(f);
-
- sol = one;
- 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);
- }
- 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);
- }
- 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);
- }
-
- cuddDeref(sol);
- return(sol);
-
-} /* end of getPath */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the size of the largest cube(s) in a DD.]
-
- Description [Finds the size of the largest cube(s) in a DD.
- This problem is translated into finding the shortest paths from a node
- when both THEN and ELSE arcs have unit lengths.
- Uses a local symbol table to store the lengths for each
- node. Only the lengths for the regular nodes are entered in the table,
- because those for the complement nodes are simply obtained by swapping
- the two lenghts.
- Returns a pair of lengths: the length of the shortest path to 1;
- and the length of the shortest path to 0. This is done so as to take
- complement arcs into account.]
-
- SideEffects [none]
-
- SeeAlso []
-
-******************************************************************************/
-static cuddPathPair
-getLargest(
- DdNode * root,
- st_table * visited)
-{
- cuddPathPair *my_pair, res_pair, pair_T, pair_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);
- }
-
- /* In the case of a BDD the following test is equivalent to
- ** testing whether the BDD is the constant 1. This formulation,
- ** however, works for ADDs as well, by assuming the usual
- ** 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;
- }
- } else {
- 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;
- }
-
- my_pair = 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);
- }
- 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;
- } else {
- res_pair.pos = my_pair->pos;
- res_pair.neg = my_pair->neg;
- }
- return(res_pair);
-
-} /* end of getLargest */
-
-
-/**Function********************************************************************
-
- Synopsis [Build a BDD for a largest cube of f.]
-
- Description [Build a BDD for a largest cube of f.
- Given the minimum length from the root, and the minimum
- lengths for each node (in visited), apply triangulation at each node.
- Of the two children of each node on a shortest path, at least one is
- on a shortest path. In case of ties the procedure chooses the THEN
- children.
- Returns a pointer to the cube BDD representing the path if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-getCube(
- DdManager * manager,
- st_table * visited,
- DdNode * f,
- int cost)
-{
- DdNode *sol, *tmp;
- DdNode *my_dd, *T, *E;
- cuddPathPair *T_pair, *E_pair;
- int Tcost, Ecost;
- int complement;
-
- my_dd = Cudd_Regular(f);
- complement = Cudd_IsComplement(f);
-
- sol = one;
- 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);
- }
- 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);
- }
- 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);
- }
-
- cuddDeref(sol);
- return(sol);
-
-} /* end of getCube */
diff --git a/src/bdd/cudd/cuddSign.c b/src/bdd/cudd/cuddSign.c
deleted file mode 100644
index fcaa65c4..00000000
--- a/src/bdd/cudd/cuddSign.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSign.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static int size;
-
-#ifdef DD_STATS
-static int num_calls; /* should equal 2n-1 (n is the # of nodes) */
-static int table_mem;
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *table));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Computes the fraction of minterms in the on-set of all the
- positive cofactors of a BDD or ADD.]
-
- Description [Computes the fraction of minterms in the on-set of all
- the positive cofactors of DD. Returns the pointer to an array of
- doubles if successful; NULL otherwise. The array hs as many
- positions as there are BDD variables in the manager plus one. The
- last position of the array contains the fraction of the minterms in
- the ON-set of the function represented by the BDD or ADD. The other
- positions of the array hold the variable signatures.]
-
- SideEffects [None]
-
-******************************************************************************/
-double *
-Cudd_CofMinterm(
- DdManager * dd,
- DdNode * node)
-{
- st_table *table;
- double *values;
- double *result = NULL;
- int i, firstLevel;
-
-#ifdef DD_STATS
- long startTime;
- startTime = util_cpu_time();
- num_calls = 0;
- table_mem = sizeof(st_table);
-#endif
-
- 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);
- }
- size = dd->size;
- values = ddCofMintermAux(dd, node, table);
- if (values != NULL) {
- result = ALLOC(double,size + 1);
- if (result != NULL) {
-#ifdef DD_STATS
- 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];
- } else {
- result[dd->invperm[i]] = values[size - firstLevel];
- }
- }
- 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) FREE(values);
- 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);
- (void) fprintf(dd->out,"Time to compute measures: %s\n",
- 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;
- }
- return(result);
-
-} /* end of Cudd_CofMinterm */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Recursive Step for Cudd_CofMinterm function.]
-
- Description [Traverses the DD node and computes the fraction of
- minterms in the on-set of all positive cofactors simultaneously.
- It allocates an array with two more entries than there are
- variables below the one labeling the node. One extra entry (the
- first in the array) is for the variable labeling the node. The other
- entry (the last one in the array) holds the fraction of minterms of
- the function rooted at node. Each other entry holds the value for
- one cofactor. The array is put in a symbol table, to avoid repeated
- computation, and its address is returned by the procedure, for use
- by the caller. Returns a pointer to the array of cofactor measures.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double *
-ddCofMintermAux(
- DdManager * dd,
- 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;
-
- statLine(dd);
-#ifdef DD_STATS
- num_calls++;
-#endif
-
- if (st_lookup(table, (char *) node, (char **) &values)) {
- return(values);
- }
-
- N = Cudd_Regular(node);
- if (cuddIsConstant(N)) {
- localSize = 1;
- } else {
- localSize = size - cuddI(dd,N->index) + 1;
- }
- values = ALLOC(double, localSize);
- if (values == 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;
- }
- } else {
- 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);
-
- 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)];
- } 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) FREE(valuesT);
- if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE);
- }
-
- if (N->ref > 1) {
- if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) {
- FREE(values);
- return(NULL);
- }
-#ifdef DD_STATS
- table_mem += localSize * sizeof(double) + sizeof(st_table_entry);
-#endif
- }
- return(values);
-
-} /* end of ddCofMintermAux */
-
diff --git a/src/bdd/cudd/cuddSolve.c b/src/bdd/cudd/cuddSolve.c
deleted file mode 100644
index d9c4a2e7..00000000
--- a/src/bdd/cudd/cuddSolve.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSolve.c]
-
- PackageName [cudd]
-
- 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> ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Structure declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the solution of F(x,y) = 0.]
-
- Description [Implements the solution for F(x,y) = 0. The return
- value is the consistency condition. The y variables are the unknowns
- and the remaining variables are the parameters. Returns the
- consistency condition if successful; NULL otherwise. Cudd_SolveEqn
- allocates an array and fills it with the indices of the
- unknowns. This array is used by Cudd_VerifySol.]
-
- SideEffects [The solution is returned in G; the indices of the y
- variables are returned in yIndex.]
-
- SeeAlso [Cudd_VerifySol]
-
-******************************************************************************/
-DdNode *
-Cudd_SolveEqn(
- DdManager * bdd,
- DdNode * F /* the left-hand side of the equation */,
- DdNode * Y /* the cube of the y variables */,
- DdNode ** G /* the array of solutions (return parameter) */,
- int ** yIndex /* index of y variables */,
- int n /* numbers of unknowns */)
-{
- DdNode *res;
- int *temp;
-
- *yIndex = temp = 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);
- }
-
- do {
- bdd->reordered = 0;
- res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
- } while (bdd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_SolveEqn */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the solution of F(x,y) = 0.]
-
- Description [Checks the solution of F(x,y) = 0. This procedure
- substitutes the solution components for the unknowns of F and returns
- the resulting BDD for F.]
-
- SideEffects [Frees the memory pointed by yIndex.]
-
- SeeAlso [Cudd_SolveEqn]
-
-******************************************************************************/
-DdNode *
-Cudd_VerifySol(
- DdManager * bdd,
- DdNode * F /* the left-hand side of the equation */,
- DdNode ** G /* the array of solutions */,
- int * yIndex /* index of y variables */,
- int n /* numbers of unknowns */)
-{
- DdNode *res;
-
- do {
- bdd->reordered = 0;
- res = cuddVerifySol(bdd, F, G, yIndex, n);
- } while (bdd->reordered == 1);
-
- FREE(yIndex);
-
- return(res);
-
-} /* end of Cudd_VerifySol */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_SolveEqn.]
-
- Description [Implements the recursive step of Cudd_SolveEqn.
- Returns NULL if the intermediate solution blows up
- or reordering occurs. The parametric solutions are
- stored in the array G.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_SolveEqn, Cudd_VerifySol]
-
-******************************************************************************/
-DdNode *
-cuddSolveEqnRecur(
- DdManager * bdd,
- DdNode * F /* the left-hand side of the equation */,
- DdNode * Y /* the cube of remaining y variables */,
- DdNode ** G /* the array of solutions */,
- int n /* number of unknowns */,
- int * yIndex /* array holding the y variable indices */,
- int i /* level of recursion */)
-{
- DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
- DdNodePtr *variables;
-
- int j;
-
- statLine(bdd);
- variables = bdd->vars;
- one = DD_ONE(bdd);
-
- /* Base condition. */
- if (Y == one) {
- return F;
- }
-
- /* Cofactor of Y. */
- yIndex[i] = Y->index;
- nextY = Cudd_T(Y);
-
- /* 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);
- } else {
- return(NULL);
- }
-
- Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
- if (Fn) {
- cuddRef(Fn);
- } else {
- Cudd_RecursiveDeref(bdd, Fm1);
- return(NULL);
- }
-
- Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
- if (Fv) {
- cuddRef(Fv);
- } else {
- Cudd_RecursiveDeref(bdd, Fm1);
- Cudd_RecursiveDeref(bdd, Fn);
- return(NULL);
- }
-
- Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
- if (Fvbar) {
- cuddRef(Fvbar);
- } else {
- 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);
- } else {
- 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);
- } 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,w);
- Cudd_RecursiveDeref(bdd,Fv);
- Cudd_RecursiveDeref(bdd,Fvbar);
-
- /* 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;
- }
- G[i] = T;
-
- Cudd_Deref(Fn);
-
- return(Fn);
-
-} /* end of cuddSolveEqnRecur */
-
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_VerifySol. ]
-
- Description []
-
- SideEffects [none]
-
- SeeAlso [Cudd_VerifySol]
-
-******************************************************************************/
-DdNode *
-cuddVerifySol(
- DdManager * bdd,
- DdNode * F /* the left-hand side of the equation */,
- DdNode ** G /* the array of solutions */,
- int * yIndex /* array holding the y variable indices */,
- int n /* number of unknowns */)
-{
- DdNode *w, *R;
-
- int j;
-
- 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;
- }
-
- cuddDeref(R);
-
- return(R);
-
-} /* end of cuddVerifySol */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddSplit.c b/src/bdd/cudd/cuddSplit.c
deleted file mode 100644
index e21ea7cb..00000000
--- a/src/bdd/cudd/cuddSplit.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSplit.c]
-
- PackageName [cudd]
-
- 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>
- Static functions included in this module:
- <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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Structure declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Returns m minterms from a BDD.]
-
- Description [Returns <code>m</code> minterms from a BDD whose
- support has <code>n</code> variables at most. The procedure tries
- to create as few extra nodes as possible. The function represented
- by <code>S</code> depends on at most <code>n</code> of the variables
- in <code>xVars</code>. Returns a BDD with <code>m</code> minterms
- of the on-set of S if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_SplitSet(
- DdManager * manager,
- DdNode * S,
- DdNode ** xVars,
- int n,
- double m)
-{
- DdNode *result;
- DdNode *zero, *one;
- double max, num;
- st_table *mtable;
- int *varSeen;
- int i,index, size;
-
- size = manager->size;
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Trivial cases. */
- if (m == 0.0) {
- return(zero);
- }
- if (S == zero) {
- 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 = 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);
- FREE(varSeen);
- } else {
- mtable = st_init_table(st_ptrcmp,st_ptrhash);
- if (mtable == NULL) {
- (void) fprintf(manager->out,
- "Cudd_SplitSet: out-of-memory.\n");
- 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);
- 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);
- FREE(varSeen);
- }
- } while (manager->reordered == 1);
-
- cuddDeref(result);
- return(result);
-
-} /* end of Cudd_SplitSet */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Implements the recursive step of Cudd_SplitSet.]
-
- Description [Implements the recursive step of Cudd_SplitSet. The
- procedure recursively traverses the BDD and checks to see if any
- node satisfies the minterm requirements as specified by 'n'. At any
- node X, n is compared to the number of minterms in the onset of X's
- children. If either of the child nodes have exactly n minterms, then
- that node is returned; else, if n is greater than the onset of one
- of the child nodes, that node is retained and the difference in the
- number of minterms is extracted from the other child. In case n
- minterms can be extracted from constant 1, the algorithm returns the
- result with at most log(n) nodes.]
-
- SideEffects [The array 'varSeen' is updated at every recursive call
- to set the variables traversed by the procedure.]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode*
-cuddSplitSetRecur(
- DdManager * manager,
- st_table * mtable,
- int * varSeen,
- DdNode * p,
- double n,
- double max,
- int index)
-{
- DdNode *one, *zero, *N, *Nv;
- DdNode *Nnv, *q, *r, *v;
- DdNode *result;
- double *dummy, numT, numE;
- int variable, positive;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* If p is constant, extract n minterms from constant 1. The procedure by
- ** construction guarantees that minterms will not be extracted from
- ** constant 0.
- */
- if (Cudd_IsConstant(p)) {
- q = selectMintermsFromUniverse(manager,varSeen,n);
- return(q);
- }
-
- N = Cudd_Regular(p);
-
- /* Set variable as seen. */
- variable = N->index;
- varSeen[manager->invperm[variable]] = -1;
-
- Nv = cuddT(N);
- Nnv = cuddE(N);
- if (Cudd_IsComplement(p)) {
- 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) {
- Cudd_RecursiveDeref(manager,q);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDeref(manager,q);
- 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));
- } else if (Nv == one) {
- numT = max/(2*(1<<index));
- } else {
- numT = 0;
- }
-
- if (!Cudd_IsConstant(Nnv)) {
- st_lookup(mtable,(char *)Nnv, (char **)&dummy);
- numE = *dummy/(2*(1<<index));
- } else if (Nnv == one) {
- numE = max/(2*(1<<index));
- } else {
- numE = 0;
- }
-
- v = cuddUniqueInter(manager,variable,one,zero);
- cuddRef(v);
-
- /* If perfect match. */
- if (numT == n) {
- q = cuddBddAndRecur(manager,v,Nv);
- if (q == NULL) {
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(q);
- Cudd_RecursiveDeref(manager,v);
- cuddDeref(q);
- return(q);
- }
- if (numE == n) {
- q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv);
- if (q == NULL) {
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(q);
- Cudd_RecursiveDeref(manager,v);
- 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) {
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- 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) {
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- cuddDeref(r);
- return(r);
- }
-
- /* None of the above cases; (n < numT and n < numE) and either of
- ** the Nv, Nnv or both are not constants. If possible extract the
- ** 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) {
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(result);
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- 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) {
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(result);
- Cudd_RecursiveDeref(manager,q);
- Cudd_RecursiveDeref(manager,v);
- cuddDeref(result);
- return(result);
- }
-
- /* Both Nv and Nnv are not constants. So choose the one which
- ** has fewer minterms in its onset.
- */
- positive = 0;
- if (numT < numE) {
- q = cuddSplitSetRecur(manager,mtable,varSeen,
- Nv,n,max,index+1);
- positive = 1;
- } else {
- q = cuddSplitSetRecur(manager,mtable,varSeen,
- Nnv,n,max,index+1);
- }
-
- if (q == NULL) {
- Cudd_RecursiveDeref(manager,v);
- return(NULL);
- }
- cuddRef(q);
-
- if (positive) {
- result = cuddBddAndRecur(manager,v,q);
- } else {
- 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);
- cuddDeref(result);
-
- return(result);
-
-} /* end of cuddSplitSetRecur */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [This function prepares an array of variables which have not been
- encountered so far when traversing the procedure cuddSplitSetRecur.]
-
- Description [This function prepares an array of variables which have not been
- encountered so far when traversing the procedure cuddSplitSetRecur. This
- array is then used to extract the required number of minterms from a constant
- 1. The algorithm guarantees that the size of BDD will be utmost \log(n).]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-selectMintermsFromUniverse(
- DdManager * manager,
- int * varSeen,
- double n)
-{
- int numVars;
- int i, size, j;
- DdNode *one, *zero, *result;
- DdNode **vars;
-
- numVars = 0;
- size = manager->size;
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- /* Count the number of variables not encountered so far in procedure
- ** cuddSplitSetRecur.
- */
- for (i = size-1; i >= 0; i--) {
- if(varSeen[i] == 0)
- numVars++;
- }
- vars = ALLOC(DdNode *, numVars);
- if (!vars) {
- 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++;
- }
- }
-
- /* Compute a function which has n minterms and depends on at most
- ** numVars variables.
- */
- result = mintermsFromUniverse(manager,vars,numVars,n, 0);
- if (result)
- cuddRef(result);
-
- for (i = 0; i < numVars; i++)
- Cudd_RecursiveDeref(manager,vars[i]);
- FREE(vars);
-
- return(result);
-
-} /* end of selectMintermsFromUniverse */
-
-
-/**Function********************************************************************
-
- Synopsis [Recursive procedure to extract n mintems from constant 1.]
-
- Description [Recursive procedure to extract n mintems from constant 1.]
-
- SideEffects [None]
-
-******************************************************************************/
-static DdNode *
-mintermsFromUniverse(
- DdManager * manager,
- DdNode ** vars,
- int numVars,
- double n,
- int index)
-{
- DdNode *one, *zero;
- DdNode *q, *result;
- double max, max2;
-
- statLine(manager);
- one = DD_ONE(manager);
- zero = Cudd_Not(one);
-
- max = pow(2.0, (double)numVars);
- max2 = max / 2.0;
-
- if (n == max)
- return(one);
- if (n == 0.0)
- return(zero);
- /* if n == 2^(numVars-1), return a single variable */
- if (n == max2)
- 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);
- } 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);
- }
-
- if (result == NULL) {
- Cudd_RecursiveDeref(manager,q);
- return(NULL);
- }
- cuddRef(result);
- Cudd_RecursiveDeref(manager,q);
- cuddDeref(result);
- return(result);
-
-} /* end of mintermsFromUniverse */
-
-
-/**Function********************************************************************
-
- Synopsis [Annotates every node in the BDD node with its minterm count.]
-
- Description [Annotates every node in the BDD node with its minterm count.
- In this function, every node and the minterm count represented by it are
- stored in a hash table.]
-
- SideEffects [Fills up 'table' with the pair <node,minterm_count>.]
-
-******************************************************************************/
-static double
-bddAnnotateMintermCount(
- DdManager * manager,
- DdNode * node,
- double max,
- st_table * table)
-{
-
- DdNode *N,*Nv,*Nnv;
- register double min_v,min_nv;
- register double min_N;
- double *pmin;
- double *dummy;
-
- statLine(manager);
- N = Cudd_Regular(node);
- if (cuddIsConstant(N)) {
- if (node == DD_ONE(manager)) {
- return(max);
- } else {
- return(0.0);
- }
- }
-
- if (st_lookup(table,(char *)node,(char **)&dummy)) {
- return(*dummy);
- }
-
- Nv = cuddT(N);
- Nnv = cuddE(N);
- if (N != node) {
- 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);
- min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0;
- if (min_nv == (double)CUDD_OUT_OF_MEM)
- return ((double)CUDD_OUT_OF_MEM);
- min_N = min_v + min_nv;
-
- pmin = ALLOC(double,1);
- if (pmin == NULL) {
- 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) {
- FREE(pmin);
- return((double)CUDD_OUT_OF_MEM);
- }
-
- return(min_N);
-
-} /* end of bddAnnotateMintermCount */
diff --git a/src/bdd/cudd/cuddSubsetHB.c b/src/bdd/cudd/cuddSubsetHB.c
deleted file mode 100644
index 24d41ce5..00000000
--- a/src/bdd/cudd/cuddSubsetHB.c
+++ /dev/null
@@ -1,1311 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSubsetHB.c]
-
- PackageName [cudd]
-
- Synopsis [Procedure to subset the given BDD by choosing the heavier
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#ifdef __STDC__
-#include <float.h>
-#else
-#define DBL_MAX_EXP 1024
-#endif
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DEFAULT_PAGE_SIZE 2048
-#define DEFAULT_NODE_DATA_PAGE_SIZE 1024
-#define INITIAL_PAGES 128
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/* data structure to store the information on each node. It keeps
- * the number of minterms represented by the DAG rooted at this node
- * in terms of the number of variables specified by the user, number
- * of nodes in this DAG and the number of nodes of its child with
- * lesser number of minterms that are not shared by the child with
- * more minterms
- */
-struct NodeData {
- double *mintermPointer;
- int *nodesPointer;
- int *lightChildNodesPointer;
-};
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-typedef struct NodeData NodeData_t;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static int memOut;
-#ifdef DEBUG
-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 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;
- /* page size */
-static int maxNodeDataPages; /* number of page pointers */
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense subset from a BDD with the heavy branch
- heuristic.]
-
- Description [Extracts a dense subset from a BDD. This procedure
- builds a subset by throwing away one of the children of each node,
- starting from the root, until the result is small enough. The child
- that is eliminated from the result is the one that contributes the
- fewer minterms. Returns a pointer to the BDD of the subset if
- successful. NULL if the procedure runs out of memory. The parameter
- numVars is the maximum number of variables to be used in minterm
- calculation and node count calculation. The optimal number should
- be as close as possible to the size of the support of f. However,
- it is safe to pass the value returned by Cudd_ReadSize for numVars
- when the number of variables is under 1023. If numVars is larger
- than 1023, it will overflow. If a 0 parameter is passed then the
- procedure will compute a value which will avoid overflow but will
- cause underflow with 2046 variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_SubsetHeavyBranch(
- DdManager * dd /* manager */,
- DdNode * f /* function to be subset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the subset */)
-{
- DdNode *subset;
-
- memOut = 0;
- do {
- dd->reordered = 0;
- subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold);
- } while ((dd->reordered == 1) && (!memOut));
-
- return(subset);
-
-} /* end of Cudd_SubsetHeavyBranch */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense superset from a BDD with the heavy branch
- heuristic.]
-
- Description [Extracts a dense superset from a BDD. The procedure is
- identical to the subset procedure except for the fact that it
- receives the complement of the given function. Extracting the subset
- of the complement function is equivalent to extracting the superset
- of the function. This procedure builds a superset by throwing away
- one of the children of each node starting from the root of the
- complement function, until the result is small enough. The child
- that is eliminated from the result is the one that contributes the
- fewer minterms.
- Returns a pointer to the BDD of the superset if successful. NULL if
- intermediate result causes the procedure to run out of memory. The
- parameter numVars is the maximum number of variables to be used in
- minterm calculation and node count calculation. The optimal number
- should be as close as possible to the size of the support of f.
- However, it is safe to pass the value returned by Cudd_ReadSize for
- numVars when the number of variables is under 1023. If numVars is
- larger than 1023, it will overflow. If a 0 parameter is passed then
- the procedure will compute a value which will avoid overflow but
- will cause underflow with 2046 variables or more.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_SupersetHeavyBranch(
- DdManager * dd /* manager */,
- DdNode * f /* function to be superset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the superset */)
-{
- DdNode *subset, *g;
-
- g = Cudd_Not(f);
- memOut = 0;
- do {
- dd->reordered = 0;
- subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold);
- } while ((dd->reordered == 1) && (!memOut));
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_SupersetHeavyBranch */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [The main procedure that returns a subset by choosing the heavier
- branch in the BDD.]
-
- Description [Here a subset BDD is built by throwing away one of the
- children. Starting at root, annotate each node with the number of
- minterms (in terms of the total number of variables specified -
- numVars), number of nodes taken by the DAG rooted at this node and
- number of additional nodes taken by the child that has the lesser
- minterms. The child with the lower number of minterms is thrown away
- and a dyanmic count of the nodes of the subset is kept. Once the
- threshold is reached the subset is returned to the calling
- procedure.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetHeavyBranch]
-
-******************************************************************************/
-DdNode *
-cuddSubsetHeavyBranch(
- DdManager * dd /* DD manager */,
- DdNode * f /* current DD */,
- int numVars /* maximum number of variables */,
- int threshold /* threshold size for the subset */)
-{
-
- int i, *size;
- st_table *visitedTable;
- 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);
- }
-
- one = Cudd_ReadOne(dd);
- zero = Cudd_Not(one);
-
- /* If user does not know numVars value, set it to the maximum
- * exponent that the pow function can take. The -1 is due to the
- * discrepancy in the value that pow takes and the value that
- * log gives.
- */
- if (numVars == 0) {
- /* set default value */
- numVars = DBL_MAX_EXP - 1;
- }
-
- if (Cudd_IsConstant(f)) {
- return(f);
- }
-
- max = pow(2.0, (double)numVars);
-
- /* Create visited table where structures for node data are allocated and
- 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);
- }
- numNodes = SubsetCountNodes(f, visitedTable, numVars);
- if (memOut) {
- (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;
- }
-
- size = ALLOC(int, 1);
- if (size == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- *size = numNodes;
-
-#ifdef DEBUG
- num_calls = 0;
-#endif
- /* table to store nodes being created. */
- storeTable = st_init_table(st_ptrcmp, st_ptrhash);
- /* 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");
- }
- /* table to store approximations of nodes */
- approxTable = st_init_table(st_ptrcmp, st_ptrhash);
- subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold,
- storeTable, approxTable);
- if (subset != NULL) {
- cuddRef(subset);
- }
-
- stGen = st_init_gen(approxTable);
- if (stGen == NULL) {
- st_free_table(approxTable);
- return(NULL);
- }
- while(st_gen(stGen, (char **)&key, (char **)&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);
- }
- while(st_gen(stGen, (char **)&key, (char **)&value)) {
- Cudd_RecursiveDeref(dd, (DdNode *)key);
- }
- st_free_gen(stGen); stGen = NULL;
- st_free_table(storeTable);
-
- for (i = 0; i <= page; i++) {
- FREE(mintermPages[i]);
- }
- FREE(mintermPages);
- for (i = 0; i <= page; i++) {
- FREE(nodePages[i]);
- }
- FREE(nodePages);
- for (i = 0; i <= page; i++) {
- FREE(lightNodePages[i]);
- }
- FREE(lightNodePages);
- for (i = 0; i <= nodeDataPage; i++) {
- FREE(nodeDataPages[i]);
- }
- FREE(nodeDataPages);
- st_free_table(visitedTable);
- FREE(size);
-#if 0
- (void) Cudd_DebugCheck(dd);
- (void) Cudd_CheckKeys(dd);
-#endif
-
- 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);
- }
-#endif
- cuddDeref(subset);
- return(subset);
- } else {
- return(NULL);
- }
-} /* end of cuddSubsetHeavyBranch */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Resize the number of pages allocated to store the node data.]
-
- Description [Resize the number of pages allocated to store the node data
- 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
- number of pages freeing stuff in case of memory out. ]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ResizeNodeDataPages(
- )
-{
- int i;
- NodeData_t **newNodeDataPages;
-
- nodeDataPage++;
- /* If the current page index is larger than the number of pages
- * allocated, allocate a new page array. Page numbers are incremented by
- * INITIAL_PAGES
- */
- if (nodeDataPage == maxNodeDataPages) {
- newNodeDataPages = ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES);
- if (newNodeDataPages == NULL) {
- for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxNodeDataPages; i++) {
- newNodeDataPages[i] = nodeDataPages[i];
- }
- /* Increase total page count */
- maxNodeDataPages += INITIAL_PAGES;
- FREE(nodeDataPages);
- nodeDataPages = newNodeDataPages;
- }
- }
- /* Allocate a new page */
- currentNodeDataPage = nodeDataPages[nodeDataPage] =
- ALLOC(NodeData_t ,nodeDataPageSize);
- if (currentNodeDataPage == NULL) {
- for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- memOut = 1;
- return;
- }
- /* reset page index */
- nodeDataPageIndex = 0;
- return;
-
-} /* end of ResizeNodeDataPages */
-
-
-/**Function********************************************************************
-
- Synopsis [Resize the number of pages allocated to store the minterm
- counts. ]
-
- Description [Resize the number of pages allocated to store the minterm
- 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
- number of pages freeing stuff in case of memory out. ]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ResizeCountMintermPages(
- )
-{
- int i;
- double **newMintermPages;
-
- page++;
- /* If the current page index is larger than the number of pages
- * allocated, allocate a new page array. Page numbers are incremented by
- * INITIAL_PAGES
- */
- if (page == maxPages) {
- newMintermPages = ALLOC(double *,maxPages + INITIAL_PAGES);
- if (newMintermPages == NULL) {
- for (i = 0; i < page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxPages; i++) {
- newMintermPages[i] = mintermPages[i];
- }
- /* Increase total page count */
- maxPages += INITIAL_PAGES;
- FREE(mintermPages);
- mintermPages = newMintermPages;
- }
- }
- /* Allocate a new page */
- currentMintermPage = mintermPages[page] = ALLOC(double,pageSize);
- if (currentMintermPage == NULL) {
- for (i = 0; i < page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- memOut = 1;
- return;
- }
- /* reset page index */
- pageIndex = 0;
- return;
-
-} /* end of ResizeCountMintermPages */
-
-
-/**Function********************************************************************
-
- Synopsis [Resize the number of pages allocated to store the node counts.]
-
- Description [Resize the number of pages allocated to store the node 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 pages, page, page index, maximum
- number of pages freeing stuff in case of memory out.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ResizeCountNodePages(
- )
-{
- int i;
- int **newNodePages;
-
- page++;
-
- /* If the current page index is larger than the number of pages
- * allocated, allocate a new page array. The number of pages is incremented
- * by INITIAL_PAGES.
- */
- if (page == maxPages) {
- newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES);
- if (newNodePages == NULL) {
- for (i = 0; i < page; i++) FREE(nodePages[i]);
- FREE(nodePages);
- for (i = 0; i < page; i++) FREE(lightNodePages[i]);
- FREE(lightNodePages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxPages; i++) {
- newNodePages[i] = nodePages[i];
- }
- FREE(nodePages);
- nodePages = newNodePages;
- }
-
- newNodePages = ALLOC(int *,maxPages + INITIAL_PAGES);
- if (newNodePages == NULL) {
- for (i = 0; i < page; i++) FREE(nodePages[i]);
- FREE(nodePages);
- for (i = 0; i < page; i++) FREE(lightNodePages[i]);
- FREE(lightNodePages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxPages; i++) {
- newNodePages[i] = lightNodePages[i];
- }
- FREE(lightNodePages);
- lightNodePages = newNodePages;
- }
- /* Increase total page count */
- maxPages += INITIAL_PAGES;
- }
- /* Allocate a new page */
- currentNodePage = nodePages[page] = ALLOC(int,pageSize);
- if (currentNodePage == NULL) {
- for (i = 0; i < page; i++) FREE(nodePages[i]);
- FREE(nodePages);
- for (i = 0; i < page; i++) FREE(lightNodePages[i]);
- FREE(lightNodePages);
- memOut = 1;
- return;
- }
- /* Allocate a new page */
- currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize);
- if (currentLightNodePage == NULL) {
- for (i = 0; i <= page; i++) FREE(nodePages[i]);
- FREE(nodePages);
- for (i = 0; i < page; i++) FREE(lightNodePages[i]);
- FREE(lightNodePages);
- memOut = 1;
- return;
- }
- /* reset page index */
- pageIndex = 0;
- return;
-
-} /* end of ResizeCountNodePages */
-
-
-/**Function********************************************************************
-
- Synopsis [Recursively counts minterms of each node in the DAG.]
-
- Description [Recursively counts minterms of each node in the DAG.
- Similar to the cuddCountMintermAux which recursively counts the
- number of minterms for the dag rooted at each node in terms of the
- total number of variables (max). This procedure creates the node
- data structure and stores the minterm count as part of the node
- data structure. ]
-
- SideEffects [Creates structures of type node quality and fills the st_table]
-
- SeeAlso [SubsetCountMinterm]
-
-******************************************************************************/
-static double
-SubsetCountMintermAux(
- DdNode * node /* function to analyze */,
- double max /* number of minterms of constant 1 */,
- st_table * table /* visitedTable table */)
-{
-
- 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;
-
-#ifdef DEBUG
- num_calls++;
-#endif
-
- /* Constant case */
- if (Cudd_IsConstant(node)) {
- 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++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- st_free_table(table);
- return(0.0);
- }
-
- /* point to the correct location in the page */
- pmin = currentMintermPage+pageIndex;
- pageIndex++;
-
- /* store the minterm count of this node in the page */
- *pmin = min;
-
- /* Note I allocate the struct here. Freeing taken care of later */
- if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages();
- if (memOut) {
- for (i = 0; i <= page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- st_free_table(table);
- return(0.0);
- }
-
- 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++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- st_free_table(table);
- return(0.0);
- }
- return(min);
- }
-
-} /* end of SubsetCountMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts minterms of each node in the DAG]
-
- Description [Counts minterms of each node in the DAG. Similar to the
- Cudd_CountMinterm procedure except this returns the minterm count for
- all the nodes in the bdd in an st_table.]
-
- SideEffects [none]
-
- SeeAlso [SubsetCountMintermAux]
-
-******************************************************************************/
-static st_table *
-SubsetCountMinterm(
- DdNode * node /* function to be analyzed */,
- int nvars /* number of variables node depends on */)
-{
- st_table *table;
- double num;
- int i;
-
-
-#ifdef DEBUG
- num_calls = 0;
-#endif
-
- max = pow(2.0,(double) nvars);
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) goto OUT_OF_MEM;
- maxPages = INITIAL_PAGES;
- mintermPages = ALLOC(double *,maxPages);
- if (mintermPages == NULL) {
- st_free_table(table);
- goto OUT_OF_MEM;
- }
- page = 0;
- currentMintermPage = ALLOC(double,pageSize);
- mintermPages[page] = currentMintermPage;
- if (currentMintermPage == NULL) {
- FREE(mintermPages);
- st_free_table(table);
- goto OUT_OF_MEM;
- }
- pageIndex = 0;
- maxNodeDataPages = INITIAL_PAGES;
- nodeDataPages = ALLOC(NodeData_t *, maxNodeDataPages);
- if (nodeDataPages == NULL) {
- for (i = 0; i <= page ; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- st_free_table(table);
- goto OUT_OF_MEM;
- }
- nodeDataPage = 0;
- currentNodeDataPage = ALLOC(NodeData_t ,nodeDataPageSize);
- nodeDataPages[nodeDataPage] = currentNodeDataPage;
- if (currentNodeDataPage == NULL) {
- for (i = 0; i <= page ; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- FREE(nodeDataPages);
- st_free_table(table);
- goto OUT_OF_MEM;
- }
- nodeDataPageIndex = 0;
-
- num = SubsetCountMintermAux(node,max,table);
- if (memOut) goto OUT_OF_MEM;
- return(table);
-
-OUT_OF_MEM:
- memOut = 1;
- return(NULL);
-
-} /* end of SubsetCountMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Recursively counts the number of nodes under the dag.
- Also counts the number of nodes under the lighter child of
- this node.]
-
- Description [Recursively counts the number of nodes under the dag.
- Also counts the number of nodes under the lighter child of
- this node. . Note that the same dag may be the lighter child of two
- different nodes and have different counts. As with the minterm counts,
- the node counts are stored in pages to be space efficient and the
- address for these node counts are stored in an st_table associated
- to each node. ]
-
- SideEffects [Updates the node data table with node counts]
-
- SeeAlso [SubsetCountNodes]
-
-******************************************************************************/
-static int
-SubsetCountNodesAux(
- DdNode * node /* current node */,
- st_table * table /* table to update node count, also serves as visited table. */,
- double max /* maximum number of variables */)
-{
- int tval, eval, i;
- DdNode *N, *Nv, *Nnv;
- double minNv, minNnv;
- NodeData_t *dummyN, *dummyNv, *dummyNnv, *dummyNBar;
- int *pmin, *pminBar, *val;
-
- if ((node == NULL) || Cudd_IsConstant(node))
- 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);
- } else {
- 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;
- }
- } else {
- if (st_lookup(table, (char *)Nv, (char **)&dummyNv) == 1)
- minNv = *(dummyNv->mintermPointer);
- else {
- return(0);
- }
- }
- if (Cudd_IsConstant(Nnv)) {
- 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);
- }
- }
-
-
- /* 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++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- 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++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- 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. */
- pmin = currentNodePage + pageIndex;
- *pmin = tval + eval + 1;
- dummyN->nodesPointer = pmin;
-
- /* pageIndex is parallel page index for count_nodes and count_lightNodes */
- pageIndex++;
-
- /* if this node has been reached first, it belongs to a heavier
- 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++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]);
- 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++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i < nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- st_free_table(table);
- return(0);
- }
- pminBar = currentNodePage + pageIndex;
- *pminBar = 0;
- dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */
-
- pageIndex++;
- }
- return(*pmin);
-} /*end of SubsetCountNodesAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the nodes under the current node and its lighter child]
-
- Description [Counts the nodes under the current node and its lighter
- child. Calls a recursive procedure to count the number of nodes of
- a DAG rooted at a particular node and the number of nodes taken by its
- lighter child.]
-
- SideEffects [None]
-
- SeeAlso [SubsetCountNodesAux]
-
-******************************************************************************/
-static int
-SubsetCountNodes(
- DdNode * node /* function to be analyzed */,
- st_table * table /* node quality table */,
- int nvars /* number of variables node depends on */)
-{
- int num;
- int i;
-
-#ifdef DEBUG
- num_calls = 0;
-#endif
-
- max = pow(2.0,(double) nvars);
- maxPages = INITIAL_PAGES;
- nodePages = ALLOC(int *,maxPages);
- if (nodePages == NULL) {
- goto OUT_OF_MEM;
- }
-
- lightNodePages = ALLOC(int *,maxPages);
- if (lightNodePages == NULL) {
- for (i = 0; i <= page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- FREE(nodePages);
- goto OUT_OF_MEM;
- }
-
- page = 0;
- currentNodePage = nodePages[page] = ALLOC(int,pageSize);
- if (currentNodePage == NULL) {
- for (i = 0; i <= page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- FREE(lightNodePages);
- FREE(nodePages);
- goto OUT_OF_MEM;
- }
-
- currentLightNodePage = lightNodePages[page] = ALLOC(int,pageSize);
- if (currentLightNodePage == NULL) {
- for (i = 0; i <= page; i++) FREE(mintermPages[i]);
- FREE(mintermPages);
- for (i = 0; i <= nodeDataPage; i++) FREE(nodeDataPages[i]);
- FREE(nodeDataPages);
- FREE(currentNodePage);
- FREE(lightNodePages);
- FREE(nodePages);
- goto OUT_OF_MEM;
- }
-
- pageIndex = 0;
- num = SubsetCountNodesAux(node,table,max);
- if (memOut) goto OUT_OF_MEM;
- return(num);
-
-OUT_OF_MEM:
- memOut = 1;
- return(0);
-
-} /* end of SubsetCountNodes */
-
-
-/**Function********************************************************************
-
- Synopsis [Procedure to recursively store nodes that are retained in the subset.]
-
- Description [rocedure to recursively store nodes that are retained in the subset.]
-
- SideEffects [None]
-
- SeeAlso [StoreNodes]
-
-******************************************************************************/
-static void
-StoreNodes(
- st_table * storeTable,
- DdManager * dd,
- DdNode * node)
-{
- char *dummy;
- DdNode *N, *Nt, *Ne;
- if (Cudd_IsConstant(dd)) {
- return;
- }
- N = Cudd_Regular(node);
- if (st_lookup(storeTable, (char *)N, (char **)&dummy)) {
- 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");
- }
-
- Nt = Cudd_T(N);
- Ne = Cudd_E(N);
-
- StoreNodes(storeTable, dd, Nt);
- StoreNodes(storeTable, dd, Ne);
- return;
-
-}
-
-
-/**Function********************************************************************
-
- 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,
- the procedure chooses the heavier branch starting from the root and keeps
- track of the number of nodes it discards at each step, thus keeping count
- of the size of the subset BDD dynamically. Once the threshold is satisfied,
- the procedure then calls ITE to build the BDD.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-BuildSubsetBdd(
- DdManager * dd /* DD manager */,
- DdNode * node /* current node */,
- int * size /* current size of the subset */,
- st_table * visitedTable /* visited table storing all node data */,
- int threshold,
- st_table * storeTable,
- st_table * approxTable)
-{
-
- DdNode *Nv, *Nnv, *N, *topv, *neW;
- double minNv, minNnv;
- NodeData_t *currNodeQual;
- NodeData_t *currNodeQualT;
- NodeData_t *currNodeQualE;
- DdNode *ThenBranch, *ElseBranch;
- unsigned int topid;
- char *dummy;
-
-#ifdef DEBUG
- num_calls++;
-#endif
- /*If the size of the subset is below the threshold, dont do
- anything. */
- if ((*size) <= threshold) {
- /* store nodes below this, so we can recombine if possible */
- StoreNodes(storeTable, dd, node);
- return(node);
- }
-
- if (Cudd_IsConstant(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");
- }
-
- /* Get children. */
- N = Cudd_Regular(node);
- Nv = Cudd_T(N);
- Nnv = Cudd_E(N);
-
- /* complement if necessary */
- Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
- Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
-
- 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);
- }
- else {
- minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer);
- }
- } else {
- 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;
- } else {
- minNnv = max;
- }
- }
-
- /* keep track of size of subset by subtracting the number of
- * differential nodes contributed by lighter child
- */
- *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer);
- if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes
- 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);
- }
- }
-
- }
- 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);
- }
- }
- }
-
- /* construct the Bdd with the top variable and the two children */
- topid = Cudd_NodeReadIndex(N);
- topv = Cudd_ReadVars(dd, topid);
- cuddRef(topv);
- neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch);
- if (neW != NULL) {
- cuddRef(neW);
- }
- Cudd_RecursiveDeref(dd, topv);
- Cudd_RecursiveDeref(dd, ThenBranch);
- Cudd_RecursiveDeref(dd, ElseBranch);
-
-
- if (neW == 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));
-
- }
- /* 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);
- }
- }
- cuddDeref(neW);
- return(neW);
- }
-} /* end of BuildSubsetBdd */
-
diff --git a/src/bdd/cudd/cuddSubsetSP.c b/src/bdd/cudd/cuddSubsetSP.c
deleted file mode 100644
index 55ee3470..00000000
--- a/src/bdd/cudd/cuddSubsetSP.c
+++ /dev/null
@@ -1,1624 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSubsetSP.c]
-
- PackageName [cudd]
-
- Synopsis [Procedure to subset the given BDD choosing the shortest paths
- (largest cubes) in the BDD.]
-
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* 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 INITIAL_PAGES 128 /* number of initial pages for the
- * queue/NodeDist_t type */
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/* 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.
- */
-struct NodeDist{
- DdHalfWord oddTopDist;
- DdHalfWord evenTopDist;
- DdHalfWord oddBotDist;
- DdHalfWord evenBotDist;
- DdNode *regResult;
- DdNode *compResult;
-};
-
-/* assorted information needed by the BuildSubsetBdd procedure. */
-struct AssortedInfo {
- unsigned int maxpath;
- int findShortestPath;
- int thresholdReached;
- st_table *maxpathTable;
- int threshold;
-};
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-typedef struct NodeDist NodeDist_t;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-#ifdef DD_DEBUG
-static int numCalls;
-static int hits;
-static int thishit;
-#endif
-
-
-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 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 DdNode **currentQueuePage; /* current page */
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of Exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense subset from a BDD with the shortest paths
- heuristic.]
-
- Description [Extracts a dense subset from a BDD. This procedure
- tries to preserve the shortest paths of the input BDD, because they
- give many minterms and contribute few nodes. This procedure may
- increase the number of nodes in trying to create the subset or
- reduce the number of nodes due to recombination as compared to the
- original BDD. Hence the threshold may not be strictly adhered to. In
- practice, recombination overshadows the increase in the number of
- nodes and results in small BDDs as compared to the threshold. The
- hardlimit specifies whether threshold needs to be strictly adhered
- to. If it is set to 1, the procedure ensures that result is never
- larger than the specified limit but may be considerably less than
- the threshold. Returns a pointer to the BDD for the subset if
- successful; NULL otherwise. The value for numVars should be as
- close as possible to the size of the support of f for better
- efficiency. However, it is safe to pass the value returned by
- Cudd_ReadSize for numVars. If 0 is passed, then the value returned
- by Cudd_ReadSize is used.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_SubsetShortPaths(
- DdManager * dd /* manager */,
- DdNode * f /* function to be subset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the subset */,
- int hardlimit /* flag: 1 if threshold is a hard limit */)
-{
- DdNode *subset;
-
- memOut = 0;
- do {
- dd->reordered = 0;
- subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit);
- } while((dd->reordered ==1) && (!memOut));
-
- return(subset);
-
-} /* end of Cudd_SubsetShortPaths */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a dense superset from a BDD with the shortest paths
- heuristic.]
-
- Description [Extracts a dense superset from a BDD. The procedure is
- identical to the subset procedure except for the fact that it
- receives the complement of the given function. Extracting the subset
- of the complement function is equivalent to extracting the superset
- of the function. This procedure tries to preserve the shortest
- paths of the complement BDD, because they give many minterms and
- contribute few nodes. This procedure may increase the number of
- nodes in trying to create the superset or reduce the number of nodes
- due to recombination as compared to the original BDD. Hence the
- threshold may not be strictly adhered to. In practice, recombination
- overshadows the increase in the number of nodes and results in small
- BDDs as compared to the threshold. The hardlimit specifies whether
- threshold needs to be strictly adhered to. If it is set to 1, the
- procedure ensures that result is never larger than the specified
- limit but may be considerably less than the threshold. Returns a
- pointer to the BDD for the superset if successful; NULL
- otherwise. The value for numVars should be as close as possible to
- the size of the support of f for better efficiency. However, it is
- safe to pass the value returned by Cudd_ReadSize for numVar. If 0
- is passed, then the value returned by Cudd_ReadSize is used.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]
-
-******************************************************************************/
-DdNode *
-Cudd_SupersetShortPaths(
- DdManager * dd /* manager */,
- DdNode * f /* function to be superset */,
- int numVars /* number of variables in the support of f */,
- int threshold /* maximum number of nodes in the subset */,
- int hardlimit /* flag: 1 if threshold is a hard limit */)
-{
- DdNode *subset, *g;
-
- g = Cudd_Not(f);
- memOut = 0;
- do {
- dd->reordered = 0;
- subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit);
- } while((dd->reordered ==1) && (!memOut));
-
- return(Cudd_NotCond(subset, (subset != NULL)));
-
-} /* end of Cudd_SupersetShortPaths */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [The outermost procedure to return a subset of the given BDD
- with the shortest path lengths.]
-
- Description [The outermost procedure to return a subset of the given
- BDD with the largest cubes. The path lengths are calculated, the maximum
- allowable path length is determined and the number of nodes of this
- path length that can be used to build a subset. If the threshold is
- larger than the size of the original BDD, the original BDD is
- returned. ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SubsetShortPaths]
-
-******************************************************************************/
-DdNode *
-cuddSubsetShortPaths(
- DdManager * dd /* DD manager */,
- DdNode * f /* function to be subset */,
- int numVars /* total number of variables in consideration */,
- int threshold /* maximum number of nodes allowed in the subset */,
- int hardlimit /* flag determining whether thershold should be respected strictly */)
-{
- st_table *pathTable;
- DdNode *N, *subset;
-
- unsigned int *pathLengthArray;
- unsigned int maxpath, oddLen, evenLen, pathLength, *excess;
- int i;
- NodeDist_t *nodeStat;
- struct AssortedInfo *info;
- st_table *subsetNodeTable;
-
- one = DD_ONE(dd);
- zero = Cudd_Not(one);
-
- if (numVars == 0) {
- /* set default value */
- numVars = Cudd_ReadSize(dd);
- }
-
- if (threshold > numVars) {
- threshold = threshold - numVars;
- }
- if (f == NULL) {
- fprintf(dd->err, "Cannot partition, nil object\n");
- dd->errorCode = CUDD_INVALID_ARG;
- return(NULL);
- }
- if (Cudd_IsConstant(f))
- return (f);
-
- pathLengthArray = ALLOC(unsigned int, numVars+1);
- for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0;
-
-
-#ifdef DD_DEBUG
- numCalls = 0;
-#endif
-
- pathTable = CreatePathTable(f, pathLengthArray, dd->err);
-
- if ((pathTable == NULL) || (memOut)) {
- if (pathTable != NULL)
- st_free_table(pathTable);
- FREE(pathLengthArray);
- return (NIL(DdNode));
- }
-
- excess = ALLOC(unsigned int, 1);
- *excess = 0;
- maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess,
- dd->err);
-
- if (maxpath != (unsigned) (numVars + 1)) {
-
- info = 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);
-#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);
- }
- }
-
-#ifdef DD_DEBUG
- 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 */
-
-#ifdef DD_DEBUG
- (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, stPathTableDdFree, (char *)dd);
-
- FREE(info);
-
- } else {/* if threshold larger than size of dd */
- subset = f;
- cuddRef(subset);
- }
- FREE(excess);
- st_free_table(pathTable);
- FREE(pathLengthArray);
- for (i = 0; i <= nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
-
-#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);
- }
- }
-#endif
-
- if (subset != NULL) {
- cuddDeref(subset);
- return(subset);
- } else {
- return(NULL);
- }
-
-} /* end of cuddSubsetShortPaths */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Resize the number of pages allocated to store the distances
- related to each node.]
-
- Description [Resize the number of pages allocated to store the distances
- related to each node. 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
- number of pages freeing stuff in case of memory out. ]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ResizeNodeDistPages(
- )
-{
- int i;
- NodeDist_t **newNodeDistPages;
-
- /* move to next page */
- nodeDistPage++;
-
- /* If the current page index is larger than the number of pages
- * allocated, allocate a new page array. Page numbers are incremented by
- * INITIAL_PAGES
- */
- if (nodeDistPage == maxNodeDistPages) {
- newNodeDistPages = ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES);
- if (newNodeDistPages == NULL) {
- for (i = 0; i < nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxNodeDistPages; i++) {
- newNodeDistPages[i] = nodeDistPages[i];
- }
- /* Increase total page count */
- maxNodeDistPages += INITIAL_PAGES;
- FREE(nodeDistPages);
- nodeDistPages = newNodeDistPages;
- }
- }
- /* Allocate a new page */
- currentNodeDistPage = nodeDistPages[nodeDistPage] = ALLOC(NodeDist_t,
- nodeDistPageSize);
- if (currentNodeDistPage == NULL) {
- for (i = 0; i < nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- memOut = 1;
- return;
- }
- /* reset page index */
- nodeDistPageIndex = 0;
- return;
-
-} /* end of ResizeNodeDistPages */
-
-
-/**Function********************************************************************
-
- 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
- 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
- number of pages freeing stuff in case of memory out. ]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ResizeQueuePages(
- )
-{
- 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
- * INITIAL_PAGES
- */
- if (queuePage == maxQueuePages) {
- newQueuePages = ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES);
- if (newQueuePages == NULL) {
- for (i = 0; i < queuePage; i++) FREE(queuePages[i]);
- FREE(queuePages);
- memOut = 1;
- return;
- } else {
- for (i = 0; i < maxQueuePages; i++) {
- newQueuePages[i] = queuePages[i];
- }
- /* Increase total page count */
- maxQueuePages += INITIAL_PAGES;
- FREE(queuePages);
- queuePages = newQueuePages;
- }
- }
- /* Allocate a new page */
- currentQueuePage = queuePages[queuePage] = ALLOC(DdNode *,queuePageSize);
- if (currentQueuePage == NULL) {
- for (i = 0; i < queuePage; i++) FREE(queuePages[i]);
- FREE(queuePages);
- memOut = 1;
- return;
- }
- /* reset page index */
- queuePageIndex = 0;
- return;
-
-} /* end of ResizeQueuePages */
-
-
-/**Function********************************************************************
-
- Synopsis [ Labels each node with its shortest distance from the root]
-
- Description [ Labels each node with its shortest distance from the root.
- This is done in a BFS search of the BDD. The nodes are processed
- in a queue implemented as pages(array) to reduce memory fragmentation.
- An entry is created for each node visited. The distance from the root
- to the node with the corresponding parity is updated. The procedure
- is called recursively each recusion level handling nodes at a given
- level from the root.]
-
-
- SideEffects [Creates entries in the pathTable]
-
- SeeAlso [CreatePathTable CreateBotDist]
-
-******************************************************************************/
-static void
-CreateTopDist(
- st_table * pathTable /* hast table to store path lengths */,
- int parentPage /* the pointer to the page on which the first parent in the queue is to be found. */,
- int parentQueueIndex /* pointer to the first parent on the page */,
- int topLen /* current distance from the root */,
- DdNode ** childPage /* pointer to the page on which the first child is to be added. */,
- int childQueueIndex /* pointer to the first child */,
- int numParents /* number of parents to process in this recursive call */,
- FILE *fp /* where to write messages */)
-{
- NodeDist_t *nodeStat;
- DdNode *N, *Nv, *Nnv, *node, *child, *regChild;
- int i;
- int processingDone, childrenCount;
-
-#ifdef DD_DEBUG
- numCalls++;
-
- /* assume this procedure comes in with only the root node*/
- /* 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");
- }
- assert(queuePageIndex == childQueueIndex);
- assert(currentQueuePage == childPage);
-#endif
- /* number children added to queue is initialized , needed for
- * 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;
- }
-
- 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++) FREE(queuePages[i]);
- 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++)
- FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- for (i = 0; i <= queuePage; i++) FREE(queuePages[i]);
- 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++)
- FREE(nodeDistPages[i]);
- 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++)
- FREE(nodeDistPages[i]);
- 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
- assert(queuePages[parentPage] == childPage);
- assert(parentQueueIndex == childQueueIndex);
-#endif
-
- if (childrenCount != 0) {
- topLen++;
- childPage = currentQueuePage;
- childQueueIndex = queuePageIndex;
- CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen,
- childPage, childQueueIndex, childrenCount, fp);
- }
-
- return;
-
-} /* end of CreateTopDist */
-
-
-/**Function********************************************************************
-
- Synopsis [ Labels each node with the shortest distance from the constant.]
-
- Description [Labels each node with the shortest distance from the constant.
- This is done in a DFS search of the BDD. Each node has an odd
- and even parity distance from the sink (since there exists paths to both
- zero and one) which is less than MAXSHORTINT. At each node these distances
- are updated using the minimum distance of its children from the constant.
- SInce now both the length from the root and child is known, the minimum path
- length(length of the shortest path between the root and the constant that
- this node lies on) of this node can be calculated and used to update the
- pathLengthArray]
-
- SideEffects [Updates Path Table and path length array]
-
- SeeAlso [CreatePathTable CreateTopDist AssessPathLength]
-
-******************************************************************************/
-static int
-CreateBotDist(
- DdNode * node /* current node */,
- st_table * pathTable /* path table with path lengths */,
- unsigned int * pathLengthArray /* array that stores number of nodes belonging to a particular path length. */,
- FILE *fp /* where to write messages */)
-{
- DdNode *N, *Nv, *Nnv;
- DdNode *realChild;
- DdNode *child, *regChild;
- NodeDist_t *nodeStat, *nodeStatChild;
- unsigned int oddLen, evenLen, pathLength;
- DdHalfWord botDist;
- int processingDone;
-
- if (Cudd_IsConstant(node))
- 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);
- }
-
- /* compute length of odd parity distances */
- if ((nodeStat->oddTopDist != MAXSHORTINT) &&
- (nodeStat->oddBotDist != MAXSHORTINT))
- oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist);
- else
- oddLen = MAXSHORTINT;
-
- /* compute length of even parity distances */
- if (!((nodeStat->evenTopDist == MAXSHORTINT) ||
- (nodeStat->evenBotDist == MAXSHORTINT)))
- evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
- else
- evenLen = MAXSHORTINT;
-
- /* assign pathlength to minimum of the two */
- pathLength = (oddLen <= evenLen) ? oddLen : evenLen;
-
- Nv = Cudd_T(N);
- Nnv = Cudd_E(N);
-
- /* 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 (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;
-
- } 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);
- else
- oddLen = MAXSHORTINT;
-
- if ((nodeStat->evenTopDist != MAXSHORTINT) &&
- (nodeStat->evenBotDist != MAXSHORTINT))
- evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
- else
- 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 (evenLen < pathLength ) {
- if (pathLength != MAXSHORTINT)
- pathLengthArray[pathLength]--;
- if (evenLen != MAXSHORTINT)
- pathLengthArray[evenLen]++;
- }
-
- return(1);
-
-} /*end of CreateBotDist */
-
-
-/**Function********************************************************************
-
- Synopsis [ The outer procedure to label each node with its shortest
- distance from the root and constant]
-
- Description [ The outer procedure to label each node with its shortest
- distance from the root and constant. Calls CreateTopDist and CreateBotDist.
- The basis for computing the distance between root and constant is that
- the distance may be the sum of even distances from the node to the root
- and constant or the sum of odd distances from the node to the root and
- constant. Both CreateTopDist and CreateBotDist create the odd and
- even parity distances from the root and constant respectively.]
-
- SideEffects [None]
-
- SeeAlso [CreateTopDist CreateBotDist]
-
-******************************************************************************/
-static st_table *
-CreatePathTable(
- DdNode * node /* root of function */,
- unsigned int * pathLengthArray /* array of path lengths to store nodes labeled with the various path lengths */,
- FILE *fp /* where to write messages */)
-{
-
- st_table *pathTable;
- NodeDist_t *nodeStat;
- DdHalfWord topLen;
- DdNode *N;
- int i, numParents;
- int insertValue;
- DdNode **childPage;
- int parentPage;
- int childQueueIndex, parentQueueIndex;
-
- /* Creating path Table for storing data about nodes */
- pathTable = st_init_table(st_ptrcmp,st_ptrhash);
-
- /* initializing pages for info about each node */
- maxNodeDistPages = INITIAL_PAGES;
- nodeDistPages = ALLOC(NodeDist_t *, maxNodeDistPages);
- if (nodeDistPages == NULL) {
- goto OUT_OF_MEM;
- }
- nodeDistPage = 0;
- currentNodeDistPage = nodeDistPages[nodeDistPage] =
- ALLOC(NodeDist_t, nodeDistPageSize);
- if (currentNodeDistPage == NULL) {
- for (i = 0; i <= nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- goto OUT_OF_MEM;
- }
- nodeDistPageIndex = 0;
-
- /* Initializing pages for the BFS search queue, implemented as an array. */
- maxQueuePages = INITIAL_PAGES;
- queuePages = ALLOC(DdNode **, maxQueuePages);
- if (queuePages == NULL) {
- goto OUT_OF_MEM;
- }
- queuePage = 0;
- currentQueuePage = queuePages[queuePage] = ALLOC(DdNode *, queuePageSize);
- if (currentQueuePage == NULL) {
- for (i = 0; i <= queuePage; i++) FREE(queuePages[i]);
- FREE(queuePages);
- goto OUT_OF_MEM;
- }
- queuePageIndex = 0;
-
- /* Enter the root node into the queue to start with. */
- parentPage = queuePage;
- parentQueueIndex = queuePageIndex;
- topLen = 0;
- *(currentQueuePage + queuePageIndex) = node;
- queuePageIndex++;
- childPage = currentQueuePage;
- childQueueIndex = queuePageIndex;
-
- N = Cudd_Regular(node);
-
- if (nodeDistPageIndex == nodeDistPageSize) ResizeNodeDistPages();
- if (memOut) {
- for (i = 0; i <= nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- for (i = 0; i <= queuePage; i++) FREE(queuePages[i]);
- FREE(queuePages);
- st_free_table(pathTable);
- goto OUT_OF_MEM;
- }
-
- nodeStat = currentNodeDistPage + nodeDistPageIndex;
- nodeDistPageIndex++;
-
- nodeStat->oddTopDist = MAXSHORTINT;
- nodeStat->evenTopDist = MAXSHORTINT;
- nodeStat->evenBotDist = MAXSHORTINT;
- nodeStat->oddBotDist = MAXSHORTINT;
- nodeStat->regResult = NULL;
- nodeStat->compResult = NULL;
-
- insertValue = st_insert(pathTable, (char *)N, (char *)nodeStat);
- if (insertValue == ST_OUT_OF_MEM) {
- memOut = 1;
- for (i = 0; i <= nodeDistPage; i++) FREE(nodeDistPages[i]);
- FREE(nodeDistPages);
- for (i = 0; i <= queuePage; i++) FREE(queuePages[i]);
- 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);
- }
-
- if (Cudd_IsComplement(node)) {
- nodeStat->oddTopDist = 0;
- } else {
- nodeStat->evenTopDist = 0;
- }
- numParents = 1;
- /* call the function that counts the distance of each node from the
- * root
- */
-#ifdef DD_DEBUG
- numCalls = 0;
-#endif
- CreateTopDist(pathTable, parentPage, parentQueueIndex, (int) topLen,
- childPage, childQueueIndex, numParents, fp);
- if (memOut) {
- fprintf(fp, "Out of Memory and cant count path lengths\n");
- goto OUT_OF_MEM;
- }
-
-#ifdef DD_DEBUG
- numCalls = 0;
-#endif
- /* call the function that counts the distance of each node from the
- * constant
- */
- if (!CreateBotDist(node, pathTable, pathLengthArray, fp)) return(NULL);
-
- /* free BFS queue pages as no longer required */
- for (i = 0; i <= queuePage; i++) FREE(queuePages[i]);
- FREE(queuePages);
- return(pathTable);
-
-OUT_OF_MEM:
- (void) fprintf(fp, "Out of Memory, cannot allocate pages\n");
- memOut = 1;
- return(NULL);
-
-} /*end of CreatePathTable */
-
-
-/**Function********************************************************************
-
- Synopsis [Chooses the maximum allowable path length of nodes under the
- threshold.]
-
- Description [Chooses the maximum allowable path length under each node.
- The corner cases are when the threshold is larger than the number
- of nodes in the BDD iself, in which case 'numVars + 1' is returned.
- If all nodes of a particular path length are needed, then the
- maxpath returned is the next one with excess nodes = 0;]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static unsigned int
-AssessPathLength(
- unsigned int * pathLengthArray /* array determining number of nodes belonging to the different path lengths */,
- int threshold /* threshold to determine maximum allowable nodes in the subset */,
- int numVars /* maximum number of variables */,
- unsigned int * excess /* number of nodes labeled maxpath required in the subset */,
- FILE *fp /* where to write messages */)
-{
- unsigned int i, maxpath;
- int temp;
-
- temp = threshold;
- i = 0;
- maxpath = 0;
- /* quit loop if i reaches max number of variables or if temp reaches
- * below zero
- */
- while ((i < (unsigned) numVars+1) && (temp > 0)) {
- 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;
- } else { /* normal case when subset required is less than size of
- original BDD */
- *excess = temp + pathLengthArray[maxpath];
- }
-
- if (maxpath == 0) {
- fprintf(fp, "Path Length array seems to be all zeroes, check\n");
- }
- return(maxpath);
-
-} /* end of AssessPathLength */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the BDD with nodes labeled with path length less than or equal to maxpath]
-
- Description [Builds the BDD with nodes labeled with path length
- under maxpath and as many nodes labeled maxpath as determined by the
- threshold. The procedure uses the path table to determine which nodes
- in the original bdd need to be retained. This procedure picks a
- shortest path (tie break decided by taking the child with the shortest
- distance to the constant) and recurs down the path till it reaches the
- constant. the procedure then starts building the subset upward from
- the constant. All nodes labeled by path lengths less than the given
- maxpath are used to build the subset. However, in the case of nodes
- that have label equal to maxpath, as many are chosen as required by
- the threshold. This number is stored in the info structure in the
- field thresholdReached. This field is decremented whenever a node
- labeled maxpath is encountered and the nodes labeled maxpath are
- aggregated in a maxpath table. As soon as the thresholdReached count
- goes to 0, the shortest path from this node to the constant is found.
- The extraction of nodes with the above labeling is based on the fact
- that each node, labeled with a path length, P, has at least one child
- labeled P or less. So extracting all nodes labeled a given path length
- P ensures complete paths between the root and the constant. Extraction
- of a partial number of nodes with a given path length may result in
- incomplete paths and hence the additional number of nodes are grabbed
- to complete the path. Since the Bdd is built bottom-up, other nodes
- labeled maxpath do lie on complete paths. The procedure may cause the
- subset to have a larger or smaller number of nodes than the specified
- threshold. The increase in the number of nodes is caused by the
- building of a subset and the reduction by recombination. However in
- most cases, the recombination overshadows the increase and the
- procedure returns a result with lower number of nodes than specified.
- The subsetNodeTable is NIL when there is no hard limit on the number
- of nodes. Further efforts towards keeping the subset closer to the
- threshold number were abandoned in favour of keeping the procedure
- simple and fast.]
-
- SideEffects [SubsetNodeTable is changed if it is not NIL.]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-BuildSubsetBdd(
- DdManager * dd /* DD manager */,
- st_table * pathTable /* path table with path lengths and computed results */,
- DdNode * node /* current node */,
- struct AssortedInfo * info /* assorted information structure */,
- st_table * subsetNodeTable /* table storing computed results */)
-{
- DdNode *N, *Nv, *Nnv;
- DdNode *ThenBranch, *ElseBranch, *childBranch;
- DdNode *child, *regChild, *regNnv, *regNv;
- NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv;
- DdNode *neW, *topv, *regNew;
- char *entry;
- unsigned int topid;
- unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength;
- unsigned int NvBotDist, NnvBotDist;
- int tiebreakChild;
- int processingDone, thenDone, elseDone;
-
-
-#ifdef DD_DEBUG
- numCalls++;
-#endif
- if (Cudd_IsConstant(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 the node in the table has been visited, then return the corresponding
- ** Dd. Since a node can become a subset of itself, its
- ** complement (that is te same node reached by a different parity) will
- ** become a superset of the original node and result in some minterms
- ** that were not in the original set. Hence two different results are
- ** maintained, corresponding to the odd and even parities.
- */
-
- /* If this node is reached with an odd parity, get odd parity results. */
- if (Cudd_IsComplement(node)) {
- if (nodeStat->compResult != NULL) {
-#ifdef DD_DEBUG
- hits++;
-#endif
- return(nodeStat->compResult);
- }
- } else {
- /* if this node is reached with an even parity, get even parity
- * results
- */
- if (nodeStat->regResult != NULL) {
-#ifdef DD_DEBUG
- hits++;
-#endif
- return(nodeStat->regResult);
- }
- }
-
-
- /* get children */
- Nv = Cudd_T(N);
- Nnv = Cudd_E(N);
-
- Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
- Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
-
- /* no child processed */
- processingDone = 0;
- /* then child not processed */
- thenDone = 0;
- ThenBranch = NULL;
- /* else child not processed */
- elseDone = 0;
- 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;
- }
-
- ThenBranch = Nv;
- cuddRef(ThenBranch);
- if (ThenBranch == NULL) {
- return(NULL);
- }
-
- 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;
- }
-
- 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;
- }
- /* 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;
- }
-
- 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);
- } else {
- oddLen = 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;
- }
-
- 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;
- } 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);
- } 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;
- }
- if (ElseBranch != NULL) {
- Cudd_RecursiveDeref(dd, ElseBranch);
- ElseBranch = NULL;
- }
- return(NULL);
- }
-
- cuddRef(childBranch);
-
- if (child == Nv) {
- ThenBranch = childBranch;
- } else {
- ElseBranch = childBranch;
- }
- processingDone++;
-
- } /*end of while processing Nv, Nnv */
-
- info->findShortestPath = 0;
- topid = Cudd_NodeReadIndex(N);
- topv = Cudd_ReadVars(dd, topid);
- cuddRef(topv);
- neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch);
- if (neW != NULL) {
- cuddRef(neW);
- }
- Cudd_RecursiveDeref(dd, topv);
- Cudd_RecursiveDeref(dd, ThenBranch);
- Cudd_RecursiveDeref(dd, ElseBranch);
-
-
- /* 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;
- }
- }
- }
- }
-
-
- if (neW == 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) {
-#ifdef DD_DEBUG
- 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);
- }
-
- } else {
- nodeStat->regResult = neW;
- cuddRef(nodeStat->regResult);
- if (neW == node) {
-#ifdef DD_DEBUG
- thishit++;
-#endif
- if (nodeStat->compResult != NULL) {
- Cudd_RecursiveDeref(dd, nodeStat->compResult);
- }
- nodeStat->compResult = Cudd_Not(neW);
- cuddRef(nodeStat->compResult);
- }
- }
-
- cuddDeref(neW);
- return(neW);
- } /* end of else i.e. Subset != NULL */
-} /* end of BuildSubsetBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Procedure to free te result dds stored in the NodeDist pages.]
-
- Description [None]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static enum st_retval
-stPathTableDdFree(
- char * key,
- char * value,
- char * arg)
-{
- NodeDist_t *nodeStat;
- DdManager *dd;
-
- nodeStat = (NodeDist_t *)value;
- dd = (DdManager *)arg;
- if (nodeStat->regResult != NULL) {
- Cudd_RecursiveDeref(dd, nodeStat->regResult);
- }
- if (nodeStat->compResult != NULL) {
- Cudd_RecursiveDeref(dd, nodeStat->compResult);
- }
- return(ST_CONTINUE);
-
-} /* end of stPathTableFree */
diff --git a/src/bdd/cudd/cuddSymmetry.c b/src/bdd/cudd/cuddSymmetry.c
deleted file mode 100644
index e5488b17..00000000
--- a/src/bdd/cudd/cuddSymmetry.c
+++ /dev/null
@@ -1,1668 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddSymmetry.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define MV_OOM (Move *)1
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static int *entry;
-
-extern int ddTotalNumberSwapping;
-#ifdef DD_STATS
-extern int ddTotalNISwaps;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints statistics on symmetric variables.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-void
-Cudd_SymmProfile(
- DdManager * table,
- int lower,
- int upper)
-{
- int i,x,gbot;
- int TotalSymm = 0;
- 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++;
-#ifdef DD_DEBUG
- assert(table->subtables[gbot].next == (unsigned) i);
-#endif
- 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);
-
-} /* end of Cudd_SymmProfile */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for symmetry of x and y.]
-
- Description [Checks for symmetry of x and y. Ignores projection
- functions, unless they are isolated. Returns 1 in case of symmetry; 0
- otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddSymmCheck(
- DdManager * table,
- int x,
- 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 yindex;
- int i;
- DdNodePtr *list;
- int slots;
- DdNode *sentinel = &(table->sentinel);
-#ifdef DD_DEBUG
- int xindex;
-#endif
-
- /* Checks that x and y are not the projection functions.
- ** For x it is sufficient to check whether there is only one
- ** node; indeed, if there is one node, it is the projection function
- ** and it cannot point to y. Hence, if y isn't just the projection
- ** function, it has one arc coming from a layer different from x.
- */
- if (table->subtables[x].keys == 1) {
- return(0);
- }
- yindex = table->invperm[y];
- if (table->subtables[y].keys == 1) {
- if (table->vars[yindex]->ref == 1)
- return(0);
- }
-
- xsymmy = xsymmyp = 1;
- arccount = 0;
- 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 */
- } /* for */
-
- /* Calculate the total reference counts of y */
- 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;
- }
- }
-
-#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);
- }
-#endif
-
- return(arccount == TotalRefCount);
-
-} /* end of cuddSymmCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Symmetric sifting algorithm.]
-
- Description [Symmetric sifting algorithm.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries in
- each unique subtable.
- <li> Sift the variable up and down, remembering each time the total
- size of the DD heap and grouping variables that are symmetric.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 plus the number of symmetric variables if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddSymmSiftingConv]
-
-******************************************************************************/
-int
-cuddSymmSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
- int symvars;
- int symgroups;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- size = table->size;
-
- /* Find order in which to sift variables. */
- var = NULL;
- entry = ALLOC(int,size);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto ddSymmSiftingOutOfMem;
- }
- var = ALLOC(int,size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare);
-
- /* Initialize the symmetry of each subtable to itself. */
- for (i = lower; i <= upper; i++) {
- table->subtables[i].next = i;
- }
-
- for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
- if (ddTotalNumberSwapping >= table->siftMaxSwap)
- break;
- x = table->perm[var[i]];
-#ifdef DD_STATS
- 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;
-#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);
-#endif
- }
- }
-
- FREE(var);
- FREE(entry);
-
- ddSymmSummary(table, lower, upper, &symvars, &symgroups);
-
-#ifdef DD_STATS
- (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
- symvars);
- (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
- symgroups);
-#endif
-
- return(1+symvars);
-
-ddSymmSiftingOutOfMem:
-
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddSymmSifting */
-
-
-/**Function********************************************************************
-
- Synopsis [Symmetric sifting to convergence algorithm.]
-
- Description [Symmetric sifting to convergence algorithm.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries in
- each unique subtable.
- <li> Sift the variable up and down, remembering each time the total
- size of the DD heap and grouping variables that are symmetric.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- <li> Repeat 1-4 until no further improvement.
- </ol>
- Returns 1 plus the number of symmetric variables if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddSymmSifting]
-
-******************************************************************************/
-int
-cuddSymmSiftingConv(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
- int symvars;
- int symgroups;
- int classes;
- int initialSize;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- initialSize = table->keys - table->isolated;
-
- size = table->size;
-
- /* Find order in which to sift variables. */
- var = NULL;
- entry = ALLOC(int,size);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto ddSymmSiftingConvOutOfMem;
- }
- var = ALLOC(int,size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))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;
- }
-
- 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) {
-#ifdef DD_STATS
- previousSize = table->keys - table->isolated;
-#endif
- 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);
-#endif
- }
- }
-
- /* Sifting now until convergence. */
- while ((unsigned) initialSize > table->keys - table->isolated) {
- initialSize = table->keys - table->isolated;
-#ifdef DD_STATS
- (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;
- }
- /* 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);
-
- /* 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;
-#endif
- 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);
-#endif
- }
- } /* for */
- }
-
- ddSymmSummary(table, lower, upper, &symvars, &symgroups);
-
-#ifdef DD_STATS
- (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
- symvars);
- (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
- symgroups);
-#endif
-
- FREE(var);
- FREE(entry);
-
- return(1+symvars);
-
-ddSymmSiftingConvOutOfMem:
-
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddSymmSiftingConv */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the variables
- according to the number of keys in the subtables.
- Returns the difference in number of keys between the two
- variables being compared.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmUniqueCompare(
- int * ptrX,
- int * ptrY)
-{
-#if 0
- if (entry[*ptrY] == entry[*ptrX]) {
- return((*ptrX) - (*ptrY));
- }
-#endif
- return(entry[*ptrY] - entry[*ptrX]);
-
-} /* end of ddSymmUniqueCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Assumes that x is not part of a symmetry group. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmSiftingAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
- Move *move;
- 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 initGroupSize, finalGroupSize;
-
-
-#ifdef DD_DEBUG
- /* check for previously detected symmetry */
- assert(table->subtables[x].next == (unsigned) x);
-#endif
-
- initialSize = table->keys - table->isolated;
-
- moveDown = NULL;
- 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 */
- }
- } 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;
- }
- 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;
-
- if (x == xLow) { /* Sift down */
-
-#ifdef DD_DEBUG
- /* x must be a singleton */
- assert((unsigned) x == table->subtables[x].next);
-#endif
- if (x == xHigh) return(1); /* just one variable */
-
- 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);
-
- 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);
-#endif
- 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;
-
- } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */
- /* 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 */
-
- 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);
-
- 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);
-#endif
- 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;
-
- } 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;
- }
- 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);
-#endif
- initGroupSize = i - x + 1;
-
- 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;
- }
-#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);
-#endif
- 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;
- }
- initialSize = table->keys - table->isolated;
- moveDown = ddSymmSiftingDown(table,x,xHigh);
- result = ddSymmSiftingBackward(table,moveDown,initialSize);
- }
- if (!result) goto ddSymmSiftingAuxOutOfMem;
-
- } else { /* moving up first: shorter */
- /* 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 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;
- }
-#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);
-#endif
- initGroupSize = x - i + 1;
-
- 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;
- }
-#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);
-#endif
- 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;
- }
- initialSize = table->keys - table->isolated;
- moveUp = ddSymmSiftingUp(table,x,xLow);
- result = ddSymmSiftingBackward(table,moveUp,initialSize);
- }
- if (!result) goto ddSymmSiftingAuxOutOfMem;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
-
- return(1);
-
-ddSymmSiftingAuxOutOfMem:
- if (moveDown != MV_OOM) {
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- }
- if (moveUp != MV_OOM) {
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
- }
-
- return(0);
-
-} /* end of ddSymmSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Assumes that x is either an isolated variable, or it is the bottom of
- a symmetry group. All symmetries may not have been found, because of
- exceeded growth limit. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmSiftingConvAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
- Move *move;
- Move *moveUp; /* list of up moves */
- Move *moveDown; /* list of down moves */
- int initialSize;
- int result;
- int i;
- int initGroupSize, finalGroupSize;
-
-
- initialSize = table->keys - table->isolated;
-
- moveDown = NULL;
- moveUp = NULL;
-
- if (x == xLow) { /* Sift down */
-#ifdef DD_DEBUG
- /* x is bottom of symmetry group */
- assert((unsigned) x >= table->subtables[x].next);
-#endif
- i = table->subtables[x].next;
- 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);
-
- 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);
-#endif
- 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;
-
- } 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 */
-
- if (x == xLow) return(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);
-
- 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);
-#endif
- 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;
-
- } 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;
- }
- } 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);
-#endif
- initGroupSize = i - x + 1;
-
- 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;
- }
-#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);
-#endif
- 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;
- }
- initialSize = table->keys - table->isolated;
- moveDown = ddSymmSiftingDown(table,x,xHigh);
- result = ddSymmSiftingBackward(table,moveDown,initialSize);
- }
- if (!result) goto ddSymmSiftingConvAuxOutOfMem;
-
- } else { /* moving up first: shorter */
- /* 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;
-
- 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);
- assert((unsigned) i == table->subtables[x].next);
-#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;
- }
- } 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);
-#endif
- 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;
- }
- initialSize = table->keys - table->isolated;
- moveUp = ddSymmSiftingUp(table,x,xLow);
- result = ddSymmSiftingBackward(table,moveUp,initialSize);
- }
- if (!result) goto ddSymmSiftingConvAuxOutOfMem;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
-
- return(1);
-
-ddSymmSiftingConvAuxOutOfMem:
- if (moveDown != MV_OOM) {
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *) moveDown);
- moveDown = move;
- }
- }
- if (moveUp != MV_OOM) {
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *) moveUp);
- moveUp = move;
- }
- }
-
- return(0);
-
-} /* end of ddSymmSiftingConvAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves x up until either it reaches the bound (xLow) or
- the size of the DD heap increases too much.]
-
- Description [Moves x up until either it reaches the bound (xLow) or
- the size of the DD heap increases too much. Assumes that x is the top
- of a symmetry group. Checks x for symmetry to the adjacent
- variables. If symmetry is found, the symmetry group of x is merged
- with the symmetry group of the other variable. Returns the set of
- moves in case of success; MV_OOM if memory is full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddSymmSiftingUp(
- DdManager * table,
- int y,
- int xLow)
-{
- Move *moves;
- Move *move;
- int x;
- int size;
- int i;
- int gxtop,gybot;
- int limitSize;
- int xindex, yindex;
- int zindex;
- int z;
- int isolated;
- int L; /* lower bound on DD size */
-#ifdef DD_DEBUG
- int checkL;
-#endif
-
-
- moves = NULL;
- yindex = table->invperm[y];
-
- /* Initialize the lower bound.
- ** The part of the DD below the bottom of y' group will not change.
- ** The part of the DD above y that does not interact with y will not
- ** change. The rest may vanish in the best case, except for
- ** the nodes at level xLow, which will not vanish, regardless.
- */
- limitSize = L = table->keys - table->isolated;
- gybot = y;
- while ((unsigned) 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;
- }
- }
-
- 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;
- }
- }
- 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);
-#ifdef DD_DEBUG
- 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;
- }
- 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);
- }
-
- return(moves);
-
-ddSymmSiftingUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(MV_OOM);
-
-} /* end of ddSymmSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves x down until either it reaches the bound (xHigh) or
- the size of the DD heap increases too much.]
-
- Description [Moves x down until either it reaches the bound (xHigh)
- or the size of the DD heap increases too much. Assumes that x is the
- bottom of a symmetry group. Checks x for symmetry to the adjacent
- variables. If symmetry is found, the symmetry group of x is merged
- with the symmetry group of the other variable. Returns the set of
- moves in case of success; MV_OOM if memory is full.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move *
-ddSymmSiftingDown(
- DdManager * table,
- int x,
- int xHigh)
-{
- Move *moves;
- Move *move;
- int y;
- int size;
- int limitSize;
- int gxtop,gybot;
- int R; /* upper bound on node decrease */
- int xindex, yindex;
- int isolated;
- int z;
- int zindex;
-#ifdef DD_DEBUG
- int checkR;
-#endif
-
- moves = NULL;
- /* 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;
- }
- }
-
- 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;
- }
- 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 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);
- }
-
- return(moves);
-
-ddSymmSiftingDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(MV_OOM);
-
-} /* end of ddSymmSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two groups.]
-
- Description [Swaps two groups. x is assumed to be the bottom variable
- of the first group. y is assumed to be the top variable of the second
- group. Updates the list of moves. Returns the number of keys in the
- table if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmGroupMove(
- DdManager * table,
- int x,
- int y,
- Move ** moves)
-{
- Move *move;
- int size;
- int i,j;
- int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
- int swapx,swapy;
-
-#if DD_DEBUG
- assert(x < y); /* we assume that x < y */
-#endif
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtables[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) 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;
- 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 = xtop; /* y is bottom of its group, join */
- /* 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 = newxtop; /* x is bottom of its group, join */
- /* its symmetry to top of its group */
- /* Store group move */
- move = (Move *) cuddDynamicAllocNode(table);
- if (move == NULL) return(0);
- move->x = swapx;
- move->y = swapy;
- move->size = size;
- move->next = *moves;
- *moves = move;
-
- return(size);
-
-} /* end of ddSymmGroupMove */
-
-
-/**Function********************************************************************
-
- Synopsis [Undoes the swap of two groups.]
-
- Description [Undoes the swap of two groups. x is assumed to be the
- bottom variable of the first group. y is assumed to be the top
- variable of the second group. Returns the number of keys in the table
- if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmGroupMoveBackward(
- DdManager * table,
- int x,
- int y)
-{
- int size;
- int i,j;
- int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
-
-#if DD_DEBUG
- assert(x < y); /* We assume that x < y */
-#endif
-
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtables[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) 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;
- }
-
- /* Fix symmetries. */
- y = xtop;
- for (i = 0; i < ysize-1 ; i++) {
- 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 */
- 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 = newxtop; /* x is bottom of its group, join */
- /* its symmetry to top of its group */
-
- return(size);
-
-} /* end of ddSymmGroupMoveBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the DD heap to the position
- giving the minimum size.]
-
- Description [Given a set of moves, returns the DD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddSymmSiftingBackward(
- DdManager * table,
- Move * moves,
- int size)
-{
- Move *move;
- int res;
-
- for (move = moves; move != NULL; move = move->next) {
- 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);
-#ifdef DD_DEBUG
- 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);
- }
-
- return(1);
-
-} /* end of ddSymmSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts numbers of symmetric variables and symmetry
- groups.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddSymmSummary(
- DdManager * table,
- int lower,
- int upper,
- int * symvars,
- int * symgroups)
-{
- int i,x,gbot;
- int TotalSymm = 0;
- 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);
-#ifdef DD_DEBUG
- assert(table->subtables[gbot].next == (unsigned) i);
-#endif
- i = gbot;
- }
- }
- *symvars = TotalSymm;
- *symgroups = TotalSymmGroups;
-
- return;
-
-} /* end of ddSymmSummary */
diff --git a/src/bdd/cudd/cuddTable.c b/src/bdd/cudd/cuddTable.c
deleted file mode 100644
index 7f14aed1..00000000
--- a/src/bdd/cudd/cuddTable.c
+++ /dev/null
@@ -1,3141 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddTable.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef DD_UNSORTED_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
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/* This is a hack for when CUDD_VALUE_TYPE is double */
-typedef union hack {
- CUDD_VALUE_TYPE value;
- unsigned int bits[2];
-} hack;
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-#ifndef DD_UNSORTED_FREE_LIST
-/* Macros for red/black trees. */
-#define DD_COLOR(p) ((p)->index)
-#define DD_IS_BLACK(p) ((p)->index == DD_BLACK)
-#define DD_IS_RED(p) ((p)->index == DD_RED)
-#define DD_LEFT(p) cuddT(p)
-#define DD_RIGHT(p) cuddE(p)
-#define DD_NEXT(p) ((p)->next)
-#endif
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-#ifdef DD_DEBUG
-static int cuddCheckCollisionOrdering ARGS((DdManager *unique, int i, int j));
-#endif
-static void ddReportRefMess ARGS((DdManager *unique, int i, char *caller));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the next prime &gt;= p.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-unsigned int
-Cudd_Prime(
- unsigned int p)
-{
- int i,pn;
-
- p--;
- do {
- p++;
- if (p&1) {
- pn = 1;
- i = 3;
- while ((unsigned) (i * i) <= p) {
- if (p % i == 0) {
- pn = 0;
- break;
- }
- i += 2;
- }
- } else {
- pn = 0;
- }
- } while (!pn);
- return(p);
-
-} /* end of Cudd_Prime */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Fast storage allocation for DdNodes in the table.]
-
- Description [Fast storage allocation for DdNodes in the table. The
- first 4 bytes of a chunk contain a pointer to the next block; the
- rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to
- a new node if successful; NULL is memory is full.]
-
- SideEffects [None]
-
- SeeAlso [cuddDynamicAllocNode]
-
-******************************************************************************/
-DdNode *
-cuddAllocNode(
- DdManager * unique)
-{
- 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);
- }
- /* Try to allocate a new block. */
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- mem = (DdNodePtr *) 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) {
- FREE(unique->stash);
- unique->stash = NULL;
- /* Inhibit resizing of tables. */
- cuddSlowTableGrowth(unique);
- /* Now try again. */
- mem = (DdNodePtr *) 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);
- }
- }
- }
- 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;
- return(node);
-
-} /* end of cuddAllocNode */
-
-
-/**Function********************************************************************
-
- Synopsis [Creates and initializes the unique table.]
-
- Description [Creates and initializes the unique table. Returns a pointer
- to the table if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Init cuddFreeTable]
-
-******************************************************************************/
-DdManager *
-cuddInitTable(
- unsigned int numVars /* Initial number of BDD variables (and subtables) */,
- unsigned int numVarsZ /* Initial number of ZDD variables (and subtables) */,
- unsigned int numSlots /* Initial size of the BDD subtables */,
- unsigned int looseUpTo /* Limit for fast table growth */)
-{
- DdManager *unique = ALLOC(DdManager,1);
- int i, j;
- DdNodePtr *nodelist;
- DdNode *sentinel;
- unsigned int slots;
- int shift;
-
- if (unique == NULL) {
- return(NULL);
- }
- sentinel = &(unique->sentinel);
- sentinel->ref = 0;
- sentinel->index = 0;
- cuddT(sentinel) = NULL;
- cuddE(sentinel) = NULL;
- sentinel->next = NULL;
- 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->size = numVars;
- unique->sizeZ = numVarsZ;
- unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars);
- unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ);
-
- /* Adjust the requested number of slots to a power of 2. */
- slots = 8;
- while (slots < numSlots) {
- 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->keysZ = 0;
- unique->dead = 0;
- unique->deadZ = 0;
- unique->gcFrac = DD_GC_FRAC_HI;
- unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
- unique->looseUpTo = looseUpTo;
- unique->gcEnabled = 1;
- unique->allocated = 0;
- unique->reclaimed = 0;
- unique->subtables = ALLOC(DdSubtable,unique->maxSize);
- if (unique->subtables == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ);
- if (unique->subtableZ == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->perm = ALLOC(int,unique->maxSize);
- if (unique->perm == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->invperm = ALLOC(int,unique->maxSize);
- if (unique->invperm == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->permZ = ALLOC(int,unique->maxSizeZ);
- if (unique->permZ == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->invpermZ = ALLOC(int,unique->maxSizeZ);
- if (unique->invpermZ == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->map = NULL;
- unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1);
- if (unique->stack == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- unique->stack[0] = NULL; /* to suppress harmless UMR */
-
-#ifndef DD_NO_DEATH_ROW
- unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2);
- unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth);
- if (unique->deathRow == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (i = 0; i < unique->deathRowDepth; i++) {
- 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;
-
- nodelist = unique->subtables[i].nodelist = 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;
- }
- 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 = 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->constants.slots = slots;
- unique->constants.shift = shift;
- unique->constants.keys = 0;
- unique->constants.dead = 0;
- unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
- nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots);
- if (nodelist == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (j = 0; (unsigned) j < slots; j++) {
- 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);
-#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->reordered = 0;
- unique->autoMethod = CUDD_REORDER_SIFT;
- unique->autoMethodZ = CUDD_REORDER_SIFT;
- unique->nextDyn = DD_FIRST_REORDER;
- unique->countDead = ~0;
- unique->siftMaxVar = DD_SIFT_MAX_VAR;
- unique->siftMaxSwap = DD_SIFT_MAX_SWAPS;
- unique->tree = NULL;
- unique->treeZ = NULL;
- unique->groupcheck = CUDD_GROUP_CHECK7;
- unique->recomb = DD_DEFAULT_RECOMB;
- unique->symmviolation = 0;
- unique->arcviolation = 0;
- unique->populationSize = 0;
- unique->numberXovers = 0;
- unique->linear = NULL;
- unique->linearSize = 0;
-
- /* Initialize ZDD universe. */
- unique->univ = (DdNodePtr *)NULL;
-
- /* Initialize auxiliary fields. */
- unique->localCaches = NULL;
- unique->preGCHook = NULL;
- unique->postGCHook = NULL;
- unique->preReorderingHook = NULL;
- unique->postReorderingHook = NULL;
- unique->out = stdout;
- unique->err = stderr;
- unique->errorCode = CUDD_NO_ERROR;
-
- /* Initialize statistical counters. */
- unique->maxmemhard = (long) ((~ (unsigned long) 0) >> 1);
- unique->garbageCollections = 0;
- unique->GCTime = 0;
- unique->reordTime = 0;
-#ifdef DD_STATS
- unique->nodesDropped = 0;
- unique->nodesFreed = 0;
-#endif
- unique->peakLiveNodes = 0;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLookUps = 0;
- unique->uniqueLinks = 0;
-#endif
-#ifdef DD_COUNT
- unique->recursiveCalls = 0;
- unique->swapSteps = 0;
-#ifdef DD_STATS
- unique->nextSample = 250000;
-#endif
-#endif
-
- return(unique);
-
-} /* end of cuddInitTable */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the resources associated to a unique table.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddInitTable]
-
-******************************************************************************/
-void
-cuddFreeTable(
- DdManager * unique)
-{
- DdNodePtr *next;
- DdNodePtr *memlist = unique->memoryList;
- int i;
-
- if (unique->univ != NULL) cuddZddFreeUniv(unique);
- while (memlist != NULL) {
- next = (DdNodePtr *) memlist[0]; /* link to next block */
- FREE(memlist);
- memlist = next;
- }
- unique->nextFree = NULL;
- unique->memoryList = NULL;
-
- for (i = 0; i < unique->size; i++) {
- FREE(unique->subtables[i].nodelist);
- }
- for (i = 0; i < unique->sizeZ; i++) {
- FREE(unique->subtableZ[i].nodelist);
- }
- FREE(unique->constants.nodelist);
- FREE(unique->subtables);
- FREE(unique->subtableZ);
- FREE(unique->acache);
- FREE(unique->perm);
- FREE(unique->permZ);
- FREE(unique->invperm);
- FREE(unique->invpermZ);
- FREE(unique->vars);
- if (unique->map != NULL) FREE(unique->map);
- FREE(unique->stack);
-#ifndef DD_NO_DEATH_ROW
- FREE(unique->deathRow);
-#endif
- if (unique->tree != NULL) Mtr_FreeTree(unique->tree);
- if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ);
- if (unique->linear != NULL) FREE(unique->linear);
- while (unique->preGCHook != NULL)
- Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK);
- while (unique->postGCHook != NULL)
- Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK);
- while (unique->preReorderingHook != NULL)
- Cudd_RemoveHook(unique,unique->preReorderingHook->f,
- CUDD_PRE_REORDERING_HOOK);
- while (unique->postReorderingHook != NULL)
- Cudd_RemoveHook(unique,unique->postReorderingHook->f,
- CUDD_POST_REORDERING_HOOK);
- FREE(unique);
-
-} /* end of cuddFreeTable */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs garbage collection on a unique table.]
-
- Description [Performs garbage collection on a 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
- cuddGarbageCollect. (As in the case of dynamic reordering.)
- Returns the total number of deleted nodes.]
-
- SideEffects [None]
-
- SeeAlso [cuddGarbageCollectZdd]
-
-******************************************************************************/
-int
-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;
-#ifndef DD_UNSORTED_FREE_LIST
- DdNodePtr tree;
-#endif
-
-#ifndef DD_NO_DEATH_ROW
- cuddClearDeathRow(unique);
-#endif
-
- 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);
- 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->gcFrac == DD_GC_FRAC_LO &&
- 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);
-#endif
- unique->gcFrac = DD_GC_FRAC_HI;
- return(0);
- }
-
- localTime = util_cpu_time();
-
- unique->garbageCollections++;
-#ifdef DD_VERBOSE
- (void) fprintf(unique->err,
- "garbage collecting (%d dead out of %d, min %d)...",
- unique->dead, unique->keys, unique->minDead);
-#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++;
- }
- }
- }
- cuddLocalCacheClearDead(unique);
- }
-
- /* Now return dead nodes to free list. Count them for sanity check. */
- totalDeleted = 0;
-#ifndef DD_UNSORTED_FREE_LIST
- tree = NULL;
-#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++;
-#ifndef DD_UNSORTED_FREE_LIST
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- cuddOrderedInsert(&tree,node);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-#else
- cuddDeallocNode(unique,node);
-#endif
- } else {
- *lastP = node;
- lastP = &(node->next);
- }
- node = next;
- }
- *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;
- }
- 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++;
-#ifndef DD_UNSORTED_FREE_LIST
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- cuddOrderedInsert(&tree,node);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-#else
- cuddDeallocNode(unique,node);
-#endif
- } else {
- *lastP = node;
- lastP = &(node->next);
- }
- node = next;
- }
- *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) totalDeleted != unique->dead) {
- ddReportRefMess(unique, -1, "cuddGarbageCollect");
- }
- unique->keys -= totalDeleted;
- unique->dead = 0;
-#ifdef DD_STATS
- 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
-
- 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++;
-#ifndef DD_UNSORTED_FREE_LIST
-#ifdef __osf__
-#pragma pointer_size save
-#pragma pointer_size short
-#endif
- cuddOrderedInsert(&tree,node);
-#ifdef __osf__
-#pragma pointer_size restore
-#endif
-#else
- cuddDeallocNode(unique,node);
-#endif
- } else {
- *lastP = node;
- lastP = &(node->next);
- }
- node = next;
- }
- *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;
- }
-
- /* 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");
- }
- unique->keysZ -= totalDeleted;
- unique->deadZ = 0;
-#ifdef DD_STATS
- 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,"ZDD",NULL);
- if (res == 0) return(0);
- hook = hook->next;
- }
-
-#ifdef DD_VERBOSE
- (void) fprintf(unique->err," done\n");
-#endif
-
- return(totalDeleted);
-
-} /* end of cuddGarbageCollectZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Wrapper for cuddUniqueInterZdd.]
-
- Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD
- reduction rule. Returns a pointer to the result node under normal
- conditions; NULL if reordering occurred or memory was exhausted.]
-
- SideEffects [None]
-
- SeeAlso [cuddUniqueInterZdd]
-
-******************************************************************************/
-DdNode *
-cuddZddGetNode(
- DdManager * zdd,
- int id,
- DdNode * T,
- DdNode * E)
-{
- DdNode *node;
-
- if (T == DD_ZERO(zdd))
- return(E);
- node = cuddUniqueInterZdd(zdd, id, T, E);
- return(node);
-
-} /* end of cuddZddGetNode */
-
-
-/**Function********************************************************************
-
- Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable
- ordering.]
-
- Description [Wrapper for cuddUniqueInterZdd that is independent of
- variable ordering (IVO). This function does not require parameter
- index to precede the indices of the top nodes of g and h in the
- variable order. Returns a pointer to the result node under normal
- conditions; NULL if reordering occurred or memory was exhausted.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddGetNode cuddZddIsop]
-
-******************************************************************************/
-DdNode *
-cuddZddGetNodeIVO(
- DdManager * dd,
- int index,
- DdNode * g,
- DdNode * h)
-{
- 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);
- }
- cuddRef(f);
- t = cuddZddProduct(dd, f, g);
- if (t == 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);
- }
- cuddRef(r);
- Cudd_RecursiveDerefZdd(dd, t);
-
- cuddDeref(r);
- return(r);
-
-} /* end of cuddZddGetNodeIVO */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the unique table for the existence of an internal node.]
-
- Description [Checks the unique table for the existence of an internal
- node. If it does not exist, it creates a new one. Does not
- modify the reference count of whatever is returned. A newly created
- internal node comes back with a reference count 0. For a newly
- created node, increments the reference counts of what T and E point
- to. Returns a pointer to the new node if successful; NULL if memory
- is exhausted or if reordering took place.]
-
- SideEffects [None]
-
- SeeAlso [cuddUniqueInterZdd]
-
-******************************************************************************/
-DdNode *
-cuddUniqueInter(
- DdManager * unique,
- int index,
- DdNode * T,
- DdNode * E)
-{
- int pos;
- unsigned int level;
- int retval;
- DdNodePtr *nodelist;
- DdNode *looking;
- DdNodePtr *previousP;
- DdSubtable *subtable;
- int gcNumber;
-
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLookUps++;
-#endif
-
- if (index >= unique->size) {
- if (!ddResizeTable(unique,index)) return(NULL);
- }
-
- level = unique->perm[index];
- subtable = &(unique->subtables[level]);
-
-#ifdef DD_DEBUG
- assert(level < (unsigned) cuddI(unique,T->index));
- assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
-#endif
-
- 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++;
-#endif
- }
- while (T == cuddT(looking) && E < cuddE(looking)) {
- previousP = &(looking->next);
- looking = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- if (T == cuddT(looking) && E == cuddE(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);
-#endif
- 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;
-#endif
- 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);
- looking = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- while (T == cuddT(looking) && E < cuddE(looking)) {
- previousP = &(looking->next);
- looking = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- }
-
- gcNumber = unique->garbageCollections;
- looking = cuddAllocNode(unique);
- if (looking == 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);
- looking2 = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- while (T == cuddT(looking2) && E < cuddE(looking2)) {
- previousP = &(looking2->next);
- looking2 = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- 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 */
- cuddRef(E);
-
-#ifdef DD_DEBUG
- cuddCheckCollisionOrdering(unique,level,pos);
-#endif
-
- return(looking);
-
-} /* end of cuddUniqueInter */
-
-
-/**Function********************************************************************
-
- Synopsis [Wrapper for cuddUniqueInter that is independent of variable
- ordering.]
-
- Description [Wrapper for cuddUniqueInter that is independent of
- variable ordering (IVO). This function does not require parameter
- index to precede the indices of the top nodes of T and E in the
- variable order. Returns a pointer to the result node under normal
- conditions; NULL if reordering occurred or memory was exhausted.]
-
- SideEffects [None]
-
- SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover]
-
-******************************************************************************/
-DdNode *
-cuddUniqueInterIVO(
- DdManager * unique,
- int index,
- DdNode * T,
- DdNode * E)
-{
- DdNode *result;
- DdNode *v;
-
- v = cuddUniqueInter(unique, index, DD_ONE(unique),
- Cudd_Not(DD_ONE(unique)));
- if (v == NULL)
- return(NULL);
- cuddRef(v);
- result = cuddBddIteRecur(unique, v, T, E);
- Cudd_RecursiveDeref(unique, v);
- return(result);
-}
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the unique table for the existence of an internal
- ZDD node.]
-
- Description [Checks the unique table for the existence of an internal
- ZDD node. If it does not exist, it creates a new one. Does not
- modify the reference count of whatever is returned. A newly created
- internal node comes back with a reference count 0. For a newly
- created node, increments the reference counts of what T and E point
- to. Returns a pointer to the new node if successful; NULL if memory
- is exhausted or if reordering took place.]
-
- SideEffects [None]
-
- SeeAlso [cuddUniqueInter]
-
-******************************************************************************/
-DdNode *
-cuddUniqueInterZdd(
- DdManager * unique,
- int index,
- DdNode * T,
- DdNode * E)
-{
- int pos;
- unsigned int level;
- int retval;
- DdNodePtr *nodelist;
- DdNode *looking;
- DdSubtable *subtable;
-
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLookUps++;
-#endif
-
- if (index >= unique->sizeZ) {
- if (!cuddResizeTableZdd(unique,index)) return(NULL);
- }
-
- level = unique->permZ[index];
- subtable = &(unique->subtableZ[level]);
-
-#ifdef DD_DEBUG
- assert(level < (unsigned) cuddIZ(unique,T->index));
- assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index));
-#endif
-
- 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);
- }
- }
-
- pos = ddHash(T, E, subtable->shift);
- nodelist = subtable->nodelist;
- looking = nodelist[pos];
-
- while (looking != NULL) {
- if (cuddT(looking) == T && cuddE(looking) == E) {
- if (looking->ref == 0) {
- cuddReclaimZdd(unique,looking);
- }
- return(looking);
- }
- looking = looking->next;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
-
- /* countDead is 0 if deads should be counted and ~0 if they should not. */
- 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);
-#endif
- 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;
-#endif
- return(NULL);
- }
-
- unique->keysZ++;
- subtable->keys++;
-
- looking = cuddAllocNode(unique);
- if (looking == NULL) return(NULL);
- looking->ref = 0;
- looking->index = index;
- cuddT(looking) = T;
- cuddE(looking) = E;
- looking->next = nodelist[pos];
- nodelist[pos] = looking;
- cuddRef(T);
- cuddRef(E);
-
- return(looking);
-
-} /* end of cuddUniqueInterZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the unique table for the existence of a constant node.]
-
- Description [Checks the unique table for the existence of a constant node.
- If it does not exist, it creates a new one. Does not
- modify the reference count of whatever is returned. A newly created
- internal node comes back with a reference count 0. Returns a
- pointer to the new node.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode *
-cuddUniqueConst(
- DdManager * unique,
- CUDD_VALUE_TYPE value)
-{
- int pos;
- DdNodePtr *nodelist;
- DdNode *looking;
- hack split;
-
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLookUps++;
-#endif
-
- 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);
- }
- }
-
- cuddAdjust(value); /* for the case of crippled infinities */
-
- if (ddAbs(value) < unique->epsilon) {
- value = 0.0;
- }
- split.value = value;
-
- pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift);
- nodelist = unique->constants.nodelist;
- looking = nodelist[pos];
-
- /* Here we compare values both for equality and for difference less
- * than epsilon. The first comparison is required when values are
- * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for
- * every X.
- */
- while (looking != NULL) {
- if (looking->type.value == value ||
- ddEqualVal(looking->type.value,value,unique->epsilon)) {
- if (looking->ref == 0) {
- cuddReclaim(unique,looking);
- }
- return(looking);
- }
- looking = looking->next;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
-
- unique->keys++;
- unique->constants.keys++;
-
- looking = cuddAllocNode(unique);
- if (looking == NULL) return(NULL);
- looking->ref = 0;
- looking->index = CUDD_CONST_INDEX;
- looking->type.value = value;
- looking->next = nodelist[pos];
- nodelist[pos] = looking;
-
- return(looking);
-
-} /* end of cuddUniqueConst */
-
-
-/**Function********************************************************************
-
- Synopsis [Rehashes a unique subtable.]
-
- Description [Doubles the size of a unique subtable and rehashes its
- contents.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddRehash(
- DdManager * unique,
- int i)
-{
- unsigned int slots, oldslots;
- int shift, oldshift;
- int j, pos;
- DdNodePtr *nodelist, *oldnodelist;
- DdNode *node, *next;
- DdNode *sentinel = &(unique->sentinel);
- hack split;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- 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);
-#ifdef DD_VERBOSE
- (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);
-#ifdef DD_VERBOSE
- (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;
- }
-
- 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;
-
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- nodelist = 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) {
- 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;
-
- /* 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;
- }
- 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);
-#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 = 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;
- }
- 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;
- }
- }
- 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);
-#endif
- }
-
- /* Update global data */
-
- unique->memused += (slots - oldslots) * sizeof(DdNodePtr);
- unique->slots += (slots - oldslots);
- ddFixLimits(unique);
-
-} /* end of cuddRehash */
-
-
-/**Function********************************************************************
-
- Synopsis [Shrinks a subtable.]
-
- Description [Shrinks a subtable.]
-
- SideEffects [None]
-
- SeeAlso [cuddRehash]
-
-******************************************************************************/
-void
-cuddShrinkSubtable(
- DdManager *unique,
- int i)
-{
- int j;
- int shift, posn;
- DdNodePtr *nodelist, *oldnodelist;
- DdNode *node, *next;
- DdNode *sentinel = &(unique->sentinel);
- unsigned int slots, oldslots;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- oldnodelist = unique->subtables[i].nodelist;
- oldslots = unique->subtables[i].slots;
- slots = oldslots >> 1;
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- nodelist = ALLOC(DdNodePtr, slots);
- MMoutOfMemory = saveHandler;
- if (nodelist == NULL) {
- return;
- }
- unique->subtables[i].nodelist = nodelist;
- unique->subtables[i].slots = slots;
- unique->subtables[i].shift++;
- 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);
-#endif
-
- for (j = 0; (unsigned) j < slots; j++) {
- 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;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- while (T == cuddT(looking) && E < cuddE(looking)) {
- previousP = &(looking->next);
- looking = *previousP;
-#ifdef DD_UNIQUE_PROFILE
- unique->uniqueLinks++;
-#endif
- }
- node->next = *previousP;
- *previousP = node;
- node = next;
- }
- }
- FREE(oldnodelist);
-
- unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *);
- 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;
-
-} /* end of cuddShrinkSubtable */
-
-
-/**Function********************************************************************
-
- Synopsis [Inserts n new subtables in a unique table at level.]
-
- Description [Inserts n new subtables in a unique table at level.
- The number n should be positive, and level should be an existing level.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddDestroySubtables]
-
-******************************************************************************/
-int
-cuddInsertSubtables(
- DdManager * unique,
- int n,
- int level)
-{
- DdSubtable *newsubtables;
- DdNodePtr *newnodelist;
- DdNodePtr *newvars;
- DdNode *sentinel = &(unique->sentinel);
- int oldsize,newsize;
- int i,j,index,reorderSave;
- unsigned int numSlots = unique->initSlots;
- int *newperm, *newinvperm, *newmap;
- DdNode *one, *zero;
-
-#ifdef DD_DEBUG
- assert(n > 0 && level < unique->size);
-#endif
-
- 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 =
- ALLOC(DdNodePtr, numSlots);
- if (newnodelist == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (j = 0; 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;
-#ifdef DD_VERBOSE
- (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 = ALLOC(DdSubtable,newsize);
- if (newsubtables == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newvars = ALLOC(DdNodePtr,newsize);
- if (newvars == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- FREE(newsubtables);
- return(0);
- }
- newperm = ALLOC(int,newsize);
- if (newperm == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- FREE(newsubtables);
- FREE(newvars);
- return(0);
- }
- newinvperm = ALLOC(int,newsize);
- if (newinvperm == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- FREE(newsubtables);
- FREE(newvars);
- FREE(newperm);
- return(0);
- }
- if (unique->map != NULL) {
- newmap = ALLOC(int,newsize);
- if (newmap == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- FREE(newsubtables);
- FREE(newvars);
- FREE(newperm);
- 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 = 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; 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;
- }
- FREE(unique->map);
- unique->map = newmap;
- }
- /* Install the new tables and free the old ones. */
- FREE(unique->subtables);
- unique->subtables = newsubtables;
- unique->maxSize = newsize;
- FREE(unique->vars);
- unique->vars = newvars;
- FREE(unique->perm);
- unique->perm = newperm;
- FREE(unique->invperm);
- unique->invperm = newinvperm;
- /* Update the stack for iterative procedures. */
- if (newsize > unique->maxSizeZ) {
- FREE(unique->stack);
- unique->stack = 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 *);
- }
- }
- /* Update manager parameters to account for the new subtables. */
- unique->slots += n * numSlots;
- ddFixLimits(unique);
- unique->size += n;
-
- /* Now that the table is in a coherent state, create the new
- ** projection functions. We need to temporarily disable reordering,
- ** because we cannot reorder without projection functions in place.
- **/
- one = unique->one;
- zero = Cudd_Not(one);
-
- 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;
- 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->autoDyn = reorderSave;
-
- return(1);
-
-} /* end of cuddInsertSubtables */
-
-
-/**Function********************************************************************
-
- Synopsis [Destroys the n most recently created subtables in a unique table.]
-
- Description [Destroys the n most recently created subtables in a unique
- table. n should be positive. The subtables should not contain any live
- nodes, except the (isolated) projection function. The projection
- functions are freed. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [The variable map used for fast variable substitution is
- destroyed if it exists. In this case the cache is also cleared.]
-
- SeeAlso [cuddInsertSubtables Cudd_SetVarMap]
-
-******************************************************************************/
-int
-cuddDestroySubtables(
- DdManager * unique,
- int n)
-{
- DdSubtable *subtables;
- DdNodePtr *nodelist;
- DdNodePtr *vars;
- int firstIndex, lastIndex;
- int index, level, newlevel;
- int lowestLevel;
- int shift;
- int found;
-
- /* Sanity check and set up. */
- if (n <= 0) return(0);
- if (n > unique->size) n = unique->size;
-
- subtables = unique->subtables;
- vars = unique->vars;
- firstIndex = unique->size - n;
- lastIndex = unique->size;
-
- /* Check for nodes labeled by the variables being destroyed
- ** that may still be in use. It is allowed to destroy a variable
- ** only if there are no such nodes. Also, find the lowest level
- ** among the variables being destroyed. This will make further
- ** processing more efficient.
- */
- 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;
- }
- }
- Cudd_RecursiveDeref(unique,vars[index]);
- }
-
- /* Collect garbage, because we cannot afford having dead nodes pointing
- ** to the dead nodes in the subtables being destroyed.
- */
- (void) cuddGarbageCollect(unique,1);
-
- /* Here we know we can destroy our subtables. */
- for (index = firstIndex; index < lastIndex; index++) {
- level = unique->perm[index];
- nodelist = subtables[level].nodelist;
-#ifdef DD_DEBUG
- assert(subtables[level].keys == 0);
-#endif
- 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
- ** their hash tables have been freed.
- ** We now scan the subtables from level lowestLevel + 1 to level size - 1,
- ** shifting the subtables as required. We keep a running count of
- ** how many subtables have been moved, so that we know by how many
- ** positions each subtable should be shifted.
- */
- 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;
- }
- /* 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);
- FREE(unique->map);
- unique->map = NULL;
- }
-
- unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
- unique->size -= n;
-
- return(1);
-
-} /* end of cuddDestroySubtables */
-
-
-/**Function********************************************************************
-
- Synopsis [Increases the number of ZDD subtables in a unique table so
- that it meets or exceeds index.]
-
- Description [Increases the number of ZDD subtables in a unique table so
- that it meets or exceeds index. When new ZDD variables are created, it
- is possible to preserve the functions unchanged, or it is possible to
- preserve the covers unchanged, but not both. cuddResizeTableZdd preserves
- the covers. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [ddResizeTable]
-
-******************************************************************************/
-int
-cuddResizeTableZdd(
- DdManager * unique,
- int index)
-{
- DdSubtable *newsubtables;
- DdNodePtr *newnodelist;
- int oldsize,newsize;
- 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 =
- ALLOC(DdNodePtr, numSlots);
- if (newnodelist == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (j = 0; 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;
-#ifdef DD_VERBOSE
- (void) fprintf(unique->err,
- "Increasing the ZDD table size from %d to %d\n",
- unique->maxSizeZ, newsize);
-#endif
- newsubtables = ALLOC(DdSubtable,newsize);
- if (newsubtables == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newperm = ALLOC(int,newsize);
- if (newperm == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newinvperm = 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) {
- FREE(unique->stack);
- unique->stack = 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 = ALLOC(DdNodePtr, numSlots);
- if (newnodelist == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (j = 0; j < numSlots; j++) {
- newnodelist[j] = NULL;
- }
- }
- FREE(unique->subtableZ);
- unique->subtableZ = newsubtables;
- unique->maxSizeZ = newsize;
- FREE(unique->permZ);
- unique->permZ = newperm;
- FREE(unique->invpermZ);
- unique->invpermZ = newinvperm;
- }
- unique->slots += (index + 1 - unique->sizeZ) * numSlots;
- ddFixLimits(unique);
- unique->sizeZ = index + 1;
-
- /* Now that the table is in a coherent state, update the ZDD
- ** 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(1);
-
-} /* end of cuddResizeTableZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Adjusts parameters of a table to slow down its growth.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-cuddSlowTableGrowth(
- DdManager *unique)
-{
- int i;
-
- unique->maxCacheHard = unique->cacheSlots - 1;
- unique->cacheSlack = -(unique->cacheSlots + 1);
- for (i = 0; i < unique->size; i++) {
- 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);
-
-} /* end of cuddSlowTableGrowth */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Rehashes a ZDD unique subtable.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddRehash]
-
-******************************************************************************/
-static void
-ddRehashZdd(
- DdManager * unique,
- int i)
-{
- unsigned int slots, oldslots;
- int shift, oldshift;
- int j, pos;
- DdNodePtr *nodelist, *oldnodelist;
- DdNode *node, *next;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
- if (unique->slots > unique->looseUpTo) {
- 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);
- }
-#endif
- unique->gcFrac = DD_GC_FRAC_LO;
- }
-
- assert(i != CUDD_MAXINDEX);
- oldslots = unique->subtableZ[i].slots;
- oldshift = unique->subtableZ[i].shift;
- oldnodelist = unique->subtableZ[i].nodelist;
-
- /* Compute the new size of the subtable. Normally, we just
- ** double. However, after reordering, a table may be severely
- ** overloaded. Therefore, we iterate. */
- slots = oldslots;
- shift = oldshift;
- do {
- slots <<= 1;
- shift--;
- } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys);
-
- saveHandler = MMoutOfMemory;
- MMoutOfMemory = Cudd_OutOfMem;
- nodelist = 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;
- }
- 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;
- }
- 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;
- }
- }
- 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);
-#endif
-
- /* Update global data. */
- unique->memused += (slots - oldslots) * sizeof(DdNode *);
- unique->slots += (slots - oldslots);
- ddFixLimits(unique);
-
-} /* end of ddRehashZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Increases the number of subtables in a unique table so
- that it meets or exceeds index.]
-
- Description [Increases the number of subtables in a unique table so
- that it meets or exceeds index. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddResizeTableZdd]
-
-******************************************************************************/
-static int
-ddResizeTable(
- DdManager * unique,
- int index)
-{
- DdSubtable *newsubtables;
- DdNodePtr *newnodelist;
- DdNodePtr *newvars;
- DdNode *sentinel = &(unique->sentinel);
- int oldsize,newsize;
- int i,j,reorderSave;
- int numSlots = unique->initSlots;
- 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 =
- ALLOC(DdNodePtr, numSlots);
- if (newnodelist == NULL) {
- for (j = oldsize; j < i; j++) {
- 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;
-#ifdef DD_VERBOSE
- (void) fprintf(unique->err,
- "Increasing the table size from %d to %d\n",
- unique->maxSize, newsize);
-#endif
- newsubtables = ALLOC(DdSubtable,newsize);
- if (newsubtables == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newvars = ALLOC(DdNodePtr,newsize);
- if (newvars == NULL) {
- FREE(newsubtables);
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newperm = ALLOC(int,newsize);
- if (newperm == NULL) {
- FREE(newsubtables);
- FREE(newvars);
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- newinvperm = ALLOC(int,newsize);
- if (newinvperm == NULL) {
- FREE(newsubtables);
- FREE(newvars);
- FREE(newperm);
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- if (unique->map != NULL) {
- newmap = ALLOC(int,newsize);
- if (newmap == NULL) {
- FREE(newsubtables);
- FREE(newvars);
- FREE(newperm);
- 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) {
- FREE(unique->stack);
- unique->stack = ALLOC(DdNodePtr,newsize + 1);
- if (unique->stack == NULL) {
- FREE(newsubtables);
- FREE(newvars);
- FREE(newperm);
- FREE(newinvperm);
- if (unique->map != NULL) {
- 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 *);
- }
- 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 = ALLOC(DdNodePtr, numSlots);
- if (newnodelist == NULL) {
- unique->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (j = 0; j < numSlots; j++) {
- newnodelist[j] = sentinel;
- }
- }
- if (unique->map != NULL) {
- for (i = 0; i < oldsize; i++) {
- newmap[i] = unique->map[i];
- }
- for (i = oldsize; i <= index; i++) {
- newmap[i] = i;
- }
- FREE(unique->map);
- unique->map = newmap;
- }
- FREE(unique->subtables);
- unique->subtables = newsubtables;
- unique->maxSize = newsize;
- FREE(unique->vars);
- unique->vars = newvars;
- FREE(unique->perm);
- unique->perm = newperm;
- FREE(unique->invperm);
- unique->invperm = newinvperm;
- }
-
- /* Now that the table is in a coherent state, create the new
- ** projection functions. We need to temporarily disable reordering,
- ** because we cannot reorder without projection functions in place.
- **/
- one = unique->one;
- zero = Cudd_Not(one);
-
- unique->size = index + 1;
- unique->slots += (index + 1 - oldsize) * numSlots;
- ddFixLimits(unique);
-
- 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++) {
- 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;
-
- return(1);
-
-} /* end of ddResizeTable */
-
-
-/**Function********************************************************************
-
- Synopsis [Searches the subtables above node for a parent.]
-
- Description [Searches the subtables above node for a parent. Returns 1
- as soon as one parent is found. Returns 0 is the search is fruitless.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddFindParent(
- DdManager * table,
- DdNode * node)
-{
- int i,j;
- 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;
-
- 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);
-
-} /* end of cuddFindParent */
-
-
-/**Function********************************************************************
-
- Synopsis [Adjusts the values of table limits.]
-
- Description [Adjusts the values of table fields controlling the.
- sizes of subtables and computed table. If the computed table is too small
- according to the new values, it is resized.]
-
- SideEffects [Modifies manager fields. May resize computed table.]
-
- SeeAlso []
-
-******************************************************************************/
-DD_INLINE
-static void
-ddFixLimits(
- DdManager *unique)
-{
- 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;
- if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0)
- cuddCacheResize(unique);
- return;
-
-} /* end of ddFixLimits */
-
-
-#ifndef DD_UNSORTED_FREE_LIST
-/**Function********************************************************************
-
- Synopsis [Inserts a DdNode in a red/black search tree.]
-
- Description [Inserts a DdNode in a red/black search tree. Nodes from
- the same "page" (defined by DD_PAGE_MASK) are linked in a LIFO list.]
-
- SideEffects [None]
-
- SeeAlso [cuddOrderedThread]
-
-******************************************************************************/
-static void
-cuddOrderedInsert(
- DdNodePtr * root,
- DdNodePtr node)
-{
- DdNode *scan;
- DdNodePtr *scanP;
- DdNodePtr *stack[DD_STACK_SIZE];
- int stackN = 0;
-
- 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);
- }
- DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL;
- DD_COLOR(node) = DD_RED;
- *scanP = node;
- stack[stackN] = &node;
- cuddDoRebalance(stack,stackN);
-
-} /* end of cuddOrderedInsert */
-
-
-/**Function********************************************************************
-
- Synopsis [Threads all the nodes of a search tree into a linear list.]
-
- Description [Threads all the nodes of a search tree into a linear
- list. For each node of the search tree, the "left" child, if non-null, has
- a lower address than its parent, and the "right" child, if non-null, has a
- higher address than its parent.
- The list is sorted in order of increasing addresses. The search
- tree is destroyed as a result of this operation. The last element of
- the linear list is made to point to the address passed in list. Each
- node if the search tree is a linearly-linked list of nodes from the
- same memory page (as defined in DD_PAGE_MASK). When a node is added to
- the linear list, all the elements of the linked list are added.]
-
- SideEffects [The search tree is destroyed as a result of this operation.]
-
- SeeAlso [cuddOrderedInsert]
-
-******************************************************************************/
-static DdNode *
-cuddOrderedThread(
- DdNode * root,
- DdNode * list)
-{
- DdNode *current, *next, *prev, *end;
-
- current = root;
- /* The first word in the node is used to implement a stack that holds
- ** the nodes from the root of the tree to the current node. Here we
- ** put the root of the tree at the bottom of the stack.
- */
- *((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;
- } else {
- current = prev;
- }
- }
- }
-
- return(list);
-
-} /* end of cuddOrderedThread */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the left rotation for red/black trees.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddRotateRight]
-
-******************************************************************************/
-DD_INLINE
-static void
-cuddRotateLeft(
- DdNodePtr * nodeP)
-{
- DdNode *newRoot;
- DdNode *oldRoot = *nodeP;
-
- *nodeP = newRoot = DD_RIGHT(oldRoot);
- DD_RIGHT(oldRoot) = DD_LEFT(newRoot);
- DD_LEFT(newRoot) = oldRoot;
-
-} /* end of cuddRotateLeft */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the right rotation for red/black trees.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddRotateLeft]
-
-******************************************************************************/
-DD_INLINE
-static void
-cuddRotateRight(
- DdNodePtr * nodeP)
-{
- DdNode *newRoot;
- DdNode *oldRoot = *nodeP;
-
- *nodeP = newRoot = DD_LEFT(oldRoot);
- DD_LEFT(oldRoot) = DD_RIGHT(newRoot);
- DD_RIGHT(newRoot) = oldRoot;
-
-} /* end of cuddRotateRight */
-
-
-/**Function********************************************************************
-
- Synopsis [Rebalances a red/black tree.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-cuddDoRebalance(
- DdNodePtr ** stack,
- int stackN)
-{
- DdNodePtr *xP, *parentP, *grandpaP;
- DdNode *x, *y, *parent, *grandpa;
-
- xP = stack[stackN];
- 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;
- } else {
- DD_COLOR(parent) = DD_BLACK;
- }
- DD_COLOR(grandpa) = DD_RED;
- cuddRotateLeft(grandpaP);
- }
- }
- }
- DD_COLOR(*(stack[0])) = DD_BLACK;
-
-} /* end of cuddDoRebalance */
-#endif
-
-
-/**Function********************************************************************
-
- Synopsis [Fixes a variable tree after the insertion of new subtables.]
-
- Description [Fixes a variable tree after the insertion of new subtables.
- After such an insertion, the low fields of the tree below the insertion
- point are inconsistent.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-ddPatchTree(
- DdManager *dd,
- MtrNode *treenode)
-{
- MtrNode *auxnode = treenode;
-
- while (auxnode != NULL) {
- auxnode->low = dd->perm[auxnode->index];
- if (auxnode->child != NULL) {
- ddPatchTree(dd, auxnode->child);
- }
- auxnode = auxnode->younger;
- }
-
- return;
-
-} /* end of ddPatchTree */
-
-
-#ifdef DD_DEBUG
-/**Function********************************************************************
-
- Synopsis [Checks whether a collision list is ordered.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddCheckCollisionOrdering(
- DdManager *unique,
- int i,
- int j)
-{
- int slots;
- DdNode *node, *next;
- DdNodePtr *nodelist;
- DdNode *sentinel = &(unique->sentinel);
-
- nodelist = unique->subtables[i].nodelist;
- slots = unique->subtables[i].slots;
- node = nodelist[j];
- 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;
- }
- return(1);
-
-} /* end of cuddCheckCollisionOrdering */
-#endif
-
-
-
-
-/**Function********************************************************************
-
- Synopsis [Reports problem in garbage collection.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [cuddGarbageCollect cuddGarbageCollectZdd]
-
-******************************************************************************/
-static void
-ddReportRefMess(
- DdManager *unique /* manager */,
- int i /* table in which the problem occurred */,
- char *caller /* procedure that detected the problem */)
-{
- if (i == CUDD_CONST_INDEX) {
- (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, " dead count != deleted\n");
- (void) fprintf(unique->err, " This problem is often due to a missing \
-call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \
-See the CUDD Programmer's Guide for additional details.");
- abort();
-
-} /* end of ddReportRefMess */
diff --git a/src/bdd/cudd/cuddUtil.c b/src/bdd/cudd/cuddUtil.c
deleted file mode 100644
index d5fa18e2..00000000
--- a/src/bdd/cudd/cuddUtil.c
+++ /dev/null
@@ -1,3633 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddUtil.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Random generator constants. */
-#define MODULUS1 2147483563
-#define LEQA1 40014
-#define LEQQ1 53668
-#define LEQR1 12211
-#define MODULUS2 2147483399
-#define LEQA2 40692
-#define LEQQ2 52774
-#define LEQR2 3791
-#define STAB_SIZE 64
-#define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE)
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static DdNode *background, *zero;
-
-static long cuddRand = 0;
-static long cuddRand2;
-static long shuffleSelect;
-static long shuffleTable[STAB_SIZE];
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ')
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a disjoint sum of products.]
-
- Description [Prints a disjoint sum of product cover for the function
- rooted at node. Each product corresponds to a path from node to a
- leaf node different from the logical zero, and different from the
- background value. Uses the package default output file. Returns 1
- if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover]
-
-******************************************************************************/
-int
-Cudd_PrintMinterm(
- DdManager * manager,
- DdNode * node)
-{
- int i, *list;
-
- background = manager->background;
- zero = Cudd_Not(manager->one);
- list = ALLOC(int,manager->size);
- if (list == NULL) {
- manager->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (i = 0; i < manager->size; i++) list[i] = 2;
- ddPrintMintermAux(manager,node,list);
- FREE(list);
- return(1);
-
-} /* end of Cudd_PrintMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a sum of prime implicants of a BDD.]
-
- Description [Prints a sum of product cover for an incompletely
- specified function given by a lower bound and an upper bound. Each
- product is a prime implicant obtained by expanding the product
- corresponding to a path from node to the constant one. Uses the
- package default output file. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintMinterm]
-
-******************************************************************************/
-int
-Cudd_bddPrintCover(
- DdManager *dd,
- DdNode *l,
- DdNode *u)
-{
- int *array;
- int q, result;
- DdNode *lb;
-#ifdef DD_DEBUG
- DdNode *cover;
-#endif
-
- array = ALLOC(int, Cudd_ReadSize(dd));
- if (array == NULL) return(0);
- lb = l;
- cuddRef(lb);
-#ifdef DD_DEBUG
- cover = Cudd_ReadLogicZero(dd);
- 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);
- FREE(array);
- return(0);
- }
- cuddRef(implicant);
- prime = Cudd_bddMakePrime(dd,implicant,u);
- if (prime == NULL) {
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,implicant);
- 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);
- FREE(array);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,lb);
- lb = tmp;
- result = Cudd_BddToCubeArray(dd,prime,array);
- if (result == 0) {
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,prime);
- 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, "?");
- }
- }
- (void) fprintf(dd->out, " 1\n");
-#ifdef DD_DEBUG
- tmp = Cudd_bddOr(dd,prime,cover);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,cover);
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,prime);
- FREE(array);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cover);
- cover = tmp;
-#endif
- Cudd_RecursiveDeref(dd,prime);
- }
- (void) fprintf(dd->out, "\n");
- Cudd_RecursiveDeref(dd,lb);
- FREE(array);
-#ifdef DD_DEBUG
- if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) {
- Cudd_RecursiveDeref(dd,cover);
- return(0);
- }
- Cudd_RecursiveDeref(dd,cover);
-#endif
- return(1);
-
-} /* end of Cudd_bddPrintCover */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints to the standard output a DD and its statistics.]
-
- Description [Prints to the standard output a DD and its statistics.
- The statistics include the number of nodes, the number of leaves, and
- the number of minterms. (The number of minterms is the number of
- assignments to the variables that cause the function to be different
- from the logical zero (for BDDs) and from the background value (for
- ADDs.) The statistics are printed if pr &gt; 0. Specifically:
- <ul>
- <li> pr = 0 : prints nothing
- <li> pr = 1 : prints counts of nodes and minterms
- <li> pr = 2 : prints counts + disjoint sum of product
- <li> pr = 3 : prints counts + list of nodes
- <li> pr &gt; 3 : prints counts + disjoint sum of product + list of nodes
- </ul>
- For the purpose of counting the number of minterms, the function is
- supposed to depend on n variables. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm
- Cudd_PrintMinterm]
-
-******************************************************************************/
-int
-Cudd_PrintDebug(
- DdManager * dd,
- DdNode * f,
- int n,
- int pr)
-{
- DdNode *azero, *bzero;
- 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);
- }
- azero = DD_ZERO(dd);
- bzero = Cudd_Not(DD_ONE(dd));
- if ((f == azero || f == bzero) && pr > 0){
- (void) fprintf(dd->out,": is the zero DD\n");
- (void) fflush(dd->out);
- 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);
- 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");
- }
- (void) fflush(dd->out);
- }
- return(retval);
-
-} /* end of Cudd_PrintDebug */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of nodes in a DD.]
-
- Description [Counts the number of nodes in a DD. Returns the number
- of nodes in the graph rooted at node.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SharingSize Cudd_PrintDebug]
-
-******************************************************************************/
-int
-Cudd_DagSize(
- DdNode * node)
-{
- int i;
-
- i = ddDagInt(Cudd_Regular(node));
- ddClearFlag(Cudd_Regular(node));
-
- return(i);
-
-} /* end of Cudd_DagSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Estimates the number of nodes in a cofactor of a DD.]
-
- Description [Estimates the number of nodes in a cofactor of a DD.
- Returns an estimate of the number of nodes in a cofactor of
- the graph rooted at node with respect to the variable whose index is i.
- In case of failure, returns CUDD_OUT_OF_MEM.
- This function uses a refinement of the algorithm of Cabodi et al.
- (ICCAD96). The refinement allows the procedure to account for part
- of the recombination that may occur in the part of the cofactor above
- the cofactoring variable. This procedure does no create any new node.
- It does keep a small table of results; therefore itmay run out of memory.
- If this is a concern, one should use Cudd_EstimateCofactorSimple, which
- is faster, does not allocate any memory, but is less accurate.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple]
-
-******************************************************************************/
-int
-Cudd_EstimateCofactor(
- DdManager *dd /* manager */,
- DdNode * f /* function */,
- int i /* index of variable */,
- int phase /* 1: positive; 0: negative */
- )
-{
- int val;
- DdNode *ptr;
- st_table *table;
-
- 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));
- st_free_table(table);
-
- return(val);
-
-} /* end of Cudd_EstimateCofactor */
-
-
-/**Function********************************************************************
-
- Synopsis [Estimates the number of nodes in a cofactor of a DD.]
-
- Description [Estimates the number of nodes in a cofactor of a DD.
- Returns an estimate of the number of nodes in the positive cofactor of
- the graph rooted at node with respect to the variable whose index is i.
- This procedure implements with minor changes the algorithm of Cabodi et al.
- (ICCAD96). It does not allocate any memory, it does not change the
- state of the manager, and it is fast. However, it has been observed to
- overestimate the size of the cofactor by as much as a factor of 2.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DagSize]
-
-******************************************************************************/
-int
-Cudd_EstimateCofactorSimple(
- DdNode * node,
- int i)
-{
- int val;
-
- val = cuddEstimateCofactorSimple(Cudd_Regular(node),i);
- ddClearFlag(Cudd_Regular(node));
-
- return(val);
-
-} /* end of Cudd_EstimateCofactorSimple */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of nodes in an array of DDs.]
-
- Description [Counts the number of nodes in an array of DDs. Shared
- nodes are counted only once. Returns the total number of nodes.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DagSize]
-
-******************************************************************************/
-int
-Cudd_SharingSize(
- DdNode ** nodeArray,
- int n)
-{
- int i,j;
-
- i = 0;
- for (j = 0; j < n; j++) {
- i += ddDagInt(Cudd_Regular(nodeArray[j]));
- }
- for (j = 0; j < n; j++) {
- ddClearFlag(Cudd_Regular(nodeArray[j]));
- }
- return(i);
-
-} /* end of Cudd_SharingSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms of a DD.]
-
- Description [Counts the number of minterms of a DD. The function is
- assumed to depend on nvars variables. The minterm count is
- represented as a double, to allow for a larger number of variables.
- Returns the number of minterms of the function rooted at node if
- successful; (double) CUDD_OUT_OF_MEM otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintDebug Cudd_CountPath]
-
-******************************************************************************/
-double
-Cudd_CountMinterm(
- DdManager * manager,
- DdNode * node,
- int nvars)
-{
- 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);
- }
- epsilon = Cudd_ReadEpsilon(manager);
- Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0);
- res = ddCountMintermAux(node,max,table);
- cuddHashTableQuit(table);
- Cudd_SetEpsilon(manager,epsilon);
-
- return(res);
-
-} /* end of Cudd_CountMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of paths of a DD.]
-
- Description [Counts the number of paths of a DD. Paths to all
- terminal nodes are counted. The path count is represented as a
- double, to allow for a larger number of variables. Returns the
- number of paths of the function rooted at node if successful;
- (double) CUDD_OUT_OF_MEM otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CountMinterm]
-
-******************************************************************************/
-double
-Cudd_CountPath(
- DdNode * node)
-{
-
- st_table *table;
- double i;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- i = ddCountPathAux(Cudd_Regular(node),table);
- st_foreach(table, cuddStCountfree, NULL);
- st_free_table(table);
- return(i);
-
-} /* end of Cudd_CountPath */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms of a DD with extended precision.]
-
- Description [Counts the number of minterms of a DD with extended precision.
- The function is assumed to depend on nvars variables. The minterm count is
- represented as an EpDouble, to allow any number of variables.
- Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintDebug Cudd_CountPath]
-
-******************************************************************************/
-int
-Cudd_EpdCountMinterm(
- DdManager * manager,
- DdNode * node,
- int nvars,
- EpDouble * epd)
-{
- EpDouble max, tmp;
- st_table *table;
- 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);
- }
- status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table);
- st_foreach(table, ddEpdFree, NULL);
- st_free_table(table);
- if (status == CUDD_OUT_OF_MEM) {
- EpdMakeZero(epd, 0);
- return(CUDD_OUT_OF_MEM);
- }
- if (Cudd_IsComplement(node)) {
- EpdSubtract3(&max, epd, &tmp);
- EpdCopy(&tmp, epd);
- }
- return(0);
-
-} /* end of Cudd_EpdCountMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of paths to a non-zero terminal of a DD.]
-
- Description [Counts the number of paths to a non-zero terminal of a
- DD. The path count is
- represented as a double, to allow for a larger number of variables.
- Returns the number of paths of the function rooted at node.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CountMinterm Cudd_CountPath]
-
-******************************************************************************/
-double
-Cudd_CountPathsToNonZero(
- DdNode * node)
-{
-
- st_table *table;
- double i;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- i = ddCountPathsToNonZero(node,table);
- st_foreach(table, cuddStCountfree, NULL);
- st_free_table(table);
- return(i);
-
-} /* end of Cudd_CountPathsToNonZero */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a DD depends.]
-
- Description [Finds the variables on which a DD depends.
- Returns a BDD consisting of the product of the variables if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-DdNode *
-Cudd_Support(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support is sought */)
-{
- int *support;
- DdNode *res, *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- /* 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;
- }
- }
- } while (dd->reordered == 1);
-
- FREE(support);
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_Support */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a DD depends.]
-
- Description [Finds the variables on which a DD depends.
- Returns an index array of the variables if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-int *
-Cudd_SupportIndex(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support is sought */)
-{
- int *support;
- int i;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- return(support);
-
-} /* end of Cudd_SupportIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the variables on which a DD depends.]
-
- Description [Counts the variables on which a DD depends.
- Returns the number of the variables if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support]
-
-******************************************************************************/
-int
-Cudd_SupportSize(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support size is sought */)
-{
- int *support;
- int i;
- int size;
- int count;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- /* Count support variables. */
- count = 0;
- for (i = 0; i < size; i++) {
- if (support[i] == 1) count++;
- }
-
- FREE(support);
- return(count);
-
-} /* end of Cudd_SupportSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a set of DDs depends.]
-
- Description [Finds the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns a BDD consisting of the product of the variables if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support Cudd_ClassifySupport]
-
-******************************************************************************/
-DdNode *
-Cudd_VectorSupport(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- DdNode *res, *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; 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);
- FREE(support);
- return(NULL);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,res);
- Cudd_RecursiveDeref(dd,var);
- res = tmp;
- }
- }
-
- FREE(support);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_VectorSupport */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a set of DDs depends.]
-
- Description [Finds the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns an index array of the variables if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-int *
-Cudd_VectorSupportIndex(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- int i;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; i++) {
- ddClearFlag(Cudd_Regular(F[i]));
- }
-
- return(support);
-
-} /* end of Cudd_VectorSupportIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the variables on which a set of DDs depends.]
-
- Description [Counts the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns the number of the variables if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_VectorSupport Cudd_SupportSize]
-
-******************************************************************************/
-int
-Cudd_VectorSupportSize(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- int i;
- int size;
- int count;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; i++) {
- ddClearFlag(Cudd_Regular(F[i]));
- }
-
- /* Count vriables in support. */
- count = 0;
- for (i = 0; i < size; i++) {
- if (support[i] == 1) count++;
- }
-
- FREE(support);
- return(count);
-
-} /* end of Cudd_VectorSupportSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Classifies the variables in the support of two DDs.]
-
- Description [Classifies the variables in the support of two DDs
- <code>f</code> and <code>g</code>, depending on whther they appear
- in both DDs, only in <code>f</code>, or only in <code>g</code>.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [The cubes of the three classes of variables are
- returned as side effects.]
-
- SeeAlso [Cudd_Support Cudd_VectorSupport]
-
-******************************************************************************/
-int
-Cudd_ClassifySupport(
- DdManager * dd /* manager */,
- DdNode * f /* first DD */,
- DdNode * g /* second DD */,
- DdNode ** common /* cube of shared variables */,
- DdNode ** onlyF /* cube of variables only in f */,
- DdNode ** onlyG /* cube of variables only in g */)
-{
- int *supportF, *supportG;
- DdNode *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support arrays for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- supportF = ALLOC(int,size);
- if (supportF == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- supportG = ALLOC(int,size);
- if (supportG == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(supportF);
- return(0);
- }
- for (i = 0; i < size; i++) {
- supportF[i] = 0;
- supportG[i] = 0;
- }
-
- /* Compute supports and clean up markers. */
- ddSupportStep(Cudd_Regular(f),supportF);
- ddClearFlag(Cudd_Regular(f));
- ddSupportStep(Cudd_Regular(g),supportG);
- ddClearFlag(Cudd_Regular(g));
-
- /* Classify variables and create cubes. */
- *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);
- FREE(supportF); 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);
- FREE(supportF); 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);
- FREE(supportF); FREE(supportG);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,*common);
- *common = tmp;
- }
- Cudd_RecursiveDeref(dd,var);
- }
-
- FREE(supportF); FREE(supportG);
- cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG);
- return(1);
-
-} /* end of Cudd_ClassifySupport */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of leaves in a DD.]
-
- Description [Counts the number of leaves in a DD. Returns the number
- of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintDebug]
-
-******************************************************************************/
-int
-Cudd_CountLeaves(
- DdNode * node)
-{
- int i;
-
- i = ddLeavesInt(Cudd_Regular(node));
- ddClearFlag(Cudd_Regular(node));
- return(i);
-
-} /* end of Cudd_CountLeaves */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks one on-set cube randomly from the given DD.]
-
- Description [Picks one on-set cube randomly from the given DD. The
- cube is written into an array of characters. The array must have at
- least as many entries as there are variables. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPickOneMinterm]
-
-******************************************************************************/
-int
-Cudd_bddPickOneCube(
- DdManager * ddm,
- DdNode * node,
- char * string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
- char dir;
- int i;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(ddm);
- bzero = Cudd_Not(one);
- if (node == bzero) return(0);
-
- for (i = 0; i < ddm->size; i++) string[i] = 2;
-
- for (;;) {
-
- if (node == one) break;
-
- 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;
- }
- }
- return(1);
-
-} /* end of Cudd_bddPickOneCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks one on-set minterm randomly from the given DD.]
-
- Description [Picks one on-set minterm randomly from the given
- DD. The minterm is in terms of <code>vars</code>. The array
- <code>vars</code> should contain at least all variables in the
- support of <code>f</code>; if this condition is not met the minterm
- built by this procedure may not be contained in
- <code>f</code>. Builds a BDD for the minterm and returns a pointer
- to it if successful; NULL otherwise. There are three reasons why the
- procedure may fail:
- <ul>
- <li> It may run out of memory;
- <li> the function <code>f</code> may be the constant 0;
- <li> the minterm may not be contained in <code>f</code>.
- </ul>]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPickOneCube]
-
-******************************************************************************/
-DdNode *
-Cudd_bddPickOneMinterm(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick one minterm */,
- DdNode ** vars /* array of variables */,
- int n /* size of <code>vars</code> */)
-{
- char *string;
- int i, size;
- int *indices;
- int result;
- DdNode *old, *neW;
-
- size = dd->size;
- string = ALLOC(char, size);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- indices = ALLOC(int,n);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- return(NULL);
- }
-
- for (i = 0; i < n; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = Cudd_bddPickOneCube(dd,f,string);
- if (result == 0) {
- FREE(string);
- 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);
- }
-
- /* Build result BDD. */
- old = Cudd_ReadOne(dd);
- 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) {
- FREE(string);
- FREE(indices);
- Cudd_RecursiveDeref(dd,old);
- return(NULL);
- }
- cuddRef(neW);
- Cudd_RecursiveDeref(dd,old);
- old = neW;
- }
-
-#ifdef DD_DEBUG
- /* Test. */
- if (Cudd_bddLeq(dd,old,f)) {
- cuddDeref(old);
- } else {
- Cudd_RecursiveDeref(dd,old);
- old = NULL;
- }
-#else
- cuddDeref(old);
-#endif
-
- FREE(string);
- FREE(indices);
- return(old);
-
-} /* end of Cudd_bddPickOneMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks k on-set minterms evenly distributed from given DD.]
-
- Description [Picks k on-set minterms evenly distributed from given DD.
- The minterms are in terms of <code>vars</code>. The array
- <code>vars</code> should contain at least all variables in the
- support of <code>f</code>; if this condition is not met the minterms
- built by this procedure may not be contained in
- <code>f</code>. Builds an array of BDDs for the minterms and returns a
- pointer to it if successful; NULL otherwise. There are three reasons
- why the procedure may fail:
- <ul>
- <li> It may run out of memory;
- <li> the function <code>f</code> may be the constant 0;
- <li> the minterms may not be contained in <code>f</code>.
- </ul>]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube]
-
-******************************************************************************/
-DdNode **
-Cudd_bddPickArbitraryMinterms(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick k minterms */,
- DdNode ** vars /* array of variables */,
- int n /* size of <code>vars</code> */,
- int k /* number of minterms to find */)
-{
- char **string;
- int i, j, l, size;
- int *indices;
- int result;
- DdNode **old, *neW;
- double minterms;
- char *saveString;
- int saveFlag, savePoint, isSame;
-
- minterms = Cudd_CountMinterm(dd,f,n);
- if ((double)k > minterms) {
- return(NULL);
- }
-
- size = dd->size;
- string = ALLOC(char *, k);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < k; i++) {
- string[i] = ALLOC(char, size + 1);
- if (string[i] == NULL) {
- for (j = 0; j < i; j++)
- FREE(string[i]);
- FREE(string);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (j = 0; j < size; j++) string[i][j] = '2';
- string[i][size] = '\0';
- }
- indices = ALLOC(int,n);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- return(NULL);
- }
-
- for (i = 0; i < n; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = ddPickArbitraryMinterms(dd,f,n,k,string);
- if (result == 0) {
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- return(NULL);
- }
-
- old = ALLOC(DdNode *, k);
- if (old == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- return(NULL);
- }
- saveString = ALLOC(char, size + 1);
- if (saveString == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- 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;
- } 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';
- }
- }
- }
-
- 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) {
- FREE(saveString);
- for (l = 0; l < k; l++)
- FREE(string[l]);
- FREE(string);
- FREE(indices);
- for (l = 0; l <= i; l++)
- Cudd_RecursiveDeref(dd,old[l]);
- FREE(old);
- return(NULL);
- }
- cuddRef(neW);
- Cudd_RecursiveDeref(dd,old[i]);
- old[i] = neW;
- }
-
- /* Test. */
- if (!Cudd_bddLeq(dd,old[i],f)) {
- FREE(saveString);
- for (l = 0; l < k; l++)
- FREE(string[l]);
- FREE(string);
- FREE(indices);
- for (l = 0; l <= i; l++)
- Cudd_RecursiveDeref(dd,old[l]);
- FREE(old);
- return(NULL);
- }
- }
-
- FREE(saveString);
- for (i = 0; i < k; i++) {
- cuddDeref(old[i]);
- FREE(string[i]);
- }
- FREE(string);
- FREE(indices);
- return(old);
-
-} /* end of Cudd_bddPickArbitraryMinterms */
-
-
-/**Function********************************************************************
-
- Synopsis [Extracts a subset from a BDD.]
-
- Description [Extracts a subset from a BDD in the following procedure.
- 1. Compute the weight for each mask variable by counting the number of
- minterms for both positive and negative cofactors of the BDD with
- respect to each mask variable. (weight = #positive - #negative)
- 2. Find a representative cube of the BDD by using the weight. From the
- top variable of the BDD, for each variable, if the weight is greater
- than 0.0, choose THEN branch, othereise ELSE branch, until meeting
- the constant 1.
- 3. Quantify out the variables not in maskVars from the representative
- cube and if a variable in maskVars is don't care, replace the
- variable with a constant(1 or 0) depending on the weight.
- 4. Make a subset of the BDD by multiplying with the modified cube.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_SubsetWithMaskVars(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick a cube */,
- DdNode ** vars /* array of variables */,
- int nvars /* size of <code>vars</code> */,
- 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;
- support = Cudd_Support(dd,f);
- cuddRef(support);
- Cudd_RecursiveDeref(dd,support);
-
- zero = Cudd_Not(dd->one);
- size = dd->size;
-
- weight = ALLOC(double,size);
- if (weight == 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, Cudd_Not(maskVars[i]));
- cuddRef(cof);
- weight[i] -= Cudd_CountMinterm(dd, cof, nvars);
- Cudd_RecursiveDeref(dd,cof);
- }
-
- string = ALLOC(char, size + 1);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- mask = ALLOC(int, size);
- if (mask == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- string[i] = '2';
- mask[i] = 0;
- }
- string[size] = '\0';
- indices = ALLOC(int,nvars);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- FREE(mask);
- return(NULL);
- }
- for (i = 0; i < nvars; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = ddPickRepresentativeCube(dd,f,nvars,weight,string);
- if (result == 0) {
- FREE(string);
- FREE(mask);
- 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) {
- FREE(string);
- FREE(mask);
- FREE(indices);
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(newCube);
- Cudd_RecursiveDeref(dd,cube);
- cube = newCube;
- }
- Cudd_RecursiveDeref(dd,cube);
-
- for (i = 0; i < mvars; i++) {
- 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';
- }
- } else {
- string[indices[i]] = '2';
- }
- }
-
- cube = Cudd_ReadOne(dd);
- cuddRef(cube);
- zero = Cudd_Not(Cudd_ReadOne(dd));
-
- /* 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) {
- FREE(string);
- FREE(mask);
- FREE(indices);
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(newCube);
- Cudd_RecursiveDeref(dd,cube);
- cube = newCube;
- }
-
- subset = Cudd_bddAnd(dd,f,cube);
- cuddRef(subset);
- Cudd_RecursiveDeref(dd,cube);
-
- /* Test. */
- if (Cudd_bddLeq(dd,subset,f)) {
- cuddDeref(subset);
- } else {
- Cudd_RecursiveDeref(dd,subset);
- subset = NULL;
- }
-
- FREE(string);
- FREE(mask);
- FREE(indices);
- FREE(weight);
- return(subset);
-
-} /* end of Cudd_SubsetWithMaskVars */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the first cube of a decision diagram.]
-
- Description [Defines an iterator on the onset of a decision diagram
- and finds its first cube. Returns a generator that contains the
- information necessary to continue the enumeration if successful; NULL
- otherwise.<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 disjoint cover of the function associated with the diagram.
- The size of the array equals the number of variables in the manager at
- the time Cudd_FirstCube is called.<p>
- For each cube, a value is also returned. This value is always 1 for a
- BDD, while it may be different from 1 for an ADD.
- For BDDs, the offset is the set of cubes whose value is the logical zero.
- For ADDs, the offset is the set of cubes whose value is the
- background value. The cubes of the offset are not enumerated.]
-
- SideEffects [The first cube and its value are returned as side effects.]
-
- SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty
- Cudd_FirstNode]
-
-******************************************************************************/
-DdGen *
-Cudd_FirstCube(
- DdManager * dd,
- DdNode * f,
- int ** cube,
- CUDD_VALUE_TYPE * value)
-{
- DdGen *gen;
- DdNode *top, *treg, *next, *nreg, *prev, *preg;
- int i;
- int nvars;
-
- /* Sanity Check. */
- if (dd == NULL || f == NULL) return(NULL);
-
- /* Allocate generator an initialize it. */
- gen = ALLOC(DdGen,1);
- if (gen == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
-
- gen->manager = dd;
- gen->type = CUDD_GEN_CUBES;
- gen->status = CUDD_GEN_EMPTY;
- gen->gen.cubes.cube = NULL;
- gen->gen.cubes.value = DD_ZERO_VAL;
- gen->stack.sp = 0;
- gen->stack.stack = NULL;
- gen->node = NULL;
-
- nvars = dd->size;
- gen->gen.cubes.cube = ALLOC(int,nvars);
- if (gen->gen.cubes.cube == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
-
- /* The maximum stack depth is one plus the number of variables.
- ** because a path may have nodes at all levels, including the
- ** constant level.
- */
- gen->stack.stack = ALLOC(DdNode *, nvars+1);
- if (gen->stack.stack == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen->gen.cubes.cube);
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
-
- /* Find the first cube of the onset. */
- 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);
- }
- } else {
- gen->status = CUDD_GEN_NONEMPTY;
- gen->gen.cubes.value = cuddV(top);
- goto done;
- }
- }
-
-done:
- *cube = gen->gen.cubes.cube;
- *value = gen->gen.cubes.value;
- return(gen);
-
-} /* end of Cudd_FirstCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates the next cube of a decision diagram onset.]
-
- Description [Generates the next cube of a decision diagram onset,
- using generator gen. Returns 0 if the enumeration is completed; 1
- otherwise.]
-
- SideEffects [The cube and its value are returned as side effects. The
- generator is modified.]
-
- SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty
- Cudd_NextNode]
-
-******************************************************************************/
-int
-Cudd_NextCube(
- DdGen * gen,
- int ** cube,
- CUDD_VALUE_TYPE * value)
-{
- DdNode *top, *treg, *next, *nreg, *prev, *preg;
- DdManager *dd = gen->manager;
-
- /* 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;
- }
- 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;
- }
- }
-
-done:
- if (gen->status == CUDD_GEN_EMPTY) return(0);
- *cube = gen->gen.cubes.cube;
- *value = gen->gen.cubes.value;
- return(1);
-
-} /* end of Cudd_NextCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the cube of an array of BDD variables.]
-
- Description [Computes the cube of an array of BDD variables. If
- non-null, the phase argument indicates which literal of each
- variable should appear in the cube. If phase\[i\] is nonzero, then the
- positive literal is used. If phase is NULL, the cube is positive unate.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd]
-
-******************************************************************************/
-DdNode *
-Cudd_bddComputeCube(
- DdManager * dd,
- DdNode ** vars,
- int * phase,
- int n)
-{
- 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) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(fn);
- Cudd_RecursiveDeref(dd,cube);
- cube = fn;
- }
- cuddDeref(cube);
-
- return(cube);
-
-} /* end of Cudd_bddComputeCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the cube of an array of ADD variables.]
-
- Description [Computes the cube of an array of ADD variables. If
- non-null, the phase argument indicates which literal of each
- variable should appear in the cube. If phase\[i\] is nonzero, then the
- positive literal is used. If phase is NULL, the cube is positive unate.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddComputeCube]
-
-******************************************************************************/
-DdNode *
-Cudd_addComputeCube(
- DdManager * dd,
- DdNode ** vars,
- int * phase,
- int n)
-{
- DdNode *cube, *zero;
- DdNode *fn;
- int i;
-
- cube = DD_ONE(dd);
- cuddRef(cube);
- 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) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(fn);
- Cudd_RecursiveDeref(dd,cube);
- cube = fn;
- }
- cuddDeref(cube);
-
- return(cube);
-
-} /* end of Cudd_addComputeCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds the BDD of a cube from a positional array.]
-
- Description [Builds a cube from a positional array. The array must
- have one integer entry for each BDD variable. If the i-th entry is
- 1, the variable of index i appears in true form in the cube; If the
- i-th entry is 0, the variable of index i appears complemented in the
- cube; otherwise the variable does not appear in the cube. Returns a
- pointer to the BDD for the cube if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray]
-
-******************************************************************************/
-DdNode *
-Cudd_CubeArrayToBdd(
- DdManager *dd,
- int *array)
-{
- DdNode *cube, *var, *tmp;
- int i;
- int size = Cudd_ReadSize(dd);
-
- 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);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cube);
- cube = tmp;
- }
- }
- cuddDeref(cube);
- return(cube);
-
-} /* end of Cudd_CubeArrayToBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds a positional array from the BDD of a cube.]
-
- Description [Builds a positional array from the BDD of a cube.
- Array must have one entry for each BDD variable. The positional
- array has 1 in i-th position if the variable of index i appears in
- true form in the cube; it has 0 in i-th position if the variable of
- index i appears in complemented form in the cube; finally, it has 2
- in i-th position if the variable of index i does not appear in the
- cube. Returns 1 if successful (the BDD is indeed a cube); 0
- otherwise.]
-
- SideEffects [The result is in the array passed by reference.]
-
- SeeAlso [Cudd_CubeArrayToBdd]
-
-******************************************************************************/
-int
-Cudd_BddToCubeArray(
- DdManager *dd,
- DdNode *cube,
- int *array)
-{
- DdNode *scan, *t, *e;
- int i;
- int size = Cudd_ReadSize(dd);
- DdNode *zero = Cudd_Not(DD_ONE(dd));
-
- for (i = size-1; i >= 0; i--) {
- 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 */
- }
- }
- if (scan == zero) {
- return(0);
- } else {
- return(1);
- }
-
-} /* end of Cudd_BddToCubeArray */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the first node of a decision diagram.]
-
- Description [Defines an iterator on the nodes of a decision diagram
- and finds its first node. Returns a generator that contains the
- information necessary to continue the enumeration if successful; NULL
- otherwise.]
-
- SideEffects [The first node is returned as a side effect.]
-
- SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty
- Cudd_FirstCube]
-
-******************************************************************************/
-DdGen *
-Cudd_FirstNode(
- DdManager * dd,
- DdNode * f,
- DdNode ** node)
-{
- DdGen *gen;
- int retval;
-
- /* Sanity Check. */
- if (dd == NULL || f == NULL) return(NULL);
-
- /* Allocate generator an initialize it. */
- gen = ALLOC(DdGen,1);
- if (gen == 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) {
- 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);
- 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);
- FREE(gen);
- return(NULL);
- }
-
- /* Find the first node. */
- retval = st_gen(gen->gen.nodes.stGen, (char **) &(gen->node), NULL);
- if (retval != 0) {
- gen->status = CUDD_GEN_NONEMPTY;
- *node = gen->node;
- }
-
- return(gen);
-
-} /* end of Cudd_FirstNode */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the next node of a decision diagram.]
-
- Description [Finds the node of a decision diagram, using generator
- gen. Returns 0 if the enumeration is completed; 1 otherwise.]
-
- SideEffects [The next node is returned as a side effect.]
-
- SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty
- Cudd_NextCube]
-
-******************************************************************************/
-int
-Cudd_NextNode(
- DdGen * gen,
- DdNode ** node)
-{
- int retval;
-
- /* Find the next node. */
- retval = st_gen(gen->gen.nodes.stGen, (char **) &(gen->node), NULL);
- if (retval == 0) {
- gen->status = CUDD_GEN_EMPTY;
- } else {
- *node = gen->node;
- }
-
- return(retval);
-
-} /* end of Cudd_NextNode */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees a CUDD generator.]
-
- Description [Frees a CUDD generator. Always returns 0, so that it can
- be used in mis-like foreach constructs.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube
- Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty]
-
-******************************************************************************/
-int
-Cudd_GenFree(
- DdGen * gen)
-{
-
- if (gen == NULL) return(0);
- switch (gen->type) {
- case CUDD_GEN_CUBES:
- case CUDD_GEN_ZDD_PATHS:
- FREE(gen->gen.cubes.cube);
- FREE(gen->stack.stack);
- break;
- case CUDD_GEN_NODES:
- st_free_gen(gen->gen.nodes.stGen);
- st_free_table(gen->gen.nodes.visited);
- break;
- default:
- return(0);
- }
- FREE(gen);
- return(0);
-
-} /* end of Cudd_GenFree */
-
-
-/**Function********************************************************************
-
- Synopsis [Queries the status of a generator.]
-
- Description [Queries the status of a generator. Returns 1 if the
- generator is empty or NULL; 0 otherswise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube
- Cudd_FirstNode Cudd_NextNode Cudd_GenFree]
-
-******************************************************************************/
-int
-Cudd_IsGenEmpty(
- DdGen * gen)
-{
- if (gen == NULL) return(1);
- return(gen->status == CUDD_GEN_EMPTY);
-
-} /* end of Cudd_IsGenEmpty */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds a cube of BDD variables from an array of indices.]
-
- Description [Builds a cube of BDD variables from an array of indices.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd]
-
-******************************************************************************/
-DdNode *
-Cudd_IndicesToCube(
- DdManager * dd,
- int * array,
- int n)
-{
- DdNode *cube, *tmp;
- int i;
-
- 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) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cube);
- cube = tmp;
- }
-
- cuddDeref(cube);
- return(cube);
-
-} /* end of Cudd_IndicesToCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the package version number.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_PrintVersion(
- FILE * fp)
-{
- (void) fprintf(fp, "%s\n", CUDD_VERSION);
-
-} /* end of Cudd_PrintVersion */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the average distance between adjacent nodes.]
-
- Description [Computes the average distance between adjacent nodes in
- the manager. Adjacent nodes are node pairs such that the second node
- is the then child, else child, or next node in the collision list.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-double
-Cudd_AverageDistance(
- DdManager * dd)
-{
- double tetotal, nexttotal;
- double tesubtotal, nextsubtotal;
- double temeasured, nextmeasured;
- int i, j;
- int slots, nvars;
- long diff;
- DdNode *scan;
- DdNodePtr *nodelist;
- DdNode *sentinel = &(dd->sentinel);
-
- nvars = dd->size;
- if (nvars == 0) return(0.0);
-
- /* Initialize totals. */
- tetotal = 0.0;
- nexttotal = 0.0;
- temeasured = 0.0;
- nextmeasured = 0.0;
-
- /* 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;
- }
- }
- tetotal += tesubtotal;
- nexttotal += nextsubtotal;
- }
-
- /* Scan the constant table. */
- nodelist = dd->constants.nodelist;
- 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 = scan->next;
- }
- }
- nexttotal += nextsubtotal;
-
- return((tetotal + nexttotal) / (temeasured + nextmeasured));
-
-} /* end of Cudd_AverageDistance */
-
-
-/**Function********************************************************************
-
- Synopsis [Portable random number generator.]
-
- Description [Portable number generator based on ran2 from "Numerical
- Recipes in C." It is a long period (> 2 * 10^18) random number generator
- of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly
- distributed between 0 and 2147483561 (inclusive of the endpoint values).
- The random generator can be explicitly initialized by calling
- Cudd_Srandom. If no explicit initialization is performed, then the
- seed 1 is assumed.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Srandom]
-
-******************************************************************************/
-long
-Cudd_Random(
- )
-{
- int i; /* index in the shuffle table */
- long int w; /* work variable */
-
- /* cuddRand == 0 if the geneartor has not been initialized yet. */
- if (cuddRand == 0) Cudd_Srandom(1);
-
- /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding
- ** overflows by Schrage's method.
- */
- w = cuddRand / LEQQ1;
- cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
- cuddRand += (cuddRand < 0) * MODULUS1;
-
- /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding
- ** overflows by Schrage's method.
- */
- w = cuddRand2 / LEQQ2;
- cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2;
- cuddRand2 += (cuddRand2 < 0) * MODULUS2;
-
- /* cuddRand is shuffled with the Bays-Durham algorithm.
- ** shuffleSelect and cuddRand2 are combined to generate the output.
- */
-
- /* Pick one element from the shuffle table; "i" will be in the range
- ** from 0 to STAB_SIZE-1.
- */
- i = (int) (shuffleSelect / STAB_DIV);
- /* Mix the element of the shuffle table with the current iterate of
- ** the second sub-generator, and replace the chosen element of the
- ** shuffle table with the current iterate of the first sub-generator.
- */
- shuffleSelect = shuffleTable[i] - cuddRand2;
- shuffleTable[i] = cuddRand;
- shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1);
- /* Since shuffleSelect != 0, and we want to be able to return 0,
- ** here we subtract 1 before returning.
- */
- return(shuffleSelect - 1);
-
-} /* end of Cudd_Random */
-
-
-/**Function********************************************************************
-
- Synopsis [Initializer for the portable random number generator.]
-
- Description [Initializer for the portable number generator based on
- ran2 in "Numerical Recipes in C." The input is the seed for the
- generator. If it is negative, its absolute value is taken as seed.
- If it is 0, then 1 is taken as seed. The initialized sets up the two
- recurrences used to generate a long-period stream, and sets up the
- shuffle table.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Random]
-
-******************************************************************************/
-void
-Cudd_Srandom(
- long seed)
-{
- int i;
-
- if (seed < 0) cuddRand = -seed;
- else if (seed == 0) cuddRand = 1;
- else cuddRand = seed;
- 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;
- }
- shuffleSelect = shuffleTable[1 % STAB_SIZE];
-
-} /* end of Cudd_Srandom */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the density of a BDD or ADD.]
-
- Description [Computes the density of a BDD or ADD. The density is
- the ratio of the number of minterms to the number of nodes. If 0 is
- passed as number of variables, the number of variables existing in
- the manager is used. Returns the density if successful; (double)
- CUDD_OUT_OF_MEM otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CountMinterm Cudd_DagSize]
-
-******************************************************************************/
-double
-Cudd_Density(
- DdManager * dd /* manager */,
- DdNode * f /* function whose density is sought */,
- int nvars /* size of the support of f */)
-{
- double minterms;
- int nodes;
- double density;
-
- if (nvars == 0) nvars = dd->size;
- minterms = Cudd_CountMinterm(dd,f,nvars);
- if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms);
- nodes = Cudd_DagSize(f);
- density = minterms / (double) nodes;
- return(density);
-
-} /* end of Cudd_Density */
-
-
-/**Function********************************************************************
-
- Synopsis [Warns that a memory allocation failed.]
-
- Description [Warns that a memory allocation failed.
- This function can be used as replacement of MMout_of_memory to prevent
- the safe_mem functions of the util package from exiting when malloc
- returns NULL. One possible use is in case of discretionary allocations;
- for instance, the allocation of memory to enlarge the computed table.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_OutOfMem(
- long size /* size of the allocation that failed */)
-{
- (void) fflush(stdout);
- (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size);
- return;
-
-} /* end of Cudd_OutOfMem */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a DD to the standard output. One line per node is
- printed.]
-
- Description [Prints a DD to the standard output. One line per node is
- printed. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_PrintDebug]
-
-******************************************************************************/
-int
-cuddP(
- DdManager * dd,
- DdNode * f)
-{
- int retval;
- st_table *table = st_init_table(st_ptrcmp,st_ptrhash);
-
- if (table == NULL) return(0);
-
- retval = dp2(dd,f,table);
- st_free_table(table);
- (void) fputc('\n',dd->out);
- return(retval);
-
-} /* end of cuddP */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the memory used to store the minterm counts recorded
- in the visited table.]
-
- Description [Frees the memory used to store the minterm counts
- recorded in the visited table. Returns ST_CONTINUE.]
-
- SideEffects [None]
-
-******************************************************************************/
-enum st_retval
-cuddStCountfree(
- char * key,
- char * value,
- char * arg)
-{
- double *d;
-
- d = (double *)value;
- FREE(d);
- return(ST_CONTINUE);
-
-} /* end of cuddStCountfree */
-
-
-/**Function********************************************************************
-
- 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
- symbol table. f is assumed to be a regular pointer and
- cuddCollectNodes guarantees this assumption in the recursive calls.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddCollectNodes(
- DdNode * f,
- st_table * visited)
-{
- DdNode *T, *E;
- int retval;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- /* If already visited, nothing to do. */
- if (st_is_member(visited, (char *) f) == 1)
- return(1);
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Mark node as visited. */
- if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
- return(0);
-
- /* Check terminal case. */
- if (cuddIsConstant(f))
- return(1);
-
- /* Recursive calls. */
- T = cuddT(f);
- retval = cuddCollectNodes(T,visited);
- if (retval != 1) return(retval);
- E = Cudd_Regular(cuddE(f));
- retval = cuddCollectNodes(E,visited);
- return(retval);
-
-} /* end of cuddCollectNodes */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of cuddP.]
-
- Description [Performs the recursive step of cuddP. Returns 1 in case
- of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-dp2(
- DdManager *dd,
- DdNode * f,
- st_table * t)
-{
- DdNode *g, *n, *N;
- int T,E;
-
- if (f == NULL) {
- return(0);
- }
- g = Cudd_Regular(f);
- 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));
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f),
- (unsigned) g / (unsigned) sizeof(DdNode),cuddV(g));
-#endif
- 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);
-#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);
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f),
- (unsigned) g / (unsigned) 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);
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\t", bang(f),
- (unsigned) g / (unsigned) sizeof(DdNode),g->index);
-#endif
-#endif
- n = cuddT(g);
- if (cuddIsConstant(n)) {
- (void) fprintf(dd->out,"T = %-9g\t",cuddV(n));
- T = 1;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"T = 0x%lx\t",(unsigned long) n / (unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(dd->out,"T = 0x%x\t",(unsigned) n / (unsigned) sizeof(DdNode));
-#endif
- 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;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (unsigned long) N/(unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (unsigned) N/(unsigned) sizeof(DdNode));
-#endif
- E = 0;
- }
- if (E == 0) {
- if (dp2(dd,N,t) == 0)
- return(0);
- }
- if (T == 0) {
- if (dp2(dd,cuddT(g),t) == 0)
- return(0);
- }
- return(1);
-
-} /* end of dp2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_PrintMinterm.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddPrintMintermAux(
- DdManager * dd /* manager */,
- DdNode * node /* current node */,
- int * list /* current recursion path */)
-{
- 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,"-");
- }
- (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;
- }
- return;
-
-} /* end of ddPrintMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_DagSize.]
-
- Description [Performs the recursive step of Cudd_DagSize. Returns the
- number of nodes in the graph rooted at n.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddDagInt(
- DdNode * n)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(n->next)) {
- return(0);
- }
- n->next = Cudd_Not(n->next);
- if (cuddIsConstant(n)) {
- return(1);
- }
- tval = ddDagInt(cuddT(n));
- eval = ddDagInt(Cudd_Regular(cuddE(n)));
- return(1 + tval + eval);
-
-} /* end of ddDagInt */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CofactorEstimate.]
-
- Description [Performs the recursive step of Cudd_CofactorEstimate.
- Returns an estimate of the number of nodes in the DD of a
- cofactor of node. Uses the least significant bit of the next field as
- visited flag. node is supposed to be regular; the invariant is maintained
- by this procedure.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddEstimateCofactor(
- DdManager *dd,
- st_table *table,
- DdNode * node,
- int i,
- int phase,
- DdNode ** ptr)
-{
- int tval, eval, val;
- 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);
- }
- 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);
- }
- 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 (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);
- }
- tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT);
- eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i,
- 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);
- }
- } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) &&
- (*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;
- }
- return(val);
-
-} /* end of cuddEstimateCofactor */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the unique table for the existence of an internal node.]
-
- Description [Checks the unique table for the existence of an internal
- node. Returns a pointer to the node if it is in the table; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddUniqueInter]
-
-******************************************************************************/
-static DdNode *
-cuddUniqueLookup(
- DdManager * unique,
- int index,
- DdNode * T,
- DdNode * E)
-{
- int posn;
- unsigned int level;
- DdNodePtr *nodelist;
- DdNode *looking;
- DdSubtable *subtable;
-
- if (index >= unique->size) {
- return(NULL);
- }
-
- level = unique->perm[index];
- subtable = &(unique->subtables[level]);
-
-#ifdef DD_DEBUG
- assert(level < (unsigned) cuddI(unique,T->index));
- assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
-#endif
-
- posn = ddHash(T, E, subtable->shift);
- nodelist = subtable->nodelist;
- looking = nodelist[posn];
-
- while (T < cuddT(looking)) {
- looking = Cudd_Regular(looking->next);
- }
- while (T == cuddT(looking) && E < cuddE(looking)) {
- looking = Cudd_Regular(looking->next);
- }
- if (cuddT(looking) == T && cuddE(looking) == E) {
- return(looking);
- }
-
- return(NULL);
-
-} /* end of cuddUniqueLookup */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.]
-
- Description [Performs the recursive step of Cudd_CofactorEstimateSimple.
- Returns an estimate of the number of nodes in the DD of the positive
- cofactor of node. Uses the least significant bit of the next field as
- visited flag. node is supposed to be regular; the invariant is maintained
- by this procedure.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddEstimateCofactorSimple(
- DdNode * node,
- int i)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(node->next)) {
- return(0);
- }
- node->next = Cudd_Not(node->next);
- if (cuddIsConstant(node)) {
- return(1);
- }
- tval = cuddEstimateCofactorSimple(cuddT(node),i);
- if ((int) node->index == i) return(tval);
- eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i);
- return(1 + tval + eval);
-
-} /* end of cuddEstimateCofactorSimple */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountMinterm.]
-
- Description [Performs the recursive step of Cudd_CountMinterm.
- It is based on the following identity. Let |f| be the
- number of minterms of f. Then:
- <xmp>
- |f| = (|f0|+|f1|)/2
- </xmp>
- where f0 and f1 are the two cofactors of f. Does not use the
- identity |f'| = max - |f|, to minimize loss of accuracy due to
- roundoff. Returns the number of minterms of the function rooted at
- node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static double
-ddCountMintermAux(
- DdNode * node,
- double max,
- DdHashTable * table)
-{
- 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 (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
- 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);
- }
-
- minT = ddCountMintermAux(Nt,max,table);
- if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- minT *= 0.5;
- minE = ddCountMintermAux(Ne,max,table);
- if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- minE *= 0.5;
- 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);
- }
- }
-
- return(min);
-
-} /* end of ddCountMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountPath.]
-
- Description [Performs the recursive step of Cudd_CountPath.
- It is based on the following identity. Let |f| be the
- number of paths of f. Then:
- <xmp>
- |f| = |f0|+|f1|
- </xmp>
- where f0 and f1 are the two cofactors of f. Uses the
- identity |f'| = |f|, to improve the utilization of the (local) cache.
- Returns the number of paths of the function rooted at node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static double
-ddCountPathAux(
- DdNode * node,
- st_table * table)
-{
-
- DdNode *Nv, *Nnv;
- double paths, *ppaths, paths1, paths2;
- double *dummy;
-
-
- if (cuddIsConstant(node)) {
- return(1.0);
- }
- if (st_lookup(table, (char *)node, (char **)&dummy)) {
- paths = *dummy;
- return(paths);
- }
-
- Nv = cuddT(node); Nnv = cuddE(node);
-
- paths1 = ddCountPathAux(Nv,table);
- if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths2 = ddCountPathAux(Cudd_Regular(Nnv),table);
- if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths = paths1 + paths2;
-
- ppaths = ALLOC(double,1);
- if (ppaths == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
-
- *ppaths = paths;
-
- if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) {
- FREE(ppaths);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(paths);
-
-} /* end of ddCountPathAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountMinterm.]
-
- Description [Performs the recursive step of Cudd_CountMinterm.
- It is based on the following identity. Let |f| be the
- number of minterms of f. Then:
- <xmp>
- |f| = (|f0|+|f1|)/2
- </xmp>
- where f0 and f1 are the two cofactors of f. Does not use the
- identity |f'| = max - |f|, to minimize loss of accuracy due to
- roundoff. Returns the number of minterms of the function rooted at
- node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddEpdCountMintermAux(
- DdNode * node,
- EpDouble * max,
- EpDouble * epd,
- st_table * table)
-{
- DdNode *Nt, *Ne;
- EpDouble *min, minT, minE;
- EpDouble *res;
- int status;
-
- if (cuddIsConstant(node)) {
- 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);
- }
-
- 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);
- if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
- if (Cudd_IsComplement(Ne)) {
- EpdSubtract3(max, &minE, epd);
- EpdCopy(epd, &minE);
- }
- EpdMultiply(&minE, (double)0.5);
- 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);
- }
- }
-
- return(0);
-
-} /* end of ddEpdCountMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.]
-
- Description [Performs the recursive step of Cudd_CountPathsToNonZero.
- It is based on the following identity. Let |f| be the
- number of paths of f. Then:
- <xmp>
- |f| = |f0|+|f1|
- </xmp>
- where f0 and f1 are the two cofactors of f. Returns the number of
- paths of the function rooted at node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static double
-ddCountPathsToNonZero(
- DdNode * N,
- st_table * table)
-{
-
- 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));
- }
- if (st_lookup(table, (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);
- }
-
- paths1 = ddCountPathsToNonZero(Nt,table);
- if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths2 = ddCountPathsToNonZero(Ne,table);
- if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths = paths1 + paths2;
-
- ppaths = ALLOC(double,1);
- if (ppaths == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
-
- *ppaths = paths;
-
- if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) {
- FREE(ppaths);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(paths);
-
-} /* end of ddCountPathsToNonZero */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_Support.]
-
- Description [Performs the recursive step of Cudd_Support. Performs a
- DFS from f. The support is accumulated in supp as a side effect. Uses
- the LSB of the then pointer as visited flag.]
-
- SideEffects [None]
-
- SeeAlso [ddClearFlag]
-
-******************************************************************************/
-static void
-ddSupportStep(
- DdNode * f,
- int * support)
-{
- if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
- return;
- }
-
- support[f->index] = 1;
- ddSupportStep(cuddT(f),support);
- ddSupportStep(Cudd_Regular(cuddE(f)),support);
- /* Mark as visited. */
- f->next = Cudd_Not(f->next);
- return;
-
-} /* end of ddSupportStep */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a DFS from f, clearing the LSB of the next
- pointers.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [ddSupportStep ddDagInt]
-
-******************************************************************************/
-static void
-ddClearFlag(
- DdNode * f)
-{
- if (!Cudd_IsComplement(f->next)) {
- return;
- }
- /* Clear visited flag. */
- f->next = Cudd_Regular(f->next);
- if (cuddIsConstant(f)) {
- return;
- }
- ddClearFlag(cuddT(f));
- ddClearFlag(Cudd_Regular(cuddE(f)));
- return;
-
-} /* end of ddClearFlag */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountLeaves.]
-
- Description [Performs the recursive step of Cudd_CountLeaves. Returns
- the number of leaves in the DD rooted at n.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_CountLeaves]
-
-******************************************************************************/
-static int
-ddLeavesInt(
- DdNode * n)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(n->next)) {
- return(0);
- }
- n->next = Cudd_Not(n->next);
- if (cuddIsConstant(n)) {
- return(1);
- }
- tval = ddLeavesInt(cuddT(n));
- eval = ddLeavesInt(Cudd_Regular(cuddE(n)));
- return(tval + eval);
-
-} /* end of ddLeavesInt */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.]
-
- Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [none]
-
- SeeAlso [Cudd_bddPickArbitraryMinterms]
-
-******************************************************************************/
-static int
-ddPickArbitraryMinterms(
- DdManager *dd,
- DdNode *node,
- int nvars,
- int nminterms,
- char **string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
- int i, t, result;
- double min1, min2;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(dd);
- bzero = Cudd_Not(one);
- if (nminterms == 0 || node == bzero) return(1);
- if (node == one) {
- return(1);
- }
-
- N = Cudd_Regular(node);
- T = cuddT(N); E = cuddE(N);
- if (Cudd_IsComplement(node)) {
- T = Cudd_Not(T); E = Cudd_Not(E);
- }
-
- min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0;
- if (min1 == (double)CUDD_OUT_OF_MEM) return(0);
- min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0;
- if (min2 == (double)CUDD_OUT_OF_MEM) return(0);
-
- t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5);
- for (i = 0; i < t; i++)
- string[i][N->index] = '1';
- for (i = t; i < nminterms; i++)
- string[i][N->index] = '0';
-
- result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]);
- if (result == 0)
- return(0);
- result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]);
- return(result);
-
-} /* end of ddPickArbitraryMinterms */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds a representative cube of a BDD.]
-
- Description [Finds a representative cube of a BDD with the weight of
- each variable. From the top variable, if the weight is greater than or
- equal to 0.0, choose THEN branch unless the child is the constant 0.
- Otherwise, choose ELSE branch unless the child is the constant 0.]
-
- SideEffects [Cudd_SubsetWithMaskVars Cudd_bddPickOneCube]
-
-******************************************************************************/
-static int
-ddPickRepresentativeCube(
- DdManager *dd,
- DdNode *node,
- int nvars,
- double *weight,
- char *string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(dd);
- bzero = Cudd_Not(one);
- if (node == bzero) return(0);
-
- 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';
- }
- } else {
- if (E == bzero) {
- node = T;
- string[N->index] = '1';
- } else {
- node = E;
- string[N->index] = '0';
- }
- }
- }
- return(1);
-
-} /* end of ddPickRepresentativeCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the memory used to store the minterm counts recorded
- in the visited table.]
-
- Description [Frees the memory used to store the minterm counts
- recorded in the visited table. Returns ST_CONTINUE.]
-
- SideEffects [None]
-
-******************************************************************************/
-static enum st_retval
-ddEpdFree(
- char * key,
- char * value,
- char * arg)
-{
- EpDouble *epd;
-
- epd = (EpDouble *) value;
- EpdFree(epd);
- return(ST_CONTINUE);
-
-} /* end of ddEpdFree */
diff --git a/src/bdd/cudd/cuddWindow.c b/src/bdd/cudd/cuddWindow.c
deleted file mode 100644
index 9ceb79b2..00000000
--- a/src/bdd/cudd/cuddWindow.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddWindow.c]
-
- PackageName [cudd]
-
- Synopsis [Functions for 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-#ifdef DD_STATS
-extern int ddTotalNumberSwapping;
-extern int ddTotalNISwaps;
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by applying the method of the sliding window.]
-
- Description [Reorders by applying the method of the sliding window.
- Tries all possible permutations to the variables in a window that
- slides from low to high. The size of the window is determined by
- submethod. Assumes that no dead nodes are present. Returns 1 in
- case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddWindowReorder(
- DdManager * table /* DD table */,
- int low /* lowest index to reorder */,
- int high /* highest index to reorder */,
- Cudd_ReorderingType submethod /* window reordering option */)
-{
-
- int res;
-#ifdef DD_DEBUG
- int supposedOpt;
-#endif
-
- switch (submethod) {
- case CUDD_REORDER_WINDOW2:
- res = ddWindow2(table,low,high);
- break;
- case CUDD_REORDER_WINDOW3:
- res = ddWindow3(table,low,high);
- break;
- case CUDD_REORDER_WINDOW4:
- res = ddWindow4(table,low,high);
- break;
- case CUDD_REORDER_WINDOW2_CONV:
- res = ddWindowConv2(table,low,high);
- break;
- case CUDD_REORDER_WINDOW3_CONV:
- 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);
- }
-#endif
- break;
- case CUDD_REORDER_WINDOW4_CONV:
- 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);
- }
-#endif
- break;
- default: return(0);
- }
-
- return(res);
-
-} /* end of cuddWindowReorder */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Reorders by applying a sliding window of width 2.]
-
- Description [Reorders by applying a sliding window of width 2.
- Tries both permutations of the variables in a window
- that slides from low to high. Assumes that no dead nodes are
- present. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindow2(
- DdManager * table,
- int low,
- int high)
-{
-
- int x;
- int res;
- int size;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- if (high-low < 1) return(0);
-
- 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 */
- 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);
-#endif
- }
-
- return(1);
-
-} /* end of ddWindow2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by repeatedly applying a sliding window of width 2.]
-
- Description [Reorders by repeatedly applying a sliding window of width
- 2. Tries both permutations of the variables in a window
- that slides from low to high. Assumes that no dead nodes are
- present. Uses an event-driven approach to determine convergence.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindowConv2(
- DdManager * table,
- int low,
- int high)
-{
- int x;
- int res;
- int nwin;
- int newevent;
- int *events;
- int size;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- if (high-low < 1) return(ddWindowConv2(table,low,high));
-
- nwin = high-low;
- events = ALLOC(int,nwin);
- if (events == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (x=0; x<nwin; x++) {
- 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) {
- FREE(events);
- return(0);
- }
- if (res >= size) { /* no improvement: undo permutation */
- res = cuddSwapInPlace(table,x+low,x+low+1);
- if (res == 0) {
- 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);
-#endif
- }
- }
-#ifdef DD_STATS
- if (newevent) {
- (void) fprintf(table->out,"|");
- fflush(table->out);
- }
-#endif
- } while (newevent);
-
- FREE(events);
-
- return(1);
-
-} /* end of ddWindowConv3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Tries all the permutations of the three variables between
- x and x+2 and retains the best.]
-
- Description [Tries all the permutations of the three variables between
- x and x+2 and retains the best. Assumes that no dead nodes are
- present. Returns the index of the best permutation (1-6) in case of
- success; 0 otherwise.Assumes that no dead nodes are present. Returns
- the index of the best permutation (1-6) in case of success; 0
- otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddPermuteWindow3(
- DdManager * table,
- int x)
-{
- int y,z;
- int size,sizeNew;
- int best;
-
-#ifdef DD_DEBUG
- assert(table->dead == 0);
- assert(x+2 < table->size);
-#endif
-
- 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.
- */
-#define ABC 1
- best = ABC;
-
-#define BAC 2
- sizeNew = cuddSwapInPlace(table,x,y);
- if (sizeNew < size) {
- 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;
- }
-#define CBA 4
- sizeNew = cuddSwapInPlace(table,x,y);
- if (sizeNew < size) {
- 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;
- }
-#define ACB 6
- sizeNew = cuddSwapInPlace(table,x,y);
- if (sizeNew < size) {
- if (sizeNew == 0) return(0);
- best = ACB;
- size = sizeNew;
- }
-
- /* Now take the shortest route to the best permuytation.
- ** The initial permutation is ACB.
- */
- switch(best) {
- case BCA: if (!cuddSwapInPlace(table,y,z)) return(0);
- case CBA: if (!cuddSwapInPlace(table,x,y)) return(0);
- case ABC: if (!cuddSwapInPlace(table,y,z)) return(0);
- case ACB: break;
- case BAC: if (!cuddSwapInPlace(table,y,z)) return(0);
- case CAB: if (!cuddSwapInPlace(table,x,y)) return(0);
- break;
- default: return(0);
- }
-
-#ifdef DD_DEBUG
- assert(table->keys - table->isolated == (unsigned) size);
-#endif
-
- return(best);
-
-} /* end of ddPermuteWindow3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by applying a sliding window of width 3.]
-
- Description [Reorders by applying a sliding window of width 3.
- Tries all possible permutations to the variables in a
- window that slides from low to high. Assumes that no dead nodes are
- present. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindow3(
- DdManager * table,
- int low,
- int high)
-{
-
- int x;
- int res;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- 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);
-#ifdef DD_STATS
- if (res == ABC) {
- (void) fprintf(table->out,"=");
- } else {
- (void) fprintf(table->out,"-");
- }
- fflush(table->out);
-#endif
- }
-
- return(1);
-
-} /* end of ddWindow3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by repeatedly applying a sliding window of width 3.]
-
- Description [Reorders by repeatedly applying a sliding window of width
- 3. Tries all possible permutations to the variables in a
- window that slides from low to high. Assumes that no dead nodes are
- present. Uses an event-driven approach to determine convergence.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindowConv3(
- DdManager * table,
- int low,
- int high)
-{
- int x;
- int res;
- int nwin;
- int newevent;
- int *events;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- if (high-low < 2) return(ddWindowConv2(table,low,high));
-
- nwin = high-low-1;
- events = ALLOC(int,nwin);
- if (events == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (x=0; x<nwin; x++) {
- 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:
- 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);
-#endif
- }
- }
-#ifdef DD_STATS
- if (newevent) {
- (void) fprintf(table->out,"|");
- fflush(table->out);
- }
-#endif
- } while (newevent);
-
- FREE(events);
-
- return(1);
-
-} /* end of ddWindowConv3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Tries all the permutations of the four variables between w
- and w+3 and retains the best.]
-
- Description [Tries all the permutations of the four variables between
- w and w+3 and retains the best. Assumes that no dead nodes are
- present. Returns the index of the best permutation (1-24) in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddPermuteWindow4(
- DdManager * table,
- int w)
-{
- int x,y,z;
- int size,sizeNew;
- int best;
-
-#ifdef DD_DEBUG
- assert(table->dead == 0);
- assert(w+3 < table->size);
-#endif
-
- 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)
- * repeated three times to get all 4! = 24 permutations.
- * This gives a hamiltonian circuit of Cayley's graph.
- * The codes to the permutation are assigned in topological order.
- * The permutations at lower distance from the final permutation are
- * assigned lower codes. This way we can choose, between
- * permutations that give the same size, one that requires the minimum
- * number of swaps from the final permutation of the hamiltonian circuit.
- * There is an exception to this rule: ABCD is given Code 1, to
- * avoid oscillation when convergence is sought.
- */
-#define ABCD 1
- best = ABCD;
-
-#define BACD 7
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size) {
- 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;
- }
-#define ABDC 8
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size || (sizeNew == size && ABDC < best)) {
- 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;
- }
-#define ADCB 9
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size || (sizeNew == size && ADCB < best)) {
- 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;
- }
-#define DABC 20
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size) {
- 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;
- }
-#define BDAC 19
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size || (sizeNew == size && BDAC < best)) {
- 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;
- }
-#define DBCA 24
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size) {
- 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;
- }
-#define DCAB 18
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size || (sizeNew == size && DCAB < best)) {
- 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;
- }
-#define CDBA 17
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size || (sizeNew == size && CDBA < best)) {
- 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;
- }
-#define BCDA 16
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size || (sizeNew == size && BCDA < best)) {
- 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;
- }
-#define CBAD 5
- sizeNew = cuddSwapInPlace(table,w,x);
- if (sizeNew < size || (sizeNew == size && CBAD < best)) {
- 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;
- }
-#define CADB 6
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size || (sizeNew == size && CADB < best)) {
- 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;
- }
-#define ACBD 2
- sizeNew = cuddSwapInPlace(table,y,z);
- if (sizeNew < size || (sizeNew == size && ACBD < best)) {
- if (sizeNew == 0) return(0);
- best = ACBD;
- size = sizeNew;
- }
-
- /* Now take the shortest route to the best permutation.
- ** The initial permutation is ACBD.
- */
- switch(best) {
- case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0);
- case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0);
- case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0);
- case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0);
- case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0);
- case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0);
- case ACBD: break;
- 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;
- 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;
- 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;
- 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;
- 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;
- default: return(0);
- }
-
-#ifdef DD_DEBUG
- assert(table->keys - table->isolated == (unsigned) size);
-#endif
-
- return(best);
-
-} /* end of ddPermuteWindow4 */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by applying a sliding window of width 4.]
-
- Description [Reorders by applying a sliding window of width 4.
- Tries all possible permutations to the variables in a
- window that slides from low to high. Assumes that no dead nodes are
- present. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindow4(
- DdManager * table,
- int low,
- int high)
-{
-
- int w;
- int res;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- 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);
-#ifdef DD_STATS
- if (res == ABCD) {
- (void) fprintf(table->out,"=");
- } else {
- (void) fprintf(table->out,"-");
- }
- fflush(table->out);
-#endif
- }
-
- return(1);
-
-} /* end of ddWindow4 */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders by repeatedly applying a sliding window of width 4.]
-
- Description [Reorders by repeatedly applying a sliding window of width
- 4. Tries all possible permutations to the variables in a
- window that slides from low to high. Assumes that no dead nodes are
- present. Uses an event-driven approach to determine convergence.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-ddWindowConv4(
- DdManager * table,
- int low,
- int high)
-{
- int x;
- int res;
- int nwin;
- int newevent;
- int *events;
-
-#ifdef DD_DEBUG
- assert(low >= 0 && high < table->size);
-#endif
-
- if (high-low < 3) return(ddWindowConv3(table,low,high));
-
- nwin = high-low-2;
- events = ALLOC(int,nwin);
- if (events == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (x=0; x<nwin; x++) {
- 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:
- 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);
-#endif
- }
- }
-#ifdef DD_STATS
- if (newevent) {
- (void) fprintf(table->out,"|");
- fflush(table->out);
- }
-#endif
- } while (newevent);
-
- FREE(events);
-
- return(1);
-
-} /* end of ddWindowConv4 */
-
diff --git a/src/bdd/cudd/cuddZddCount.c b/src/bdd/cudd/cuddZddCount.c
deleted file mode 100644
index 6c6ec1df..00000000
--- a/src/bdd/cudd/cuddZddCount.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddCount.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms in a ZDD.]
-
- Description [Returns an integer representing the number of minterms
- in a ZDD.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddCountDouble]
-
-******************************************************************************/
-int
-Cudd_zddCount(
- DdManager * zdd,
- DdNode * P)
-{
- st_table *table;
- int res;
- DdNode *base, *empty;
-
- base = DD_ONE(zdd);
- empty = DD_ZERO(zdd);
- table = st_init_table(st_ptrcmp, st_ptrhash);
- 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;
- }
- st_foreach(table, st_zdd_countfree, NIL(char));
- st_free_table(table);
-
- return(res);
-
-} /* end of Cudd_zddCount */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms of a ZDD.]
-
- Description [Counts the number of minterms of a ZDD. The result is
- returned as a double. If the procedure runs out of memory, it
- returns (double) CUDD_OUT_OF_MEM. This procedure is used in
- Cudd_zddCountMinterm.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddCountMinterm Cudd_zddCount]
-
-******************************************************************************/
-double
-Cudd_zddCountDouble(
- DdManager * zdd,
- DdNode * P)
-{
- st_table *table;
- double res;
- DdNode *base, *empty;
-
- base = DD_ONE(zdd);
- empty = DD_ZERO(zdd);
- table = st_init_table(st_ptrcmp, st_ptrhash);
- 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;
- }
- st_foreach(table, st_zdd_count_dbl_free, NIL(char));
- st_free_table(table);
-
- return(res);
-
-} /* end of Cudd_zddCountDouble */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddCount.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddCountStep(
- DdNode * P,
- st_table * table,
- DdNode * base,
- DdNode * empty)
-{
- int res;
- int *dummy;
-
- if (P == empty)
- return(0);
- if (P == base)
- return(1);
-
- /* Check cache. */
- if (st_lookup(table, (char *)P, (char **)(&dummy))) {
- res = *dummy;
- return(res);
- }
-
- res = cuddZddCountStep(cuddE(P), table, base, empty) +
- cuddZddCountStep(cuddT(P), table, base, empty);
-
- dummy = ALLOC(int, 1);
- if (dummy == NULL) {
- return(CUDD_OUT_OF_MEM);
- }
- *dummy = res;
- if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
- FREE(dummy);
- return(CUDD_OUT_OF_MEM);
- }
-
- return(res);
-
-} /* end of cuddZddCountStep */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddCountDouble.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double
-cuddZddCountDoubleStep(
- DdNode * P,
- st_table * table,
- DdNode * base,
- DdNode * empty)
-{
- double res;
- double *dummy;
-
- if (P == empty)
- return((double)0.0);
- if (P == base)
- return((double)1.0);
-
- /* Check cache */
- if (st_lookup(table, (char *)P, (char **)(&dummy))) {
- res = *dummy;
- return(res);
- }
-
- res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) +
- cuddZddCountDoubleStep(cuddT(P), table, base, empty);
-
- dummy = ALLOC(double, 1);
- if (dummy == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- *dummy = res;
- if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
- FREE(dummy);
- return((double)CUDD_OUT_OF_MEM);
- }
-
- return(res);
-
-} /* end of cuddZddCountDoubleStep */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the memory associated with the computed table of
- Cudd_zddCount.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static enum st_retval
-st_zdd_countfree(
- char * key,
- char * value,
- char * arg)
-{
- int *d;
-
- d = (int *)value;
- FREE(d);
- return(ST_CONTINUE);
-
-} /* end of st_zdd_countfree */
-
-
-/**Function********************************************************************
-
- Synopsis [Frees the memory associated with the computed table of
- Cudd_zddCountDouble.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static enum st_retval
-st_zdd_count_dbl_free(
- char * key,
- char * value,
- char * arg)
-{
- double *d;
-
- d = (double *)value;
- FREE(d);
- return(ST_CONTINUE);
-
-} /* end of st_zdd_count_dbl_free */
diff --git a/src/bdd/cudd/cuddZddFuncs.c b/src/bdd/cudd/cuddZddFuncs.c
deleted file mode 100644
index 9dc27a95..00000000
--- a/src/bdd/cudd/cuddZddFuncs.c
+++ /dev/null
@@ -1,1603 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddFuncs.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the product of two covers represented by ZDDs.]
-
- Description [Computes the product of two covers represented by
- ZDDs. The result is also a ZDD. Returns a pointer to the result if
- successful; NULL otherwise. The covers on which Cudd_zddProduct
- operates use two ZDD variables for each function variable (one ZDD
- variable for each literal of the variable). Those two ZDD variables
- should be adjacent in the order.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddUnateProduct]
-
-******************************************************************************/
-DdNode *
-Cudd_zddProduct(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddProduct(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddProduct */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the product of two unate covers.]
-
- Description [Computes the product of two unate covers represented as
- ZDDs. Unate covers use one ZDD variable for each BDD
- variable. Returns a pointer to the result if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddProduct]
-
-******************************************************************************/
-DdNode *
-Cudd_zddUnateProduct(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddUnateProduct(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddUnateProduct */
-
-
-/**Function********************************************************************
-
- Synopsis [Applies weak division to two covers.]
-
- Description [Applies weak division to two ZDDs representing two
- covers. Returns a pointer to the ZDD representing the result if
- successful; NULL otherwise. The result of weak division depends on
- the variable order. The covers on which Cudd_zddWeakDiv operates use
- two ZDD variables for each function variable (one ZDD variable for
- each literal of the variable). Those two ZDD variables should be
- adjacent in the order.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddDivide]
-
-******************************************************************************/
-DdNode *
-Cudd_zddWeakDiv(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddWeakDiv(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddWeakDiv */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the quotient of two unate covers.]
-
- Description [Computes the quotient of two unate covers represented
- by ZDDs. Unate covers use one ZDD variable for each BDD
- variable. Returns a pointer to the resulting ZDD if successful; NULL
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddWeakDiv]
-
-******************************************************************************/
-DdNode *
-Cudd_zddDivide(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddDivide(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddDivide */
-
-
-/**Function********************************************************************
-
- Synopsis [Modified version of Cudd_zddWeakDiv.]
-
- Description [Modified version of Cudd_zddWeakDiv. This function may
- disappear in future releases.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddWeakDiv]
-
-******************************************************************************/
-DdNode *
-Cudd_zddWeakDivF(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddWeakDivF(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddWeakDivF */
-
-
-/**Function********************************************************************
-
- Synopsis [Modified version of Cudd_zddDivide.]
-
- Description [Modified version of Cudd_zddDivide. This function may
- disappear in future releases.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddDivideF(
- DdManager * dd,
- DdNode * f,
- DdNode * g)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddDivideF(dd, f, g);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddDivideF */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes a complement cover for a ZDD node.]
-
- Description [Computes a complement cover for a ZDD node. For lack of a
- better method, we first extract the function BDD from the ZDD cover,
- then make the complement of the ZDD cover from the complement of the
- BDD node by using ISOP. Returns a pointer to the resulting cover if
- successful; NULL otherwise. The result depends on current variable
- order.]
-
- SideEffects [The result depends on current variable order.]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddComplement(
- DdManager *dd,
- DdNode *node)
-{
- DdNode *b, *isop, *zdd_I;
-
- /* Check cache */
- zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
- if (zdd_I)
- return(zdd_I);
-
- b = Cudd_MakeBddFromZddCover(dd, node);
- if (!b)
- 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_Ref(isop);
- Cudd_Ref(zdd_I);
- Cudd_RecursiveDeref(dd, b);
- Cudd_RecursiveDeref(dd, isop);
-
- cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
- Cudd_Deref(zdd_I);
- return(zdd_I);
-} /* end of Cudd_zddComplement */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddProduct.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddProduct]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (f == zero || g == zero)
- return(zero);
- if (f == one)
- return(g);
- if (g == one)
- return(f);
-
- top_f = dd->permZ[f->index];
- top_g = dd->permZ[g->index];
-
- if (top_f > top_g)
- return(cuddZddProduct(dd, g, f));
-
- /* Check cache */
- r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g);
- if (r)
- return(r);
-
- v = f->index; /* either yi or zi */
- flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
- if (flag == 1)
- 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_Ref(g1);
- Cudd_Ref(g0);
- Cudd_Ref(gd);
- pv = cuddZddGetPosVarIndex(dd, v);
- nv = cuddZddGetNegVarIndex(dd, v);
-
- 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_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_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_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_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_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_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_Ref(N0);
- Cudd_RecursiveDerefZdd(dd, R0);
- Cudd_RecursiveDerefZdd(dd, Rd);
-
- 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_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_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_Ref(term3);
- Cudd_RecursiveDerefZdd(dd, f1);
- Cudd_RecursiveDerefZdd(dd, g1);
- Cudd_RecursiveDerefZdd(dd, fd);
- 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_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_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_Ref(N1);
- Cudd_RecursiveDerefZdd(dd, R1);
- Cudd_RecursiveDerefZdd(dd, N0);
-
- cuddCacheInsert2(dd, cuddZddProduct, f, g, N1);
- Cudd_Deref(N1);
- return(N1);
-
-} /* end of cuddZddProduct */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddUnateProduct.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddUnateProduct]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (f == zero || g == zero)
- return(zero);
- if (f == one)
- return(g);
- if (g == one)
- return(f);
-
- top_f = dd->permZ[f->index];
- top_g = dd->permZ[g->index];
-
- if (top_f > top_g)
- return(cuddZddUnateProduct(dd, g, f));
-
- /* Check cache */
- r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g);
- if (r)
- return(r);
-
- v = f->index; /* either yi or zi */
- flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
- if (flag == 1)
- 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_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_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_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_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_Ref(term4);
- Cudd_RecursiveDerefZdd(dd, f1);
- Cudd_RecursiveDerefZdd(dd, f0);
- Cudd_RecursiveDerefZdd(dd, g1);
- 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_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_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_Ref(r);
- Cudd_RecursiveDerefZdd(dd, sum2);
- Cudd_RecursiveDerefZdd(dd, term4);
-
- cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r);
- Cudd_Deref(r);
- return(r);
-
-} /* end of cuddZddUnateProduct */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddWeakDiv.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddWeakDiv]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (g == one)
- return(f);
- if (f == zero || f == one)
- return(zero);
- if (f == g)
- return(one);
-
- /* Check cache. */
- r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g);
- if (r)
- return(r);
-
- v = g->index;
-
- flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
- if (flag == 1)
- 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_Ref(g1);
- Cudd_Ref(g0);
- Cudd_Ref(gd);
-
- 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);
- }
- else
- 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);
- }
- 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);
- }
- }
- else {
- 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);
- }
-
- if (gd != zero) {
- 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);
- 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);
- }
- }
- else {
- Cudd_RecursiveDerefZdd(dd, fd);
- Cudd_RecursiveDerefZdd(dd, gd);
- }
-
- cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q);
- Cudd_Deref(q);
- return(q);
-
-} /* end of cuddZddWeakDiv */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddWeakDivF.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddWeakDivF]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (g == one)
- return(f);
- if (f == zero || f == one)
- return(zero);
- if (f == g)
- return(one);
-
- /* Check cache. */
- r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g);
- if (r)
- return(r);
-
- top_f = dd->permZ[f->index];
- top_g = dd->permZ[g->index];
- vf = top_f >> 1;
- vg = top_g >> 1;
- 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) {
- 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);
-
- 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);
- 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);
-
- cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
- Cudd_Deref(q);
- return(q);
- }
-
- if (v == top_f)
- v = f->index;
- else
- v = g->index;
-
- flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
- if (flag == 1)
- 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_Ref(g1);
- Cudd_Ref(g0);
- Cudd_Ref(gd);
-
- 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);
- }
- else
- 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);
- }
- 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);
- }
- }
- else {
- 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);
- }
-
- if (gd != zero) {
- 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);
- 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);
- }
- }
- else {
- Cudd_RecursiveDerefZdd(dd, fd);
- Cudd_RecursiveDerefZdd(dd, gd);
- }
-
- cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
- Cudd_Deref(q);
- return(q);
-
-} /* end of cuddZddWeakDivF */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddDivide.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddDivide]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (g == one)
- return(f);
- if (f == zero || f == one)
- return(zero);
- if (f == g)
- return(one);
-
- /* Check cache. */
- r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g);
- if (r)
- return(r);
-
- v = g->index;
-
- flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
- if (flag == 1)
- 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_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);
- }
-
- Cudd_RecursiveDerefZdd(dd, f1);
- Cudd_RecursiveDerefZdd(dd, f0);
- Cudd_RecursiveDerefZdd(dd, g1);
- Cudd_RecursiveDerefZdd(dd, g0);
-
- cuddCacheInsert2(dd, cuddZddDivide, f, g, r);
- Cudd_Deref(r);
- return(r);
-
-} /* end of cuddZddDivide */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddDivideF.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddDivideF]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (g == one)
- return(f);
- if (f == zero || f == one)
- return(zero);
- if (f == g)
- return(one);
-
- /* Check cache. */
- r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g);
- if (r)
- return(r);
-
- v = g->index;
-
- flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
- if (flag == 1)
- 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_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);
- }
-
- Cudd_RecursiveDerefZdd(dd, f1);
- Cudd_RecursiveDerefZdd(dd, f0);
- Cudd_RecursiveDerefZdd(dd, g1);
- Cudd_RecursiveDerefZdd(dd, g0);
-
- cuddCacheInsert2(dd, cuddZddDivideF, f, g, r);
- Cudd_Deref(r);
- return(r);
-
-} /* end of cuddZddDivideF */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the three-way decomposition of f w.r.t. v.]
-
- Description [Computes the three-way decomposition of function f (represented
- by a ZDD) wit respect to variable v.]
-
- SideEffects [The results are returned in f1, f0, and fd.]
-
- SeeAlso [cuddZddGetCofactors2]
-
-******************************************************************************/
-int
-cuddZddGetCofactors3(
- DdManager * dd,
- DdNode * f,
- int v,
- DdNode ** f1,
- DdNode ** f0,
- DdNode ** fd)
-{
- 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];
- hv = level >> 1;
- ht = top >> 1;
-
- if (hv < ht) {
- *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);
- }
- 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);
- }
- return(0);
-
-} /* end of cuddZddGetCofactors3 */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the two-way decomposition of f w.r.t. v.]
-
- Description []
-
- SideEffects [The results are returned in f1 and f0.]
-
- SeeAlso [cuddZddGetCofactors3]
-
-******************************************************************************/
-int
-cuddZddGetCofactors2(
- DdManager * dd,
- DdNode * f,
- int v,
- DdNode ** f1,
- DdNode ** f0)
-{
- *f1 = cuddZddSubset1(dd, f, v);
- if (*f1 == NULL)
- return(1);
- *f0 = cuddZddSubset0(dd, f, v);
- if (*f0 == NULL) {
- Cudd_RecursiveDerefZdd(dd, *f1);
- return(1);
- }
- return(0);
-
-} /* end of cuddZddGetCofactors2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes a complement of a ZDD node.]
-
- Description [Computes the complement of a ZDD node. So far, since we
- couldn't find a direct way to get the complement of a ZDD cover, we first
- convert a ZDD cover to a BDD, then make the complement of the ZDD cover
- from the complement of the BDD node by using ISOP.]
-
- SideEffects [The result depends on current variable order.]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddComplement(
- DdManager * dd,
- DdNode *node)
-{
- DdNode *b, *isop, *zdd_I;
-
- /* Check cache */
- zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
- if (zdd_I)
- return(zdd_I);
-
- b = cuddMakeBddFromZddCover(dd, node);
- if (!b)
- return(NULL);
- cuddRef(b);
- isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
- if (!isop) {
- Cudd_RecursiveDeref(dd, b);
- return(NULL);
- }
- cuddRef(isop);
- cuddRef(zdd_I);
- Cudd_RecursiveDeref(dd, b);
- Cudd_RecursiveDeref(dd, isop);
-
- cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
- cuddDeref(zdd_I);
- return(zdd_I);
-} /* end of cuddZddComplement */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of positive ZDD variable.]
-
- Description [Returns the index of positive ZDD variable.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddGetPosVarIndex(
- DdManager * dd,
- int index)
-{
- int pv = (index >> 1) << 1;
- return(pv);
-} /* end of cuddZddGetPosVarIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of negative ZDD variable.]
-
- Description [Returns the index of negative ZDD variable.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddGetNegVarIndex(
- DdManager * dd,
- int index)
-{
- int nv = index | 0x1;
- return(nv);
-} /* end of cuddZddGetPosVarIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the level of positive ZDD variable.]
-
- Description [Returns the level of positive ZDD variable.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddGetPosVarLevel(
- DdManager * dd,
- int index)
-{
- int pv = cuddZddGetPosVarIndex(dd, index);
- return(dd->permZ[pv]);
-} /* end of cuddZddGetPosVarLevel */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the level of negative ZDD variable.]
-
- Description [Returns the level of negative ZDD variable.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddGetNegVarLevel(
- DdManager * dd,
- int index)
-{
- int nv = cuddZddGetNegVarIndex(dd, index);
- return(dd->permZ[nv]);
-} /* end of cuddZddGetNegVarLevel */
diff --git a/src/bdd/cudd/cuddZddGroup.c b/src/bdd/cudd/cuddZddGroup.c
deleted file mode 100644
index 621fa43f..00000000
--- a/src/bdd/cudd/cuddZddGroup.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddGroup.c]
-
- PackageName [cudd]
-
- 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>]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-static int *entry;
-extern int zddTotalNumberSwapping;
-#ifdef DD_STATS
-static int extsymmcalls;
-static int extsymm;
-static int secdiffcalls;
-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 */
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int zddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method));
-#ifdef DD_STATS
-static int zddCountInternalMtrNodes ARGS((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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Creates a new ZDD variable group.]
-
- Description [Creates a new ZDD variable group. The group starts at
- variable and contains size variables. The parameter low is the index
- of the first variable. If the variable already exists, its current
- position in the order is known to the manager. If the variable does
- not exist yet, the position is assumed to be the same as the index.
- The group tree is created if it does not exist yet.
- Returns a pointer to the group if successful; NULL otherwise.]
-
- SideEffects [The ZDD variable tree is changed.]
-
- SeeAlso [Cudd_MakeTreeNode]
-
-******************************************************************************/
-MtrNode *
-Cudd_MakeZddTreeNode(
- DdManager * dd /* manager */,
- unsigned int low /* index of the first group variable */,
- unsigned int size /* number of variables in the group */,
- unsigned int type /* MTR_DEFAULT or MTR_FIXED */)
-{
- MtrNode *group;
- MtrNode *tree;
- unsigned int level;
-
- /* If the variable does not exist yet, the position is assumed to be
- ** the same as the index. Therefore, applications that rely on
- ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
- ** variables have to create the variables before they group them.
- */
- level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;
-
- if (level + size - 1> (int) MTR_MAXHIGH)
- 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];
- }
-
- /* Extend the upper bound of the tree if necessary. This allows the
- ** application to create groups even before the variables are created.
- */
- tree->size = ddMax(tree->size, level + size);
-
- /* Create the group. */
- group = Mtr_MakeGroup(tree, level, size, type);
- if (group == 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
- ** procedure to provide a handle to the group once it has been moved.
- */
- group->index = (MtrHalfWord) low;
-
- return(group);
-
-} /* end of Cudd_MakeZddTreeNode */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Tree sifting algorithm for ZDDs.]
-
- Description [Tree sifting algorithm for ZDDs. Assumes that a tree
- representing a group hierarchy is passed as a parameter. It then
- reorders each group in postorder fashion by calling
- zddTreeSiftingAux. Assumes that no dead nodes are present. Returns
- 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-int
-cuddZddTreeSifting(
- DdManager * table /* DD table */,
- Cudd_ReorderingType method /* reordering method for the groups of leaves */)
-{
- int i;
- int nvars;
- int result;
- int tempTree;
-
- /* If no tree is provided we create a temporary one in which all
- ** variables are in a single group. After reordering this tree is
- ** destroyed.
- */
- tempTree = table->treeZ == NULL;
- if (tempTree) {
- 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:");
- 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");
- }
- /* End of debugging code. */
-#endif
-#ifdef DD_STATS
- extsymmcalls = 0;
- extsymm = 0;
- secdiffcalls = 0;
- secdiff = 0;
- secdiffmisfire = 0;
-
- (void) fprintf(table->out,"\n");
- if (!tempTree)
- (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
- ** there are no groups. Groups are created according to the tree
- ** structure in postorder fashion.
- */
- for (i = 0; i < nvars; i++)
- table->subtableZ[i].next = i;
-
- /* Reorder. */
- result = zddTreeSiftingAux(table, table->treeZ, method);
-
-#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);
- }
- 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);
- }
-#endif
-
- if (tempTree)
- Cudd_FreeZddTree(table);
- return(result);
-
-} /* end of cuddZddTreeSifting */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Visits the group tree and reorders each group.]
-
- Description [Recursively visits the group tree and reorders each
- group in postorder fashion. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddTreeSiftingAux(
- DdManager * table,
- MtrNode * treenode,
- Cudd_ReorderingType method)
-{
- MtrNode *auxnode;
- int res;
-
-#ifdef DD_DEBUG
- Mtr_PrintGroups(treenode,1);
-#endif
-
- 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;
- }
-
- return(1);
-
-} /* end of zddTreeSiftingAux */
-
-
-#ifdef DD_STATS
-/**Function********************************************************************
-
- Synopsis [Counts the number of internal nodes of the group tree.]
-
- Description [Counts the number of internal nodes of the group tree.
- Returns the count.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddCountInternalMtrNodes(
- DdManager * table,
- MtrNode * treenode)
-{
- MtrNode *auxnode;
- int count,nodeCount;
-
-
- nodeCount = 0;
- auxnode = treenode;
- while (auxnode != NULL) {
- if (!(MTR_TEST(auxnode,MTR_TERMINAL))) {
- nodeCount++;
- count = zddCountInternalMtrNodes(table,auxnode->child);
- nodeCount += count;
- }
- auxnode = auxnode->younger;
- }
-
- return(nodeCount);
-
-} /* end of zddCountInternalMtrNodes */
-#endif
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders the children of a group tree node according to
- the options.]
-
- Description [Reorders the children of a group tree node according to
- the options. After reordering puts all the variables in the group
- and/or its descendents in a single group. This allows hierarchical
- reordering. If the variables in the group do not exist yet, simply
- does nothing. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddReorderChildren(
- DdManager * table,
- MtrNode * treenode,
- Cudd_ReorderingType method)
-{
- int lower;
- int upper;
- int result;
- unsigned int initialSize;
-
- zddFindNodeHiLo(table,treenode,&lower,&upper);
- /* If upper == -1 these variables do not exist yet. */
- if (upper == -1)
- return(1);
-
- if (treenode->flags == MTR_FIXED) {
- result = 1;
- } else {
-#ifdef DD_STATS
- (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)
- break;
-#ifdef DD_STATS
- 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)
- break;
-#ifdef DD_STATS
- else
- (void) fprintf(table->out,"\n");
-#endif
- } while (result != 0);
- break;
- default:
- return(0);
- }
- }
-
- /* Create a single group for all the variables that were sifted,
- ** so that they will be treated as a single block by successive
- ** invocations of zddGroupSifting.
- */
- zddMergeGroups(table,treenode,lower,upper);
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:");
-#endif
-
- return(result);
-
-} /* end of zddReorderChildren */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the lower and upper bounds of the group represented
- by treenode.]
-
- Description [Finds the lower and upper bounds of the group represented
- by treenode. The high and low fields of treenode are indices. From
- those we need to derive the current positions, and find maximum and
- minimum.]
-
- SideEffects [The bounds are returned as side effects.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-zddFindNodeHiLo(
- DdManager * table,
- MtrNode * treenode,
- int * lower,
- int * upper)
-{
- int low;
- int high;
-
- /* Check whether no variables in this group already exist.
- ** If so, return immediately. The calling procedure will know from
- ** the values of upper that no reordering is needed.
- */
- if ((int) treenode->low >= table->sizeZ) {
- *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.
- */
- 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;
- }
-
-#ifdef DD_DEBUG
- /* Make sure that all variables in group are contiguous. */
- assert(treenode->size >= *upper - *lower + 1);
-#endif
-
- return;
-
-} /* end of zddFindNodeHiLo */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the variables
- according to the number of keys in the subtables. Returns the
- difference in number of keys between the two variables being
- compared.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddUniqueCompareGroup(
- int * ptrX,
- int * ptrY)
-{
-#if 0
- if (entry[*ptrY] == entry[*ptrX]) {
- return((*ptrX) - (*ptrY));
- }
-#endif
- return(entry[*ptrY] - entry[*ptrX]);
-
-} /* end of zddUniqueCompareGroup */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts from treenode->low to treenode->high.]
-
- Description [Sifts from treenode->low to treenode->high. If
- croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the
- end of the initial sifting. If a group is created, it is then sifted
- again. After sifting one variable, the group that contains it is
- dissolved. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int *var;
- int i,j,x,xInit;
- int nvars;
- int classes;
- int result;
- int *sifted;
-#ifdef DD_STATS
- unsigned previousSize;
-#endif
- int xindex;
-
- nvars = table->sizeZ;
-
- /* Order variables to sift. */
- entry = NULL;
- sifted = NULL;
- var = ALLOC(int,nvars);
- if (var == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto zddGroupSiftingOutOfMem;
- }
- entry = ALLOC(int,nvars);
- if (entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto zddGroupSiftingOutOfMem;
- }
- sifted = ALLOC(int,nvars);
- if (sifted == NULL) {
- 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++;
- }
- }
-
- qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))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;
- x = table->permZ[xindex]; /* find current level of this variable */
- if (x < lower || x > upper)
- continue;
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
-#ifdef DD_DEBUG
- /* x is bottom of group */
- assert((unsigned) x >= table->subtableZ[x].next);
-#endif
- 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);
-#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);
- }
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:");
-#endif
- } /* for */
-
- FREE(sifted);
- FREE(var);
- FREE(entry);
-
- return(1);
-
-zddGroupSiftingOutOfMem:
- if (entry != NULL) FREE(entry);
- if (var != NULL) FREE(var);
- if (sifted != NULL) FREE(sifted);
-
- return(0);
-
-} /* end of zddGroupSifting */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts one variable up and down until it has taken all
- positions. Checks for aggregation.]
-
- Description [Sifts one variable up and down until it has taken all
- positions. Checks for aggregation. There may be at most two sweeps,
- even if the group grows. Assumes that x is either an isolated
- variable, or it is the bottom of a group. All groups may not have
- been found. The variable being moved is returned to the best position
- seen during sifting. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupSiftingAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
- Move *move;
- Move *moves; /* list of moves */
- int initialSize;
- int result;
-
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh);
- assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */
-#endif
-
- initialSize = table->keysZ;
- moves = NULL;
-
- if (x == xLow) { /* Sift down */
-#ifdef DD_DEBUG
- /* x must be a singleton */
- assert((unsigned) x == table->subtableZ[x].next);
-#endif
- if (x == xHigh) return(1); /* just one variable */
-
- if (!zddGroupSiftingDown(table,x,xHigh,&moves))
- goto zddGroupSiftingAuxOutOfMem;
- /* at this point x == xHigh, unless early term */
-
- /* move backward and stop at best position */
- result = zddGroupSiftingBackward(table,moves,initialSize);
-#ifdef DD_DEBUG
- 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 */
- assert((unsigned) x >= table->subtableZ[x].next);
-#endif
- /* Find top of x's group */
- x = table->subtableZ[x].next;
-
- if (!zddGroupSiftingUp(table,x,xLow,&moves))
- goto zddGroupSiftingAuxOutOfMem;
- /* at this point x == xLow, unless early term */
-
- /* move backward and stop at best position */
- result = zddGroupSiftingBackward(table,moves,initialSize);
-#ifdef DD_DEBUG
- 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 */
-
- /* Find top of group */
- if (moves) {
- x = moves->y;
- }
- while ((unsigned) 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);
-#endif
-
- if (!zddGroupSiftingUp(table,x,xLow,&moves))
- goto zddGroupSiftingAuxOutOfMem;
-
- /* move backward and stop at best position */
- result = zddGroupSiftingBackward(table,moves,initialSize);
-#ifdef DD_DEBUG
- assert(table->keysZ <= (unsigned) initialSize);
-#endif
- if (!result) goto zddGroupSiftingAuxOutOfMem;
-
- } else { /* moving up first: shorter */
- /* Find top of x's group */
- x = table->subtableZ[x].next;
-
- if (!zddGroupSiftingUp(table,x,xLow,&moves))
- goto zddGroupSiftingAuxOutOfMem;
- /* 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;
-#ifdef DD_DEBUG
- /* x is bottom of a group */
- assert((unsigned) x >= table->subtableZ[x].next);
-#endif
-
- if (!zddGroupSiftingDown(table,x,xHigh,&moves))
- goto zddGroupSiftingAuxOutOfMem;
-
- /* move backward and stop at best position */
- result = zddGroupSiftingBackward(table,moves,initialSize);
-#ifdef DD_DEBUG
- assert(table->keysZ <= (unsigned) initialSize);
-#endif
- if (!result) goto zddGroupSiftingAuxOutOfMem;
- }
-
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
-
- return(1);
-
-zddGroupSiftingAuxOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
-
- return(0);
-
-} /* end of zddGroupSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts up a variable until either it reaches position xLow
- or the size of the DD heap increases too much.]
-
- Description [Sifts up a variable until either it reaches position
- xLow or the size of the DD heap increases too much. Assumes that y is
- the top of a group (or a singleton). Checks y for aggregation to the
- adjacent variables. Records all the moves that are appended to the
- list of moves received as input and returned as a side effect.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupSiftingUp(
- DdManager * table,
- int y,
- int xLow,
- Move ** moves)
-{
- Move *move;
- int x;
- int size;
- int gxtop;
- int limitSize;
- int xindex, yindex;
-
- yindex = table->invpermZ[y];
-
- limitSize = table->keysZ;
-
- x = cuddZddNextLow(table,y);
- while (x >= xLow) {
- gxtop = table->subtableZ[x].next;
- if (table->subtableZ[x].next == (unsigned) x &&
- 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);
- assert(table->subtableZ[y].next == (unsigned) y);
-#endif
- if (size == 0) goto zddGroupSiftingUpOutOfMem;
- move = (Move *)cuddDynamicAllocNode(table);
- if (move == NULL) goto zddGroupSiftingUpOutOfMem;
- move->x = x;
- move->y = y;
- 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");
-#endif
- if ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
- } else { /* group move */
- size = zddGroupMove(table,x,y,moves);
- if (size == 0) goto zddGroupSiftingUpOutOfMem;
- if ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
- }
- y = gxtop;
- x = cuddZddNextLow(table,y);
- }
-
- return(1);
-
-zddGroupSiftingUpOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
- return(0);
-
-} /* end of zddGroupSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts down a variable until it reaches position xHigh.]
-
- Description [Sifts down a variable until it reaches position xHigh.
- Assumes that x is the bottom of a group (or a singleton). Records
- all the moves. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupSiftingDown(
- DdManager * table,
- int x,
- int xHigh,
- Move ** moves)
-{
- Move *move;
- int y;
- int size;
- int limitSize;
- int gxtop,gybot;
- int xindex;
-
-
- /* 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. */
- 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) {
- /* x and y are self groups */
- size = cuddZddSwapInPlace(table,x,y);
-#ifdef DD_DEBUG
- assert(table->subtableZ[x].next == (unsigned) x);
- assert(table->subtableZ[y].next == (unsigned) y);
-#endif
- if (size == 0) goto zddGroupSiftingDownOutOfMem;
-
- /* Record move. */
- move = (Move *) cuddDynamicAllocNode(table);
- if (move == NULL) goto zddGroupSiftingDownOutOfMem;
- move->x = x;
- move->y = y;
- move->flags = MTR_DEFAULT;
- move->size = size;
- move->next = *moves;
- *moves = move;
-
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n");
-#endif
- if ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
- x = y;
- y = cuddZddNextHigh(table,x);
- } else { /* Group move */
- size = zddGroupMove(table,x,y,moves);
- if (size == 0) goto zddGroupSiftingDownOutOfMem;
- if ((double) size > (double) limitSize * table->maxGrowth)
- return(1);
- if (size < limitSize) limitSize = size;
- }
- x = gybot;
- y = cuddZddNextHigh(table,x);
- }
-
- return(1);
-
-zddGroupSiftingDownOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
-
- return(0);
-
-} /* end of zddGroupSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two groups and records the move.]
-
- Description [Swaps two groups and records the move. Returns the
- number of keys in the DD table in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupMove(
- DdManager * table,
- int x,
- int y,
- Move ** moves)
-{
- Move *move;
- int size;
- int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
- int swapx,swapy;
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- int initialSize,bestSize;
-#endif
-
-#if DD_DEBUG
- /* We assume that x < y */
- assert(x < y);
-#endif
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtableZ[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) ybot < table->subtableZ[ybot].next)
- ybot = table->subtableZ[ybot].next;
- ytop = y;
- ysize = ybot - ytop + 1;
-
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- initialSize = bestSize = table->keysZ;
-#endif
- /* 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 = cuddZddSwapInPlace(table,x,y);
- if (size == 0) goto zddGroupMoveOutOfMem;
-#if defined(DD_DEBUG) && defined(DD_VERBOSE)
- if (size < bestSize)
- bestSize = size;
-#endif
- swapx = x; swapy = y;
- y = x;
- x = cuddZddNextLow(table,y);
- }
- y = ytop + i;
- x = cuddZddNextLow(table,y);
- }
-#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);
-#endif
-
- /* fix groups */
- y = xtop; /* ytop is now where xtop used to be */
- for (i = 0; i < ysize - 1; i++) {
- table->subtableZ[y].next = cuddZddNextHigh(table,y);
- y = cuddZddNextHigh(table,y);
- }
- table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
- /* it to top of its group */
- x = cuddZddNextHigh(table,y);
- newxtop = x;
- for (i = 0; i < xsize - 1; i++) {
- table->subtableZ[x].next = cuddZddNextHigh(table,x);
- x = cuddZddNextHigh(table,x);
- }
- table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
- /* it to top of its group */
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n");
-#endif
-
- /* Store group move */
- move = (Move *) cuddDynamicAllocNode(table);
- if (move == NULL) goto zddGroupMoveOutOfMem;
- move->x = swapx;
- move->y = swapy;
- move->flags = MTR_DEFAULT;
- move->size = table->keysZ;
- move->next = *moves;
- *moves = move;
-
- return(table->keysZ);
-
-zddGroupMoveOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *) *moves);
- *moves = move;
- }
- return(0);
-
-} /* end of zddGroupMove */
-
-
-/**Function********************************************************************
-
- Synopsis [Undoes the swap two groups.]
-
- Description [Undoes the swap two groups. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupMoveBackward(
- DdManager * table,
- int x,
- int y)
-{
- int size;
- int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
-
-
-#if DD_DEBUG
- /* We assume that x < y */
- assert(x < y);
-#endif
-
- /* Find top, bottom, and size for the two groups. */
- xbot = x;
- xtop = table->subtableZ[x].next;
- xsize = xbot - xtop + 1;
- ybot = y;
- while ((unsigned) ybot < table->subtableZ[ybot].next)
- ybot = table->subtableZ[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 = cuddZddSwapInPlace(table,x,y);
- if (size == 0)
- return(0);
- y = x;
- x = cuddZddNextLow(table,y);
- }
- y = ytop + i;
- x = cuddZddNextLow(table,y);
- }
-
- /* fix groups */
- y = xtop;
- for (i = 0; i < ysize - 1; i++) {
- table->subtableZ[y].next = cuddZddNextHigh(table,y);
- y = cuddZddNextHigh(table,y);
- }
- table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
- /* to its top */
- x = cuddZddNextHigh(table,y);
- newxtop = x;
- for (i = 0; i < xsize - 1; i++) {
- table->subtableZ[x].next = cuddZddNextHigh(table,x);
- x = cuddZddNextHigh(table,x);
- }
- table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
- /* to its top */
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n");
-#endif
-
- return(1);
-
-} /* end of zddGroupMoveBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Determines the best position for a variables and returns
- it there.]
-
- Description [Determines the best position for a variables and returns
- it there. Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddGroupSiftingBackward(
- DdManager * table,
- Move * moves,
- int size)
-{
- Move *move;
- int res;
-
-
- for (move = moves; move != NULL; move = move->next) {
- if (move->size < size) {
- size = move->size;
- }
- }
-
- 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)) {
- res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
- if (!res) return(0);
-#ifdef DD_DEBUG
- if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n");
- assert(table->subtableZ[move->x].next == move->x);
- 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);
- }
- }
-
- return(1);
-
-} /* end of zddGroupSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Merges groups in the DD table.]
-
- Description [Creates a single group from low to high and adjusts the
- idex field of the tree node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-zddMergeGroups(
- DdManager * table,
- MtrNode * treenode,
- int low,
- int high)
-{
- int i;
- MtrNode *auxnode;
- int saveindex;
- int newindex;
-
- /* Merge all variables from low to high in one group, unless
- ** 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;
- }
-
- /* Adjust the index fields of the tree nodes. If a node is the
- ** first child of its parent, then the parent may also need adjustment. */
- saveindex = treenode->index;
- newindex = table->invpermZ[low];
- auxnode = treenode;
- do {
- auxnode->index = newindex;
- if (auxnode->parent == NULL ||
- (int) auxnode->parent->index != saveindex)
- break;
- auxnode = auxnode->parent;
- } while (1);
- return;
-
-} /* end of zddMergeGroups */
-
diff --git a/src/bdd/cudd/cuddZddIsop.c b/src/bdd/cudd/cuddZddIsop.c
deleted file mode 100644
index f4b057ea..00000000
--- a/src/bdd/cudd/cuddZddIsop.c
+++ /dev/null
@@ -1,885 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddIsop.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticEnd***************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Computes an ISOP in ZDD form from BDDs.]
-
- Description [Computes an irredundant sum of products (ISOP) in ZDD
- form from BDDs. The two BDDs L and U represent the lower bound and
- the upper bound, respectively, of the function. The ISOP uses two
- ZDD variables for each BDD variable: One for the positive literal,
- and one for the negative literal. These two variables should be
- adjacent in the ZDD order. The two ZDD variables corresponding to
- BDD variable <code>i</code> should have indices <code>2i</code> and
- <code>2i+1</code>. The result of this procedure depends on the
- variable order. If successful, Cudd_zddIsop returns the BDD for
- the function chosen from the interval. The ZDD representing the
- irredundant cover is returned as a side effect in zdd_I. In case of
- failure, NULL is returned.]
-
- SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on
- successful return.]
-
- SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars]
-
-******************************************************************************/
-DdNode *
-Cudd_zddIsop(
- DdManager * dd,
- DdNode * L,
- DdNode * U,
- DdNode ** zdd_I)
-{
- DdNode *res;
- int autoDynZ;
-
- autoDynZ = dd->autoDynZ;
- dd->autoDynZ = 0;
-
- do {
- dd->reordered = 0;
- res = cuddZddIsop(dd, L, U, zdd_I);
- } while (dd->reordered == 1);
- dd->autoDynZ = autoDynZ;
- return(res);
-
-} /* end of Cudd_zddIsop */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes a BDD in the interval between L and U with a
- simple sum-of-produuct cover.]
-
- Description [Computes a BDD in the interval between L and U with a
- simple sum-of-produuct cover. This procedure is similar to
- Cudd_zddIsop, but it does not return the ZDD for the cover. Returns
- a pointer to the BDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddIsop]
-
-******************************************************************************/
-DdNode *
-Cudd_bddIsop(
- DdManager * dd,
- DdNode * L,
- DdNode * U)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddBddIsop(dd, L, U);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_bddIsop */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a ZDD cover to a BDD graph.]
-
- Description [Converts a ZDD cover to a BDD graph. If successful, it
- returns a BDD node, otherwise it returns NULL.]
-
- SideEffects []
-
- SeeAlso [cuddMakeBddFromZddCover]
-
-******************************************************************************/
-DdNode *
-Cudd_MakeBddFromZddCover(
- DdManager * dd,
- DdNode * node)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddMakeBddFromZddCover(dd, node);
- } while (dd->reordered == 1);
- return(res);
-} /* end of Cudd_MakeBddFromZddCover */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddIsop.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddIsop]
-
-******************************************************************************/
-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 *);
-
- statLine(dd);
- if (L == zero) {
- *zdd_I = zdd_zero;
- return(zero);
- }
- if (U == one) {
- *zdd_I = zdd_one;
- return(one);
- }
-
- if (U == zero || L == one) {
- printf("*** ERROR : illegal condition for ISOP (U < L).\n");
- exit(1);
- }
-
- /* Check the cache. We store two results for each recursive call.
- ** One is the BDD, and the other is the ZDD. Both are needed.
- ** 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;
- 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);
- }
- }
-
- top_l = dd->perm[Cudd_Regular(L)->index];
- top_u = dd->perm[Cudd_Regular(U)->index];
- v = ddMin(top_l, top_u);
-
- /* Compute cofactors. */
- if (top_l == v) {
- index = Cudd_Regular(L)->index;
- Lv = Cudd_T(L);
- Lnv = Cudd_E(L);
- if (Cudd_IsComplement(L)) {
- Lv = Cudd_Not(Lv);
- Lnv = Cudd_Not(Lnv);
- }
- }
- else {
- index = Cudd_Regular(U)->index;
- Lv = Lnv = L;
- }
-
- if (top_u == v) {
- Uv = Cudd_T(U);
- Unv = Cudd_E(U);
- if (Cudd_IsComplement(U)) {
- Uv = Cudd_Not(Uv);
- Unv = Cudd_Not(Unv);
- }
- }
- else {
- Uv = Unv = U;
- }
-
- Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
- if (Lsub0 == 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_Ref(Lsub1);
- Usub1 = Uv;
-
- Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
- if (Isub0 == 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_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);
- }
- /*
- 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_Ref(Isub1);
- Cudd_Ref(zdd_Isub1);
- Cudd_RecursiveDeref(dd, Lsub0);
- Cudd_RecursiveDeref(dd, Lsub1);
-
- 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_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_Ref(Lsuper1);
- Usuper0 = Unv;
- Usuper1 = Uv;
-
- /* 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);
- }
- 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_Ref(Ud);
- Cudd_RecursiveDeref(dd, Lsuper0);
- Cudd_RecursiveDeref(dd, Lsuper1);
-
- 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);
- }
- /*
- 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_Ref(Id);
- Cudd_Ref(zdd_Id);
- Cudd_RecursiveDeref(dd, Ld);
- Cudd_RecursiveDeref(dd, Ud);
-
- 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_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_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_Ref(term1);
- Cudd_RecursiveDeref(dd, x);
- Cudd_RecursiveDeref(dd, Isub1);
- /* 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);
- }
- sum = Cudd_Not(sum);
- Cudd_Ref(sum);
- Cudd_RecursiveDeref(dd, term0);
- Cudd_RecursiveDeref(dd, term1);
- /* r = sum + Id */
- 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_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);
- }
- }
- else {
- 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);
- }
- }
- else
- y = z;
- Cudd_Ref(y);
-
- Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
- Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
- Cudd_RecursiveDerefZdd(dd, zdd_Id);
- Cudd_RecursiveDerefZdd(dd, z);
-
- cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
- cuddCacheInsert2(dd, cacheOp, L, U, y);
-
- Cudd_Deref(r);
- Cudd_Deref(y);
- *zdd_I = y;
- /*
- if (Cudd_Regular(r)->index != y->index / 2) {
- printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
- }
- */
- return(r);
-
-} /* end of cuddZddIsop */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_bddIsop.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddIsop]
-
-******************************************************************************/
-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;
-
- statLine(dd);
- if (L == zero)
- return(zero);
- if (U == one)
- return(one);
-
- /* Check cache */
- r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
- if (r)
- return(r);
-
- top_l = dd->perm[Cudd_Regular(L)->index];
- top_u = dd->perm[Cudd_Regular(U)->index];
- v = ddMin(top_l, top_u);
-
- /* Compute cofactors */
- if (top_l == v) {
- index = Cudd_Regular(L)->index;
- Lv = Cudd_T(L);
- Lnv = Cudd_E(L);
- if (Cudd_IsComplement(L)) {
- Lv = Cudd_Not(Lv);
- Lnv = Cudd_Not(Lnv);
- }
- }
- else {
- index = Cudd_Regular(U)->index;
- Lv = Lnv = L;
- }
-
- if (top_u == v) {
- Uv = Cudd_T(U);
- Unv = Cudd_E(U);
- if (Cudd_IsComplement(U)) {
- Uv = Cudd_Not(Uv);
- Unv = Cudd_Not(Unv);
- }
- }
- else {
- Uv = Unv = U;
- }
-
- Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
- if (Lsub0 == 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_Ref(Lsub1);
- Usub1 = Uv;
-
- Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
- if (Isub0 == 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_Ref(Isub1);
- Cudd_RecursiveDeref(dd, Lsub0);
- Cudd_RecursiveDeref(dd, Lsub1);
-
- Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
- if (Lsuper0 == 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_Ref(Lsuper1);
- Usuper0 = Unv;
- Usuper1 = Uv;
-
- /* Ld = Lsuper0 + Lsuper1 */
- 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_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_Ref(Ud);
- Cudd_RecursiveDeref(dd, Lsuper0);
- Cudd_RecursiveDeref(dd, Lsuper1);
-
- 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_Ref(Id);
- Cudd_RecursiveDeref(dd, Ld);
- Cudd_RecursiveDeref(dd, Ud);
-
- x = cuddUniqueInter(dd, index, one, zero);
- if (x == 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_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_Ref(term1);
- Cudd_RecursiveDeref(dd, x);
- Cudd_RecursiveDeref(dd, Isub1);
- /* sum = term0 + term1 */
- 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_Ref(sum);
- Cudd_RecursiveDeref(dd, term0);
- Cudd_RecursiveDeref(dd, term1);
- /* r = sum + Id */
- 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_Ref(r);
- Cudd_RecursiveDeref(dd, sum);
- Cudd_RecursiveDeref(dd, Id);
-
- cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
-
- Cudd_Deref(r);
- return(r);
-
-} /* end of cuddBddIsop */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a ZDD cover to a BDD graph.]
-
- Description [Converts a ZDD cover to a BDD graph. If successful, it
- returns a BDD node, otherwise it returns NULL. It is a recursive
- algorithm as the following. First computes 3 cofactors of a ZDD cover;
- f1, f0 and fd. Second, compute BDDs(b1, b0 and bd) of f1, f0 and fd.
- Third, compute T=b1+bd and E=b0+bd. Fourth, compute ITE(v,T,E) where v
- is the variable which has the index of the top node of the ZDD cover.
- In this case, since the index of v can be larger than either one of T or
- one of E, cuddUniqueInterIVO is called, here IVO stands for
- independent variable ordering.]
-
- SideEffects []
-
- SeeAlso [Cudd_MakeBddFromZddCover]
-
-******************************************************************************/
-DdNode *
-cuddMakeBddFromZddCover(
- DdManager * dd,
- DdNode * node)
-{
- DdNode *neW;
- int v;
- DdNode *f1, *f0, *fd;
- DdNode *b1, *b0, *bd;
- DdNode *T, *E;
-
- statLine(dd);
- if (node == dd->one)
- return(dd->one);
- if (node == dd->zero)
- return(Cudd_Not(dd->one));
-
- /* Check cache */
- neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
- if (neW)
- return(neW);
-
- v = Cudd_Regular(node)->index; /* either yi or zi */
- cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd);
- 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_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);
- }
- Cudd_Ref(b0);
- Cudd_RecursiveDerefZdd(dd, f1);
- Cudd_RecursiveDerefZdd(dd, f0);
- if (fd != dd->zero) {
- 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);
-
- 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);
- }
- else {
- 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);
- }
- else {
- 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);
- Cudd_RecursiveDeref(dd, E);
-
- cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW);
- Cudd_Deref(neW);
- return(neW);
-
-} /* end of cuddMakeBddFromZddCover */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
diff --git a/src/bdd/cudd/cuddZddLin.c b/src/bdd/cudd/cuddZddLin.c
deleted file mode 100644
index ef2cd298..00000000
--- a/src/bdd/cudd/cuddZddLin.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddLin.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define CUDD_SWAP_MOVE 0
-#define CUDD_LINEAR_TRANSFORM_MOVE 1
-#define CUDD_INVERSE_TRANSFORM_MOVE 2
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-extern int *zdd_entry;
-extern int zddTotalNumberSwapping;
-static int zddTotalNumberLinearTr;
-static DdNode *empty;
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-
-
-/**Function********************************************************************
-
- Synopsis [Implementation of the linear sifting algorithm for ZDDs.]
-
- Description [Implementation of the linear sifting algorithm for ZDDs.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries
- in each unique table.
- <li> Sift the variable up and down and applies the XOR transformation,
- remembering each time the total size of the DD heap.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddLinearSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- size = table->sizeZ;
- empty = table->zero;
-
- /* Find order in which to sift variables. */
- var = NULL;
- zdd_entry = ALLOC(int, size);
- if (zdd_entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddZddSiftingOutOfMem;
- }
- var = ALLOC(int, size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))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;
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
- 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);
-#endif
- }
-
- FREE(var);
- FREE(zdd_entry);
-
- return(1);
-
-cuddZddSiftingOutOfMem:
-
- if (zdd_entry != NULL) FREE(zdd_entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddZddLinearSifting */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Linearly combines two adjacent variables.]
-
- Description [Linearly combines two adjacent variables. It assumes
- that no dead nodes are present on entry to this procedure. The
- procedure then guarantees that no dead nodes will be present when it
- terminates. cuddZddLinearInPlace assumes that x &lt; y. Returns the
- number of keys in the table if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddSwapInPlace cuddLinearInPlace]
-
-******************************************************************************/
-int
-cuddZddLinearInPlace(
- 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 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);
- assert(cuddZddNextHigh(table,x) == y);
- assert(table->subtableZ[x].keys != 0);
- assert(table->subtableZ[y].keys != 0);
- assert(table->subtableZ[x].dead == 0);
- assert(table->subtableZ[y].dead == 0);
-#endif
-
- zddTotalNumberLinearTr++;
-
- /* Get parameters of x subtable. */
- xindex = table->invpermZ[x];
- xlist = table->subtableZ[x].nodelist;
- oldxkeys = table->subtableZ[x].keys;
- xslots = table->subtableZ[x].slots;
- xshift = table->subtableZ[x].shift;
- newxkeys = 0;
-
- /* Get parameters of y subtable. */
- yindex = table->invpermZ[y];
- ylist = table->subtableZ[y].nodelist;
- oldykeys = table->subtableZ[y].keys;
- yslots = table->subtableZ[y].slots;
- yshift = table->subtableZ[y].shift;
- newykeys = oldykeys;
-
- /* The nodes in the x layer are put in two chains. The chain
- ** pointed by g holds the normal nodes. When re-expressed they stay
- ** in the x list. The chain pointed by special holds the elements
- ** that will move to the y list.
- */
- 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 */
- } /* 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 */
- } /* 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;
- }
-
- /* Take care of the remaining x nodes that must be re-expressed.
- ** They form a linked list pointed by g.
- */
- f = g;
- while (f != NULL) {
-#ifdef DD_COUNT
- 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 */
- }
- 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) {
- 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;
-
- /* 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 */
- }
- 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 */
- } /* for i */
-
- /* Set the appropriate fields in table. */
- table->subtableZ[x].keys = newxkeys;
- table->subtableZ[y].keys = newykeys;
-
- table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
-
- /* Update univ section; univ[x] remains the same. */
- table->univ[y] = cuddT(table->univ[x]);
-
-#if 0
- (void) fprintf(table->out,"x = %d y = %d\n", x, y);
- (void) Cudd_DebugCheck(table);
- (void) Cudd_CheckKeys(table);
-#endif
-
- return (table->keysZ);
-
-zddSwapOutOfMem:
- (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
-
- return (0);
-
-} /* end of cuddZddLinearInPlace */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddLinearAux(
- DdManager * table,
- int x,
- int xLow,
- int xHigh)
-{
- Move *move;
- Move *moveUp; /* list of up move */
- Move *moveDown; /* list of down move */
-
- int initial_size;
- int result;
-
- initial_size = table->keysZ;
-
-#ifdef DD_DEBUG
- assert(table->subtableZ[x].keys > 0);
-#endif
-
- moveDown = NULL;
- 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;
-
- } 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;
-
- } 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);
-#ifdef DD_DEBUG
- 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;
-
- } 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);
-#ifdef DD_DEBUG
- 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;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *)moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *)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;
- }
- }
- if (moveUp != (Move *) CUDD_OUT_OF_MEM) {
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *)moveUp);
- moveUp = move;
- }
- }
-
- return(0);
-
-} /* end of cuddZddLinearAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable up applying the XOR transformation.]
-
- Description [Sifts a variable up applying the XOR
- transformation. Moves y up until either it reaches the bound (xLow)
- or the size of the ZDD heap increases too much. Returns the set of
- moves in case of success; NULL if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddLinearUp(
- DdManager * table,
- int y,
- int xLow,
- Move * prevMoves)
-{
- 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;
-#ifdef DD_DEBUG
- 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;
-
- if ((double)size > (double)limitSize * table->maxGrowth)
- break;
- if (size < limitSize)
- limitSize = size;
-
- y = x;
- x = cuddZddNextLow(table, y);
- }
- return(moves);
-
-cuddZddLinearUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *)moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of cuddZddLinearUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable down and applies the XOR transformation.]
-
- Description [Sifts a variable down. Moves x down until either it
- reaches the bound (xHigh) or the size of the ZDD heap increases too
- much. Returns the set of moves in case of success; NULL if memory is
- full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddLinearDown(
- DdManager * table,
- int x,
- int xHigh,
- Move * prevMoves)
-{
- 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);
- }
- } else {
- size = newsize;
- move->flags = CUDD_LINEAR_TRANSFORM_MOVE;
- }
- move->size = size;
-
- if ((double)size > (double)limitSize * table->maxGrowth)
- break;
- if (size < limitSize)
- limitSize = size;
-
- x = y;
- y = cuddZddNextHigh(table, x);
- }
- return(moves);
-
-cuddZddLinearDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *)moves);
- moves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of cuddZddLinearDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the ZDD heap to the position
- giving the minimum size.]
-
- Description [Given a set of moves, returns the ZDD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddLinearBackward(
- DdManager * table,
- int size,
- Move * moves)
-{
- 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;
- }
- }
-
- 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);
- }
- }
-
- return(1);
-
-} /* end of cuddZddLinearBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the ZDD heap to the order
- in effect before the moves.]
-
- Description [Given a set of moves, returns the ZDD heap to the
- order in effect before the moves. Returns 1 in case of success;
- 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static Move*
-cuddZddUndoMoves(
- DdManager * table,
- Move * moves)
-{
- Move *invmoves = NULL;
- Move *move;
- Move *invmove;
- 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 */
-#ifdef DD_DEBUG
- (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;
- }
-
- return(invmoves);
-
-cuddZddUndoMovesOutOfMem:
- while (invmoves != NULL) {
- move = invmoves->next;
- cuddDeallocNode(table, (DdNode *) invmoves);
- invmoves = move;
- }
- return((Move *) CUDD_OUT_OF_MEM);
-
-} /* end of cuddZddUndoMoves */
-
diff --git a/src/bdd/cudd/cuddZddMisc.c b/src/bdd/cudd/cuddZddMisc.c
deleted file mode 100644
index 6a4ddd09..00000000
--- a/src/bdd/cudd/cuddZddMisc.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddMisc.c]
-
- PackageName [cudd]
-
- Synopsis [.]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include <math.h>
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int cuddZddDagInt ARGS((DdNode *n, st_table *tab));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of nodes in a ZDD.]
-
- Description [Counts the number of nodes in a ZDD. This function
- duplicates Cudd_DagSize and is only retained for compatibility.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DagSize]
-
-******************************************************************************/
-int
-Cudd_zddDagSize(
- DdNode * p_node)
-{
-
- int i;
- st_table *table;
-
- table = st_init_table(st_ptrcmp, st_ptrhash);
- i = cuddZddDagInt(p_node, table);
- st_free_table(table);
- return(i);
-
-} /* end of Cudd_zddDagSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms of a ZDD.]
-
- Description [Counts the number of minterms of the ZDD rooted at
- <code>node</code>. This procedure takes a parameter
- <code>path</code> that specifies how many variables are in the
- support of the function. If the procedure runs out of memory, it
- returns (double) CUDD_OUT_OF_MEM.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddCountDouble]
-
-******************************************************************************/
-double
-Cudd_zddCountMinterm(
- DdManager * zdd,
- DdNode * node,
- int path)
-{
- double dc_var, minterms;
-
- dc_var = (double)((double)(zdd->sizeZ) - (double)path);
- minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var);
- return(minterms);
-
-} /* end of Cudd_zddCountMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the ZDD table.]
-
- Description [Prints the ZDD table for debugging purposes.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_zddPrintSubtable(
- DdManager * table)
-{
- 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,
-#if SIZEOF_VOID_P == 8
- "ID = 0x%lx\tindex = %d\tr = %d\t",
- (unsigned long) z1 / (unsigned long) sizeof(DdNode),
- z1->index, z1->ref);
-#else
- "ID = 0x%x\tindex = %d\tr = %d\t",
- (unsigned) z1 / (unsigned) 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 {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(table->out, "T = 0x%lx\t",
- (unsigned long) z1_next / (unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(table->out, "T = 0x%x\t",
- (unsigned) z1_next / (unsigned) sizeof(DdNode));
-#endif
- }
- 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));
-#else
- (void) fprintf(table->out, "E = 0x%x\n",
- (unsigned) z1_next / (unsigned) sizeof(DdNode));
-#endif
- }
-
- z1_next = z1->next;
- z1 = z1_next;
- }
- }
- }
- putchar('\n');
-
-} /* Cudd_zddPrintSubtable */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddDagSize.]
-
- Description [Performs the recursive step of Cudd_zddDagSize. Does
- not check for out-of-memory conditions.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddDagInt(
- DdNode * n,
- st_table * tab)
-{
- if (n == NIL(DdNode))
- return(0);
-
- if (st_is_member(tab, (char *)n) == 1)
- return(0);
-
- if (Cudd_IsConstant(n))
- return(0);
-
- (void)st_insert(tab, (char *)n, NIL(char));
- return(1 + cuddZddDagInt(cuddT(n), tab) +
- cuddZddDagInt(cuddE(n), tab));
-
-} /* cuddZddDagInt */
-
diff --git a/src/bdd/cudd/cuddZddPort.c b/src/bdd/cudd/cuddZddPort.c
deleted file mode 100644
index 6d4a3236..00000000
--- a/src/bdd/cudd/cuddZddPort.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddPort.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * zddPortFromBddStep ARGS((DdManager *dd, DdNode *B, int expected));
-static DdNode * zddPortToBddStep ARGS((DdManager *dd, DdNode *f, int depth));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a BDD into a ZDD.]
-
- Description [Converts a BDD into a ZDD. This function assumes that
- there is a one-to-one correspondence between the BDD variables and the
- ZDD variables, and that the variable order is the same for both types
- of variables. These conditions are established if the ZDD variables
- are created by one call to Cudd_zddVarsFromBddVars with multiplicity =
- 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddVarsFromBddVars]
-
-******************************************************************************/
-DdNode *
-Cudd_zddPortFromBdd(
- DdManager * dd,
- DdNode * B)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = zddPortFromBddStep(dd,B,0);
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_zddPortFromBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a ZDD into a BDD.]
-
- Description [Converts a ZDD into a BDD. Returns a pointer to the resulting
- ZDD if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddPortFromBdd]
-
-******************************************************************************/
-DdNode *
-Cudd_zddPortToBdd(
- DdManager * dd,
- DdNode * f)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = zddPortToBddStep(dd,f,0);
- } while (dd->reordered == 1);
-
- return(res);
-
-} /* end of Cudd_zddPortToBdd */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddPortFromBdd.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-zddPortFromBddStep(
- DdManager * dd,
- DdNode * B,
- int expected)
-{
- 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));
- if (B == DD_ONE(dd)) {
- if (expected >= dd->sizeZ) {
- return(DD_ONE(dd));
- } else {
- return(dd->univ[expected]);
- }
- }
-
- Breg = Cudd_Regular(B);
-
- /* 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);
- }
- cuddDeref(res);
- }
- return(res);
- } /* end of cache look-up */
-
- if (Cudd_IsComplement(B)) {
- Bt = Cudd_Not(cuddT(Breg));
- Be = Cudd_Not(cuddE(Breg));
- } else {
- Bt = cuddT(Breg);
- Be = cuddE(Breg);
- }
-
- id = Breg->index;
- level = cuddI(dd,id);
- t = zddPortFromBddStep(dd, Bt, level+1);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = zddPortFromBddStep(dd, Be, level+1);
- if (e == 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);
- }
- cuddRef(res);
- Cudd_RecursiveDerefZdd(dd, t);
- Cudd_RecursiveDerefZdd(dd, e);
-
- 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) {
- Cudd_RecursiveDerefZdd(dd, prevZdd);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDerefZdd(dd, prevZdd);
- }
-
- cuddDeref(res);
- return(res);
-
-} /* end of zddPortFromBddStep */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddPortToBdd.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-zddPortToBddStep(
- DdManager * dd /* manager */,
- DdNode * f /* ZDD to be converted */,
- int depth /* recursion depth */)
-{
- DdNode *one, *zero, *T, *E, *res, *var;
- unsigned int index;
- unsigned int level;
-
- statLine(dd);
- one = DD_ONE(dd);
- zero = DD_ZERO(dd);
- if (f == zero) return(Cudd_Not(one));
-
- if (depth == dd->sizeZ) return(one);
-
- index = dd->invpermZ[depth];
- level = cuddIZ(dd,f->index);
- var = cuddUniqueInter(dd,index,one,Cudd_Not(one));
- if (var == NULL) return(NULL);
- 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) {
- Cudd_RecursiveDeref(dd,var);
- Cudd_RecursiveDeref(dd,E);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd,var);
- Cudd_RecursiveDeref(dd,E);
- cuddDeref(res);
- return(res);
- }
-
- res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f);
- if (res != NULL) {
- Cudd_RecursiveDeref(dd,var);
- return(res);
- }
-
- T = zddPortToBddStep(dd,cuddT(f),depth+1);
- if (T == 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);
- }
- 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);
- }
- cuddRef(res);
- Cudd_RecursiveDeref(dd,var);
- Cudd_RecursiveDeref(dd,T);
- Cudd_RecursiveDeref(dd,E);
- cuddDeref(res);
-
- cuddCacheInsert1(dd,Cudd_zddPortToBdd,f,res);
-
- return(res);
-
-} /* end of zddPortToBddStep */
-
diff --git a/src/bdd/cudd/cuddZddReord.c b/src/bdd/cudd/cuddZddReord.c
deleted file mode 100644
index e2da37f2..00000000
--- a/src/bdd/cudd/cuddZddReord.c
+++ /dev/null
@@ -1,1633 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddReord.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_MAX_SUBTABLE_SPARSITY 8
-#define DD_SHRINK_FACTOR 2
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-int *zdd_entry;
-
-int zddTotalNumberSwapping;
-
-static DdNode *empty;
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Main dynamic reordering routine for ZDDs.]
-
- Description [Main dynamic reordering routine for ZDDs.
- Calls one of the possible reordering procedures:
- <ul>
- <li>Swapping
- <li>Sifting
- <li>Symmetric Sifting
- </ul>
-
- For sifting and symmetric sifting it is possible to request reordering
- to convergence.<p>
-
- The core of all methods is the reordering procedure
- cuddZddSwapInPlace() which swaps two adjacent variables.
- Returns 1 in case of success; 0 otherwise. In the case of symmetric
- sifting (with and without convergence) returns 1 plus the number of
- symmetric variables, in case of success.]
-
- SideEffects [Changes the variable order for all ZDDs and clears
- the cache.]
-
-******************************************************************************/
-int
-Cudd_zddReduceHeap(
- DdManager * table /* DD manager */,
- Cudd_ReorderingType heuristic /* method used for reordering */,
- int minsize /* bound below which no reordering occurs */)
-{
- DdHook *hook;
- int result;
- unsigned int nextDyn;
-#ifdef DD_STATS
- unsigned int initialSize;
- unsigned int finalSize;
-#endif
- long localTime;
-
- /* Don't reorder if there are too many dead nodes. */
- if (table->keysZ - table->deadZ < (unsigned) minsize)
- return(1);
-
- if (heuristic == CUDD_REORDER_SAME) {
- heuristic = table->autoMethodZ;
- }
- if (heuristic == CUDD_REORDER_NONE) {
- return(1);
- }
-
- /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore
- ** we count it.
- */
- table->reorderings++;
- empty = table->zero;
-
- localTime = util_cpu_time();
-
- /* 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;
- }
-
- /* Clear the cache and collect garbage. */
- zddReorderPreprocess(table);
- zddTotalNumberSwapping = 0;
-
-#ifdef DD_STATS
- initialSize = table->keysZ;
-
- switch(heuristic) {
- case CUDD_REORDER_RANDOM:
- case CUDD_REORDER_RANDOM_PIVOT:
- (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;
- case CUDD_REORDER_LINEAR:
- case CUDD_REORDER_LINEAR_CONVERGE:
- (void) fprintf(table->out,"#:I_LINSIFT ");
- break;
- default:
- (void) fprintf(table->err,"Unsupported ZDD reordering method\n");
- return(0);
- }
- (void) fprintf(table->out,"%8d: initial size",initialSize);
-#endif
-
- result = cuddZddTreeSifting(table,heuristic);
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
- 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));
- (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
- zddTotalNumberSwapping);
-#endif
-
- if (result == 0)
- return(0);
-
- if (!zddReorderPostprocess(table))
- return(0);
-
- if (table->realignZ) {
- if (!cuddBddAlignToZdd(table))
- return(0);
- }
-
- nextDyn = table->keysZ * DD_DYN_RATIO;
- if (table->reorderings < 20 || nextDyn > table->nextDyn)
- table->nextDyn = nextDyn;
- else
- 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;
- }
- /* Update cumulative reordering time. */
- table->reordTime += util_cpu_time() - localTime;
-
- return(result);
-
-} /* end of Cudd_zddReduceHeap */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders ZDD variables according to given permutation.]
-
- Description [Reorders ZDD variables according to given permutation.
- The i-th entry of the permutation array contains the index of the variable
- that should be brought to the i-th level. The size of the array should be
- equal or greater to the number of variables currently in use.
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [Changes the ZDD variable order for all diagrams and clears
- the cache.]
-
- SeeAlso [Cudd_zddReduceHeap]
-
-******************************************************************************/
-int
-Cudd_zddShuffleHeap(
- DdManager * table /* DD manager */,
- int * permutation /* required variable permutation */)
-{
-
- int result;
-
- empty = table->zero;
- zddReorderPreprocess(table);
-
- result = zddShuffle(table,permutation);
-
- if (!zddReorderPostprocess(table)) return(0);
-
- return(result);
-
-} /* end of Cudd_zddShuffleHeap */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders ZDD variables according to the order of the BDD
- variables.]
-
- Description [Reorders ZDD variables according to the order of the
- BDD variables. This function can be called at the end of BDD
- reordering to insure that the order of the ZDD variables is
- consistent with the order of the BDD variables. The number of ZDD
- variables must be a multiple of the number of BDD variables. Let
- <code>M</code> be the ratio of the two numbers. cuddZddAlignToBdd
- then considers the ZDD variables from <code>M*i</code> to
- <code>(M+1)*i-1</code> as corresponding to BDD variable
- <code>i</code>. This function should be normally called from
- Cudd_ReduceHeap, which clears the cache. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [Changes the ZDD variable order for all diagrams and performs
- garbage collection of the ZDD unique table.]
-
- SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap]
-
-******************************************************************************/
-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 */
-
- /* We assume that a ratio of 0 is OK. */
- if (table->sizeZ == 0)
- return(1);
-
- empty = table->zero;
- 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);
- /* Create and initialize the inverse permutation array. */
- invpermZ = ALLOC(int,table->sizeZ);
- if (invpermZ == NULL) {
- 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];
- }
- }
- /* Eliminate dead nodes. Do not scan the cache again, because we
- ** assume that Cudd_ReduceHeap has already cleared it.
- */
- cuddGarbageCollectZdd(table,0);
-
- result = zddShuffle(table, invpermZ);
- FREE(invpermZ);
- /* Fix the ZDD variable group tree. */
- zddFixTree(table,table->treeZ);
- return(result);
-
-} /* end of cuddZddAlignToBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the next subtable with a larger index.]
-
- Description [Finds the next subtable with a larger index. Returns the
- index.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddNextHigh(
- DdManager * table,
- int x)
-{
- return(x + 1);
-
-} /* end of cuddZddNextHigh */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the next subtable with a smaller index.]
-
- Description [Finds the next subtable with a smaller index. Returns the
- index.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddNextLow(
- DdManager * table,
- int x)
-{
- return(x - 1);
-
-} /* end of cuddZddNextLow */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function used by qsort.]
-
- Description [Comparison function used by qsort to order the
- variables according to the number of keys in the subtables.
- Returns the difference in number of keys between the two
- variables being compared.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddUniqueCompare(
- int * ptr_x,
- int * ptr_y)
-{
- return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]);
-
-} /* end of cuddZddUniqueCompare */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two adjacent variables.]
-
- Description [Swaps two adjacent variables. It assumes that no dead
- nodes are present on entry to this procedure. The procedure then
- guarantees that no dead nodes will be present when it terminates.
- cuddZddSwapInPlace assumes that x &lt; y. Returns the number of keys in
- the table if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddSwapInPlace(
- 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 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);
- assert(cuddZddNextHigh(table,x) == y);
- assert(table->subtableZ[x].keys != 0);
- assert(table->subtableZ[y].keys != 0);
- assert(table->subtableZ[x].dead == 0);
- assert(table->subtableZ[y].dead == 0);
-#endif
-
- zddTotalNumberSwapping++;
-
- /* Get parameters of x subtable. */
- xindex = table->invpermZ[x];
- xlist = table->subtableZ[x].nodelist;
- oldxkeys = table->subtableZ[x].keys;
- xslots = table->subtableZ[x].slots;
- xshift = table->subtableZ[x].shift;
- newxkeys = 0;
-
- yindex = table->invpermZ[y];
- ylist = table->subtableZ[y].nodelist;
- oldykeys = table->subtableZ[y].keys;
- yslots = table->subtableZ[y].slots;
- yshift = table->subtableZ[y].shift;
- newykeys = oldykeys;
-
- /* The nodes in the x layer that don't depend on y directly
- ** will stay there; the others 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;
- 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;
- } /* for each slot of the x subtable */
- *lastP = NULL;
-
-
-#ifdef DD_COUNT
- 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
- ** changed to yindex already.
- */
- 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);
- }
- /* 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) {
- 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;
-
- /* 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;
- } /* for i */
-
- /* Set the appropriate fields in table. */
- table->subtableZ[x].nodelist = ylist;
- table->subtableZ[x].slots = yslots;
- table->subtableZ[x].shift = yshift;
- table->subtableZ[x].keys = newykeys;
- table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
-
- table->subtableZ[y].nodelist = xlist;
- table->subtableZ[y].slots = xslots;
- table->subtableZ[y].shift = xshift;
- table->subtableZ[y].keys = newxkeys;
- table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
-
- table->permZ[xindex] = y; table->permZ[yindex] = x;
- table->invpermZ[x] = yindex; table->invpermZ[y] = xindex;
-
- table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
-
- /* Update univ section; univ[x] remains the same. */
- table->univ[y] = cuddT(table->univ[x]);
-
- return (table->keysZ);
-
-zddSwapOutOfMem:
- (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
-
- return (0);
-
-} /* end of cuddZddSwapInPlace */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]
-
- Description [Implementation of Plessier's algorithm that reorders
- variables by a sequence of (non-adjacent) swaps.
- <ol>
- <li> Select two variables (RANDOM or HEURISTIC).
- <li> Permute these variables.
- <li> If the nodes have decreased accept the permutation.
- <li> Otherwise reconstruct the original heap.
- <li> Loop.
- </ol>
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddSwapping(
- DdManager * table,
- int lower,
- int upper,
- Cudd_ReorderingType heuristic)
-{
- int i, j;
- int max, keys;
- int nvars;
- int x, y;
- int iterate;
- int previousSize;
- Move *moves, *move;
- int pivot;
- int modulo;
- int result;
-
-#ifdef DD_DEBUG
- /* Sanity check */
- assert(lower >= 0 && upper < table->sizeZ && lower <= upper);
-#endif
-
- nvars = upper - lower + 1;
- 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;
- } 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 {
- 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;
-
- result = cuddZddSiftingBackward(table, moves, previousSize);
- if (!result)
- goto cuddZddSwappingOutOfMem;
-
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) 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);
-#endif
- }
-
- return(1);
-
-cuddZddSwappingOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *) moves);
- moves = move;
- }
- return(0);
-
-} /* end of cuddZddSwapping */
-
-
-/**Function********************************************************************
-
- Synopsis [Implementation of Rudell's sifting algorithm.]
-
- Description [Implementation of Rudell's sifting algorithm.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries
- in each unique table.
- <li> Sift the variable up and down, remembering each time the
- total size of the DD heap.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int size;
- int x;
- int result;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- size = table->sizeZ;
-
- /* Find order in which to sift variables. */
- var = NULL;
- zdd_entry = ALLOC(int, size);
- if (zdd_entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddZddSiftingOutOfMem;
- }
- var = ALLOC(int, size);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))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;
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
- 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);
-#endif
- }
-
- FREE(var);
- FREE(zdd_entry);
-
- return(1);
-
-cuddZddSiftingOutOfMem:
-
- if (zdd_entry != NULL) FREE(zdd_entry);
- if (var != NULL) FREE(var);
-
- return(0);
-
-} /* end of cuddZddSifting */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps any two variables.]
-
- Description [Swaps any two variables. Returns the set of moves.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-zddSwapAny(
- DdManager * table,
- 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;
- }
-
- x_ref = x; y_ref = y;
-
- x_next = cuddZddNextHigh(table, x);
- y_next = cuddZddNextLow(table, y);
- moves = NULL;
- 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;
-
- 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;
- }
-
- 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;
- }
- return(NULL);
-
-} /* end of zddSwapAny */
-
-
-/**Function********************************************************************
-
- Synopsis [Given xLow <= x <= xHigh moves x up and down between the
- boundaries.]
-
- Description [Given xLow <= x <= xHigh moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddSiftingAux(
- DdManager * table,
- int x,
- int x_low,
- int x_high)
-{
- Move *move;
- Move *moveUp; /* list of up move */
- Move *moveDown; /* list of down move */
-
- int initial_size;
- int result;
-
- initial_size = table->keysZ;
-
-#ifdef DD_DEBUG
- assert(table->subtableZ[x].keys > 0);
-#endif
-
- moveDown = NULL;
- 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;
-
- }
- 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;
- }
- 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;
- }
- 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;
- }
-
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *)moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *)moveUp);
- moveUp = move;
- }
-
- return(1);
-
-cuddZddSiftingAuxOutOfMem:
- while (moveDown != NULL) {
- move = moveDown->next;
- cuddDeallocNode(table, (DdNode *)moveDown);
- moveDown = move;
- }
- while (moveUp != NULL) {
- move = moveUp->next;
- cuddDeallocNode(table, (DdNode *)moveUp);
- moveUp = move;
- }
-
- return(0);
-
-} /* end of cuddZddSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable up.]
-
- Description [Sifts a variable up. Moves y up until either it reaches
- the bound (x_low) or the size of the ZDD heap increases too much.
- Returns the set of moves in case of success; NULL if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddSiftingUp(
- DdManager * table,
- int x,
- int x_low,
- int 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;
- if (size < limit_size)
- limit_size = size;
-
- x = y;
- y = cuddZddNextLow(table, x);
- }
- return(moves);
-
-cuddZddSiftingUpOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *)moves);
- moves = move;
- }
- return(NULL);
-
-} /* end of cuddZddSiftingUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Sifts a variable down.]
-
- Description [Sifts a variable down. Moves x down until either it
- reaches the bound (x_high) or the size of the ZDD heap increases too
- much. Returns the set of moves in case of success; NULL if memory is
- full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddSiftingDown(
- DdManager * table,
- int x,
- int x_high,
- int 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;
- if (size < limit_size)
- limit_size = size;
-
- x = y;
- y = cuddZddNextHigh(table, x);
- }
- return(moves);
-
-cuddZddSiftingDownOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *)moves);
- moves = move;
- }
- return(NULL);
-
-} /* end of cuddZddSiftingDown */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the ZDD heap to the position
- giving the minimum size.]
-
- Description [Given a set of moves, returns the ZDD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddSiftingBackward(
- DdManager * table,
- Move * moves,
- int size)
-{
- 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;
- }
- }
-
- 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;
- }
-
- return(1);
-
-} /* end of cuddZddSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Prepares the ZDD heap for dynamic reordering.]
-
- Description [Prepares the ZDD heap for dynamic reordering. Does
- garbage collection, to guarantee that there are no dead nodes;
- and clears the cache, which is invalidated by dynamic reordering.]
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-zddReorderPreprocess(
- DdManager * table)
-{
-
- /* Clear the cache. */
- cuddCacheFlush(table);
-
- /* Eliminate dead nodes. Do not scan the cache again. */
- cuddGarbageCollectZdd(table,0);
-
- return;
-
-} /* end of ddReorderPreprocess */
-
-
-/**Function********************************************************************
-
- Synopsis [Shrinks almost empty ZDD subtables at the end of reordering
- to guarantee that they have a reasonable load factor.]
-
- Description [Shrinks almost empty subtables at the end of reordering to
- guarantee that they have a reasonable load factor. However, if there many
- nodes are being reclaimed, then no resizing occurs. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
-******************************************************************************/
-static int
-zddReorderPostprocess(
- DdManager * table)
-{
- int i, j, posn;
- DdNodePtr *nodelist, *oldnodelist;
- DdNode *node, *next;
- unsigned int slots, oldslots;
- extern void (*MMoutOfMemory)(long);
- void (*saveHandler)(long);
-
-#ifdef DD_VERBOSE
- (void) fflush(table->out);
-#endif
-
- /* If we have very many reclaimed nodes, we do not want to shrink
- ** the subtables, because this will lead to more garbage
- ** collections. More garbage collections mean shorter mean life for
- ** nodes with zero reference count; hence lower probability of finding
- ** a result in the cache.
- */
- if (table->reclaimed > table->allocated * 0.5) return(1);
-
- /* 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 = 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);
-#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;
- }
- }
- 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.
- */
-
- return(1);
-
-} /* end of zddReorderPostprocess */
-
-
-/**Function********************************************************************
-
- Synopsis [Reorders ZDD variables according to a given permutation.]
-
- Description [Reorders ZDD variables according to a given permutation.
- The i-th permutation array contains the index of the variable that
- should be brought to the i-th level. zddShuffle assumes that no
- dead nodes are present. The reordering is achieved by a series of
- upward sifts. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-zddShuffle(
- DdManager * table,
- int * permutation)
-{
- int index;
- int level;
- int position;
- int numvars;
- int result;
-#ifdef DD_STATS
- long localTime;
- int initialSize;
- int finalSize;
- int previousSize;
-#endif
-
- zddTotalNumberSwapping = 0;
-#ifdef DD_STATS
- localTime = util_cpu_time();
- initialSize = table->keysZ;
- (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n",
- initialSize);
-#endif
-
- numvars = table->sizeZ;
-
- for (level = 0; level < numvars; level++) {
- index = permutation[level];
- position = table->permZ[index];
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
- 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);
-#endif
- }
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
- 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));
- (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n",
- zddTotalNumberSwapping);
-#endif
-
- return(1);
-
-} /* end of zddShuffle */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves one ZDD variable up.]
-
- Description [Takes a ZDD variable from position x and sifts it up to
- position xLow; xLow should be less than or equal to x.
- Returns 1 if successful; 0 otherwise]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-zddSiftUp(
- DdManager * table,
- int x,
- int xLow)
-{
- int y;
- int size;
-
- y = cuddZddNextLow(table,x);
- while (y >= xLow) {
- size = cuddZddSwapInPlace(table,y,x);
- if (size == 0) {
- return(0);
- }
- x = y;
- y = cuddZddNextLow(table,x);
- }
- return(1);
-
-} /* end of zddSiftUp */
-
-
-/**Function********************************************************************
-
- Synopsis [Fixes the ZDD variable group tree after a shuffle.]
-
- Description [Fixes the ZDD variable group tree after a
- shuffle. Assumes that the order of the variables in a terminal node
- has not been changed.]
-
- SideEffects [Changes the ZDD variable group tree.]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-zddFixTree(
- DdManager * table,
- MtrNode * treenode)
-{
- if (treenode == NULL) return;
- treenode->low = ((int) treenode->index < table->sizeZ) ?
- table->permZ[treenode->index] : treenode->index;
- if (treenode->child != NULL) {
- zddFixTree(table, treenode->child);
- }
- if (treenode->younger != NULL)
- zddFixTree(table, treenode->younger);
- if (treenode->parent != NULL && treenode->low < treenode->parent->low) {
- treenode->parent->low = treenode->low;
- treenode->parent->index = treenode->index;
- }
- return;
-
-} /* end of zddFixTree */
-
diff --git a/src/bdd/cudd/cuddZddSetop.c b/src/bdd/cudd/cuddZddSetop.c
deleted file mode 100644
index f1bd72f3..00000000
--- a/src/bdd/cudd/cuddZddSetop.c
+++ /dev/null
@@ -1,1137 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddSetop.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the ITE of three ZDDs.]
-
- Description [Computes the ITE of three ZDDs. Returns a pointer to the
- result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddIte(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddIte(dd, f, g, h);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddIte */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the union of two ZDDs.]
-
- Description [Computes the union of two ZDDs. Returns a pointer to the
- result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddUnion(
- DdManager * dd,
- DdNode * P,
- DdNode * Q)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddUnion(dd, P, Q);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddUnion */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the intersection of two ZDDs.]
-
- Description [Computes the intersection of two ZDDs. Returns a pointer to
- the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddIntersect(
- DdManager * dd,
- DdNode * P,
- DdNode * Q)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddIntersect(dd, P, Q);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddIntersect */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the difference of two ZDDs.]
-
- Description [Computes the difference of two ZDDs. Returns a pointer to the
- result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddDiffConst]
-
-******************************************************************************/
-DdNode *
-Cudd_zddDiff(
- DdManager * dd,
- DdNode * P,
- DdNode * Q)
-{
- DdNode *res;
-
- do {
- dd->reordered = 0;
- res = cuddZddDiff(dd, P, Q);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddDiff */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the inclusion test for ZDDs (P implies Q).]
-
- Description [Inclusion test for ZDDs (P implies Q). No new nodes are
- generated by this procedure. Returns empty if true;
- a valid pointer different from empty or DD_NON_CONSTANT otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddDiff]
-
-******************************************************************************/
-DdNode *
-Cudd_zddDiffConst(
- DdManager * zdd,
- DdNode * P,
- DdNode * Q)
-{
- int p_top, q_top;
- DdNode *empty = DD_ZERO(zdd), *t, *res;
- DdManager *table = zdd;
-
- statLine(zdd);
- if (P == empty)
- return(empty);
- if (Q == empty)
- return(P);
- if (P == Q)
- return(empty);
-
- /* Check cache. The cache is shared by cuddZddDiff(). */
- res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
- if (res != NULL)
- return(res);
-
- if (cuddIsConstant(P))
- p_top = P->index;
- else
- p_top = zdd->permZ[P->index];
- if (cuddIsConstant(Q))
- q_top = Q->index;
- else
- q_top = zdd->permZ[Q->index];
- if (p_top < q_top) {
- res = DD_NON_CONSTANT;
- } else if (p_top > q_top) {
- 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));
- }
-
- cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
-
- return(res);
-
-} /* end of Cudd_zddDiffConst */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]
-
- Description [Computes the positive cofactor of a ZDD w.r.t. a
- variable. In terms of combinations, the result is the set of all
- combinations in which the variable is asserted. Returns a pointer to
- the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddSubset0]
-
-******************************************************************************/
-DdNode *
-Cudd_zddSubset1(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- DdNode *r;
-
- do {
- dd->reordered = 0;
- r = cuddZddSubset1(dd, P, var);
- } while (dd->reordered == 1);
-
- return(r);
-
-} /* end of Cudd_zddSubset1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]
-
- Description [Computes the negative cofactor of a ZDD w.r.t. a
- variable. In terms of combinations, the result is the set of all
- combinations in which the variable is negated. Returns a pointer to
- the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddSubset1]
-
-******************************************************************************/
-DdNode *
-Cudd_zddSubset0(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- DdNode *r;
-
- do {
- dd->reordered = 0;
- r = cuddZddSubset0(dd, P, var);
- } while (dd->reordered == 1);
-
- return(r);
-
-} /* end of Cudd_zddSubset0 */
-
-
-/**Function********************************************************************
-
- Synopsis [Substitutes a variable with its complement in a ZDD.]
-
- Description [Substitutes a variable with its complement in a ZDD.
- returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Cudd_zddChange(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- DdNode *res;
-
- if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL);
-
- do {
- dd->reordered = 0;
- res = cuddZddChange(dd, P, var);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Cudd_zddChange */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddIte.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddIte(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- DdNode * h)
-{
- DdNode *tautology, *empty;
- DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e;
- unsigned int topf,topg,toph,v,top;
- int index;
-
- statLine(dd);
- /* Trivial cases. */
- /* One variable cases. */
- if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
- return(h);
- }
- topf = cuddIZ(dd,f->index);
- topg = cuddIZ(dd,g->index);
- toph = cuddIZ(dd,h->index);
- v = ddMin(topg,toph);
- top = ddMin(topf,v);
-
- tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top];
- if (f == tautology) { /* ITE(1,G,H) = G */
- return(g);
- }
-
- /* From now on, f is known to not be a constant. */
- zddVarToConst(f,&g,&h,tautology,empty);
-
- /* Check remaining one variable cases. */
- if (g == h) { /* ITE(F,G,G) = G */
- return(g);
- }
-
- 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);
- }
-
- /* Recompute these because they may have changed in zddVarToConst. */
- topg = cuddIZ(dd,g->index);
- toph = cuddIZ(dd,h->index);
- v = ddMin(topg,toph);
-
- if (topf < v) {
- 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;
- } 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);
-
- return(r);
-
-} /* end of cuddZddIte */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddUnion.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddUnion(
- DdManager * zdd,
- DdNode * P,
- DdNode * Q)
-{
- int p_top, q_top;
- DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
- DdManager *table = zdd;
-
- statLine(zdd);
- if (P == empty)
- return(Q);
- if (Q == empty)
- return(P);
- if (P == Q)
- return(P);
-
- /* Check cache */
- res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q);
- if (res != NULL)
- return(res);
-
- if (cuddIsConstant(P))
- p_top = P->index;
- else
- p_top = zdd->permZ[P->index];
- if (cuddIsConstant(Q))
- q_top = Q->index;
- else
- 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);
- } 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);
- } 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);
- }
-
- cuddCacheInsert2(table, cuddZddUnion, P, Q, res);
-
- return(res);
-
-} /* end of cuddZddUnion */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddIntersect.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddIntersect(
- DdManager * zdd,
- DdNode * P,
- DdNode * Q)
-{
- int p_top, q_top;
- DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
- DdManager *table = zdd;
-
- statLine(zdd);
- if (P == empty)
- return(empty);
- if (Q == empty)
- return(empty);
- if (P == Q)
- return(P);
-
- /* Check cache. */
- res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q);
- if (res != NULL)
- return(res);
-
- if (cuddIsConstant(P))
- p_top = P->index;
- else
- p_top = zdd->permZ[P->index];
- if (cuddIsConstant(Q))
- q_top = Q->index;
- else
- q_top = zdd->permZ[Q->index];
- if (p_top < q_top) {
- 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);
- } 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);
- }
-
- cuddCacheInsert2(table, cuddZddIntersect, P, Q, res);
-
- return(res);
-
-} /* end of cuddZddIntersect */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddDiff.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddDiff(
- DdManager * zdd,
- DdNode * P,
- DdNode * Q)
-{
- int p_top, q_top;
- DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
- DdManager *table = zdd;
-
- statLine(zdd);
- if (P == empty)
- return(empty);
- if (Q == empty)
- return(P);
- if (P == Q)
- 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);
-
- if (cuddIsConstant(P))
- p_top = P->index;
- else
- p_top = zdd->permZ[P->index];
- if (cuddIsConstant(Q))
- q_top = Q->index;
- else
- 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);
- } else if (p_top > q_top) {
- 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);
- }
-
- cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
-
- return(res);
-
-} /* end of cuddZddDiff */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddChange.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-cuddZddChangeAux(
- DdManager * zdd,
- DdNode * P,
- DdNode * zvar)
-{
- 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);
- if (P == base)
- return(zvar);
-
- /* Check cache. */
- res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar);
- if (res != NULL)
- 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);
- } else if (top_var == level) {
- 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);
- }
-
- cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res);
-
- return(res);
-
-} /* end of cuddZddChangeAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]
-
- Description [Computes the positive cofactor of a ZDD w.r.t. a
- variable. In terms of combinations, the result is the set of all
- combinations in which the variable is asserted. Returns a pointer to
- the result if successful; NULL otherwise. cuddZddSubset1 performs
- the same function as Cudd_zddSubset1, but does not restart if
- reordering has taken place. Therefore it can be called from within a
- recursive procedure.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddSubset0 Cudd_zddSubset1]
-
-******************************************************************************/
-DdNode *
-cuddZddSubset1(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- 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);
- } else {
- cuddRef(zvar);
- r = zdd_subset1_aux(dd, P, zvar);
- if (r == NULL) {
- Cudd_RecursiveDerefZdd(dd, zvar);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDerefZdd(dd, zvar);
- }
-
- cuddDeref(r);
- return(r);
-
-} /* end of cuddZddSubset1 */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]
-
- Description [Computes the negative cofactor of a ZDD w.r.t. a
- variable. In terms of combinations, the result is the set of all
- combinations in which the variable is negated. Returns a pointer to
- the result if successful; NULL otherwise. cuddZddSubset0 performs
- the same function as Cudd_zddSubset0, but does not restart if
- reordering has taken place. Therefore it can be called from within a
- recursive procedure.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddSubset1 Cudd_zddSubset0]
-
-******************************************************************************/
-DdNode *
-cuddZddSubset0(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- 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);
- } else {
- cuddRef(zvar);
- r = zdd_subset0_aux(dd, P, zvar);
- if (r == NULL) {
- Cudd_RecursiveDerefZdd(dd, zvar);
- return(NULL);
- }
- cuddRef(r);
- Cudd_RecursiveDerefZdd(dd, zvar);
- }
-
- cuddDeref(r);
- return(r);
-
-} /* end of cuddZddSubset0 */
-
-
-/**Function********************************************************************
-
- Synopsis [Substitutes a variable with its complement in a ZDD.]
-
- Description [Substitutes a variable with its complement in a ZDD.
- returns a pointer to the result if successful; NULL
- otherwise. cuddZddChange performs the same function as
- Cudd_zddChange, but does not restart if reordering has taken
- place. Therefore it can be called from within a recursive
- procedure.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddChange]
-
-******************************************************************************/
-DdNode *
-cuddZddChange(
- DdManager * dd,
- DdNode * P,
- int var)
-{
- DdNode *zvar, *res;
-
- zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd));
- if (zvar == NULL) return(NULL);
- cuddRef(zvar);
-
- res = cuddZddChangeAux(dd, P, zvar);
- if (res == NULL) {
- Cudd_RecursiveDerefZdd(dd,zvar);
- return(NULL);
- }
- cuddRef(res);
- Cudd_RecursiveDerefZdd(dd,zvar);
- cuddDeref(res);
- return(res);
-
-} /* end of cuddZddChange */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddSubset1.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-zdd_subset1_aux(
- DdManager * zdd,
- DdNode * P,
- DdNode * zvar)
-{
- int top_var, level;
- DdNode *res, *t, *e;
- DdNode *base, *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);
-
- if (cuddIsConstant(P)) {
- res = empty;
- cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res);
- return(res);
- }
-
- top_var = zdd->permZ[P->index];
- level = zdd->permZ[zvar->index];
-
- if (top_var > level) {
- res = empty;
- } else if (top_var == level) {
- res = cuddT(P);
- } else {
- t = zdd_subset1_aux(zdd, cuddT(P), zvar);
- 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);
- 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, zdd_subset1_aux, P, zvar, res);
-
- return(res);
-
-} /* end of zdd_subset1_aux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddSubset0.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static DdNode *
-zdd_subset0_aux(
- DdManager * zdd,
- DdNode * P,
- DdNode * zvar)
-{
- int top_var, level;
- DdNode *res, *t, *e;
- DdNode *base, *empty;
-
- 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);
-
- if (cuddIsConstant(P)) {
- res = P;
- cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res);
- return(res);
- }
-
- top_var = zdd->permZ[P->index];
- level = zdd->permZ[zvar->index];
-
- if (top_var > level) {
- res = P;
- }
- else if (top_var == level) {
- res = cuddE(P);
- }
- else {
- t = zdd_subset0_aux(zdd, cuddT(P), zvar);
- 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);
- 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, zdd_subset0_aux, P, zvar, res);
-
- return(res);
-
-} /* end of zdd_subset0_aux */
-
-
-/**Function********************************************************************
-
- Synopsis [Replaces variables with constants if possible (part of
- canonical form).]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-zddVarToConst(
- DdNode * f,
- DdNode ** gp,
- DdNode ** hp,
- DdNode * base,
- DdNode * empty)
-{
- DdNode *g = *gp;
- DdNode *h = *hp;
-
- if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
- *gp = base;
- }
-
- if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
- *hp = empty;
- }
-
-} /* end of zddVarToConst */
-
diff --git a/src/bdd/cudd/cuddZddSymm.c b/src/bdd/cudd/cuddZddSymm.c
deleted file mode 100644
index 54019892..00000000
--- a/src/bdd/cudd/cuddZddSymm.c
+++ /dev/null
@@ -1,1677 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddSymm.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define ZDD_MV_OOM (Move *)1
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-extern int *zdd_entry;
-
-extern int zddTotalNumberSwapping;
-
-static DdNode *empty;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints statistics on symmetric ZDD variables.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_zddSymmProfile(
- DdManager * table,
- int lower,
- int upper)
-{
- int i, x, gbot;
- int TotalSymm = 0;
- int TotalSymmGroups = 0;
- int nvars;
-
- nvars = table->sizeZ;
-
- 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++;
-#ifdef DD_DEBUG
- assert(table->subtableZ[gbot].next == (unsigned) i);
-#endif
- 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);
-
-} /* end of Cudd_zddSymmProfile */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Checks for symmetry of x and y.]
-
- Description [Checks for symmetry of x and y. Ignores projection
- functions, unless they are isolated. Returns 1 in case of
- symmetry; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddZddSymmCheck(
- DdManager * table,
- 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;
-
- 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 */
- } /* 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;
- }
- }
-
- 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);
- }
-#endif
-
- return(symm_found);
-
-} /* end cuddZddSymmCheck */
-
-
-/**Function********************************************************************
-
- Synopsis [Symmetric sifting algorithm for ZDDs.]
-
- Description [Symmetric sifting algorithm.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries in
- each unique subtable.
- <li> Sift the variable up and down, remembering each time the total
- size of the ZDD heap and grouping variables that are symmetric.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- </ol>
- Returns 1 plus the number of symmetric variables if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddSymmSiftingConv]
-
-******************************************************************************/
-int
-cuddZddSymmSifting(
- DdManager * table,
- int lower,
- int upper)
-{
- int i;
- int *var;
- int nvars;
- int x;
- int result;
- int symvars;
- int symgroups;
- int iteration;
-#ifdef DD_STATS
- int previousSize;
-#endif
-
- nvars = table->sizeZ;
-
- /* Find order in which to sift variables. */
- var = NULL;
- zdd_entry = ALLOC(int, nvars);
- if (zdd_entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddZddSymmSiftingOutOfMem;
- }
- var = ALLOC(int, nvars);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare);
-
- /* Initialize the symmetry of each subtable to itself. */
- for (i = lower; i <= upper; 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]];
-#ifdef DD_STATS
- 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;
-#ifdef DD_STATS
- 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]);
-#endif
- } else {
- (void) fprintf(table->out,"=");
- }
- fflush(table->out);
-#endif
- }
- }
-
- FREE(var);
- FREE(zdd_entry);
-
- cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars);
- (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups);
-#endif
-
- return(1+symvars);
-
-cuddZddSymmSiftingOutOfMem:
-
- if (zdd_entry != NULL)
- FREE(zdd_entry);
- if (var != NULL)
- FREE(var);
-
- return(0);
-
-} /* end of cuddZddSymmSifting */
-
-
-/**Function********************************************************************
-
- Synopsis [Symmetric sifting to convergence algorithm for ZDDs.]
-
- Description [Symmetric sifting to convergence algorithm for ZDDs.
- Assumes that no dead nodes are present.
- <ol>
- <li> Order all the variables according to the number of entries in
- each unique subtable.
- <li> Sift the variable up and down, remembering each time the total
- size of the ZDD heap and grouping variables that are symmetric.
- <li> Select the best permutation.
- <li> Repeat 3 and 4 for all variables.
- <li> Repeat 1-4 until no further improvement.
- </ol>
- Returns 1 plus the number of symmetric variables if successful; 0
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [cuddZddSymmSifting]
-
-******************************************************************************/
-int
-cuddZddSymmSiftingConv(
- DdManager * table,
- int lower,
- int upper)
-{
- 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
-
- initialSize = table->keysZ;
-
- nvars = table->sizeZ;
-
- /* Find order in which to sift variables. */
- var = NULL;
- zdd_entry = ALLOC(int, nvars);
- if (zdd_entry == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- goto cuddZddSymmSiftingConvOutOfMem;
- }
- var = ALLOC(int, nvars);
- if (var == NULL) {
- 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;
- }
-
- qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))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;
-
- 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) {
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
- 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,"+");
-#ifdef DD_VERBOSE
- (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);
-#endif
- }
- }
-
- /* Sifting now until convergence. */
- while ((unsigned) initialSize > table->keysZ) {
- initialSize = table->keysZ;
-#ifdef DD_STATS
- (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;
- }
-
- qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))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) {
-#ifdef DD_STATS
- previousSize = table->keysZ;
-#endif
- 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,"+");
-#ifdef DD_VERBOSE
- (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);
-#endif
- }
- } /* for */
- }
-
- cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
-
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",
- symvars);
- (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",
- symgroups);
-#endif
-
- FREE(var);
- FREE(zdd_entry);
-
- return(1+symvars);
-
-cuddZddSymmSiftingConvOutOfMem:
-
- if (zdd_entry != NULL)
- FREE(zdd_entry);
- if (var != NULL)
- FREE(var);
-
- return(0);
-
-} /* end of cuddZddSymmSiftingConv */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Given x_low <= x <= x_high moves x up and down between the
- boundaries.]
-
- Description [Given x_low <= x <= x_high moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Assumes that x is not part of a symmetry group. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddSymmSiftingAux(
- DdManager * table,
- int x,
- 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 topbot; /* index to either top or bottom of symmetry group */
- int init_group_size, final_group_size;
-
- initial_size = table->keysZ;
-
- move_down = NULL;
- move_up = NULL;
-
- /* Look for consecutive symmetries above x. */
- for (i = x; i > x_low; 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 */
- }
- /* Look for consecutive symmetries below x. */
- for (i = x; i < x_high; i++) {
- 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 */
- }
-
- /* 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;
-
- 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;
-
- 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 {
- result = cuddZddSymmSiftingBackward(table, move_down,
- initial_size);
- /* move backward and stop at best position */
- }
- 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)
- 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);
- /* 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)
- 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);
- }
- else {
- 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;
- }
- 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;
-
- 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);
- }
- 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 */
- }
- if (!result)
- goto cuddZddSymmSiftingAuxOutOfMem;
- }
- else { /* moving up first:shorter */
- /* Find top of x's symmetry group */
- while ((unsigned) 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;
-
- 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;
- }
- 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;
- 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 */
- }
- if (!result)
- goto cuddZddSymmSiftingAuxOutOfMem;
- }
-
- while (move_down != NULL) {
- move = move_down->next;
- cuddDeallocNode(table, (DdNode *)move_down);
- move_down = move;
- }
- while (move_up != NULL) {
- move = move_up->next;
- cuddDeallocNode(table, (DdNode *)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;
- }
- }
- if (move_up != ZDD_MV_OOM) {
- while (move_up != NULL) {
- move = move_up->next;
- cuddDeallocNode(table, (DdNode *)move_up);
- move_up = move;
- }
- }
-
- return(0);
-
-} /* end of cuddZddSymmSiftingAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Given x_low <= x <= x_high moves x up and down between the
- boundaries.]
-
- Description [Given x_low <= x <= x_high moves x up and down between the
- boundaries. Finds the best position and does the required changes.
- Assumes that x is either an isolated variable, or it is the bottom of
- a symmetry group. All symmetries may not have been found, because of
- exceeded growth limit. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddSymmSiftingConvAux(
- DdManager * table,
- int x,
- 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;
-
- initial_size = table->keysZ;
-
- move_down = NULL;
- move_up = NULL;
-
- 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;
-
- 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 {
- result = cuddZddSymmSiftingBackward(table, move_down,
- initial_size);
- /* move backward and stop at best position */
- }
- 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)
- 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);
- /* 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)
- 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);
- }
- else {
- 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 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;
-
- 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);
- }
- 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 */
- }
- if (!result)
- goto cuddZddSymmSiftingConvAuxOutOfMem;
- }
- else { /* moving up first:shorter */
- /* 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;
-
- 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;
-
- 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 {
- 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 */
- }
- if (!result)
- goto cuddZddSymmSiftingConvAuxOutOfMem;
- }
-
- while (move_down != NULL) {
- move = move_down->next;
- cuddDeallocNode(table, (DdNode *)move_down);
- move_down = move;
- }
- while (move_up != NULL) {
- move = move_up->next;
- cuddDeallocNode(table, (DdNode *)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;
- }
- }
- if (move_up != ZDD_MV_OOM) {
- while (move_up != NULL) {
- move = move_up->next;
- cuddDeallocNode(table, (DdNode *)move_up);
- move_up = move;
- }
- }
-
- return(0);
-
-} /* end of cuddZddSymmSiftingConvAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves x up until either it reaches the bound (x_low) or
- the size of the ZDD heap increases too much.]
-
- Description [Moves x up until either it reaches the bound (x_low) or
- the size of the ZDD heap increases too much. Assumes that x is the top
- of a symmetry group. Checks x for symmetry to the adjacent
- variables. If symmetry is found, the symmetry group of x is merged
- with the symmetry group of the other variable. Returns the set of
- moves in case of success; ZDD_MV_OOM if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddSymmSifting_up(
- DdManager * table,
- int x,
- int x_low,
- int initial_size)
-{
- 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);
- }
-
- return(moves);
-
-cuddZddSymmSifting_upOutOfMem:
- while (moves != NULL) {
- move = moves->next;
- cuddDeallocNode(table, (DdNode *)moves);
- moves = move;
- }
- return(ZDD_MV_OOM);
-
-} /* end of cuddZddSymmSifting_up */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves x down until either it reaches the bound (x_high) or
- the size of the ZDD heap increases too much.]
-
- Description [Moves x down until either it reaches the bound (x_high)
- or the size of the ZDD heap increases too much. Assumes that x is the
- bottom of a symmetry group. Checks x for symmetry to the adjacent
- variables. If symmetry is found, the symmetry group of x is merged
- with the symmetry group of the other variable. Returns the set of
- moves in case of success; ZDD_MV_OOM if memory is full.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static Move *
-cuddZddSymmSifting_down(
- DdManager * table,
- int x,
- int x_high,
- int initial_size)
-{
- 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;
- 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;
- }
- return(ZDD_MV_OOM);
-
-} /* end of cuddZddSymmSifting_down */
-
-
-/**Function********************************************************************
-
- Synopsis [Given a set of moves, returns the ZDD heap to the position
- giving the minimum size.]
-
- Description [Given a set of moves, returns the ZDD heap to the
- position giving the minimum size. In case of ties, returns to the
- closest position giving the minimum size. Returns 1 in case of
- success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-cuddZddSymmSiftingBackward(
- DdManager * table,
- Move * moves,
- int size)
-{
- 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;
- }
- }
-
- 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;
- }
-
- return(1);
-
-} /* end of cuddZddSymmSiftingBackward */
-
-
-/**Function********************************************************************
-
- Synopsis [Swaps two groups.]
-
- Description [Swaps two groups. x is assumed to be the bottom variable
- of the first group. y is assumed to be the top variable of the second
- group. Updates the list of moves. Returns the number of keys in the
- table if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-zdd_group_move(
- DdManager * table,
- int x,
- int y,
- Move ** moves)
-{
- Move *move;
- int size;
- int i, temp, gxtop, gxbot, gytop, gybot, yprev;
- int swapx, swapy;
-
-#ifdef DD_DEBUG
- 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;
- 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;
- }
-
- 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;
- 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;
- }
-
- yprev = gxtop;
- gxtop++;
- gxbot++;
- x = gxbot;
- } /* while x <= y, end of group movement */
- move = (Move *)cuddDynamicAllocNode(table);
- if (move == NULL)
- goto zdd_group_moveOutOfMem;
- move->x = swapx;
- move->y = swapy;
- move->size = table->keysZ;
- move->next = *moves;
- *moves = move;
-
- return(table->keysZ);
-
-zdd_group_moveOutOfMem:
- while (*moves != NULL) {
- move = (*moves)->next;
- cuddDeallocNode(table, (DdNode *)(*moves));
- *moves = move;
- }
- return(0);
-
-} /* end of zdd_group_move */
-
-
-/**Function********************************************************************
-
- Synopsis [Undoes the swap of two groups.]
-
- Description [Undoes the swap of two groups. x is assumed to be the
- bottom variable of the first group. y is assumed to be the top
- variable of the second group. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-zdd_group_move_backward(
- DdManager * table,
- int x,
- int y)
-{
- int size;
- int i, temp, gxtop, gxbot, gytop, gybot, yprev;
-
-#ifdef DD_DEBUG
- 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;
- 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;
- }
-
- 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 {
- y = table->subtableZ[y].next;
- }
-
- yprev = gxtop;
- gxtop++;
- gxbot++;
- x = gxbot;
- } /* while x <= y, end of group movement backward */
-
- return(size);
-
-} /* end of zdd_group_move_backward */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts numbers of symmetric variables and symmetry
- groups.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-cuddZddSymmSummary(
- DdManager * table,
- int lower,
- int upper,
- int * symvars,
- int * symgroups)
-{
- int i,x,gbot;
- int TotalSymm = 0;
- 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);
-#ifdef DD_DEBUG
- assert(table->subtableZ[gbot].next == (unsigned) i);
-#endif
- i = gbot;
- }
- }
- *symvars = TotalSymm;
- *symgroups = TotalSymmGroups;
-
- return;
-
-} /* end of cuddZddSymmSummary */
-
diff --git a/src/bdd/cudd/cuddZddUtil.c b/src/bdd/cudd/cuddZddUtil.c
deleted file mode 100644
index 616d16d4..00000000
--- a/src/bdd/cudd/cuddZddUtil.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddZddUtil.c]
-
- PackageName [cudd]
-
- 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>
- ]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a disjoint sum of product form for a ZDD.]
-
- Description [Prints a disjoint sum of product form for a ZDD. Returns 1
- if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover]
-
-******************************************************************************/
-int
-Cudd_zddPrintMinterm(
- DdManager * zdd,
- DdNode * node)
-{
- int i, size;
- int *list;
-
- size = (int)zdd->sizeZ;
- list = ALLOC(int, size);
- if (list == NULL) {
- 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);
- FREE(list);
- return(1);
-
-} /* end of Cudd_zddPrintMinterm */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a sum of products from a ZDD representing a cover.]
-
- Description [Prints a sum of products from a ZDD representing a cover.
- Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddPrintMinterm]
-
-******************************************************************************/
-int
-Cudd_zddPrintCover(
- DdManager * zdd,
- DdNode * node)
-{
- int i, size;
- int *list;
-
- size = (int)zdd->sizeZ;
- if (size % 2 != 0) return(0); /* number of variables should be even */
- list = ALLOC(int, size);
- if (list == NULL) {
- 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);
- FREE(list);
- return(1);
-
-} /* end of Cudd_zddPrintCover */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints to the standard output a ZDD and its statistics.]
-
- Description [Prints to the standard output a DD and its statistics.
- The statistics include the number of nodes and the number of minterms.
- (The number of minterms is also the number of combinations in the set.)
- The statistics are printed if pr &gt; 0. Specifically:
- <ul>
- <li> pr = 0 : prints nothing
- <li> pr = 1 : prints counts of nodes and minterms
- <li> pr = 2 : prints counts + disjoint sum of products
- <li> pr = 3 : prints counts + list of nodes
- <li> pr &gt; 3 : prints counts + disjoint sum of products + list of nodes
- </ul>
- Returns 1 if successful; 0 otherwise.
- ]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-Cudd_zddPrintDebug(
- DdManager * zdd,
- DdNode * f,
- int n,
- int pr)
-{
- 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);
- }
-
- 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);
- }
- return(retval);
-
-} /* end of Cudd_zddPrintDebug */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the first path of a ZDD.]
-
- Description [Defines an iterator on the paths of a ZDD
- and finds its first path. Returns a generator that contains the
- information necessary to continue the enumeration if successful; NULL
- otherwise.<p>
- A path is represented as an array of literals, which are integers in
- {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc
- out of a node, and 2 stands for the absence of a node.
- The size of the array equals the number of variables in the manager at
- the time Cudd_zddFirstCube is called.<p>
- The paths that end in the empty terminal are not enumerated.]
-
- SideEffects [The first path is returned as a side effect.]
-
- SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree
- Cudd_IsGenEmpty]
-
-******************************************************************************/
-DdGen *
-Cudd_zddFirstPath(
- DdManager * zdd,
- DdNode * f,
- int ** path)
-{
- DdGen *gen;
- DdNode *top, *next, *prev;
- int i;
- int nvars;
-
- /* Sanity Check. */
- if (zdd == NULL || f == NULL) return(NULL);
-
- /* Allocate generator an initialize it. */
- gen = ALLOC(DdGen,1);
- if (gen == NULL) {
- zdd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
-
- gen->manager = zdd;
- gen->type = CUDD_GEN_ZDD_PATHS;
- gen->status = CUDD_GEN_EMPTY;
- gen->gen.cubes.cube = NULL;
- gen->gen.cubes.value = DD_ZERO_VAL;
- gen->stack.sp = 0;
- gen->stack.stack = NULL;
- gen->node = NULL;
-
- nvars = zdd->sizeZ;
- gen->gen.cubes.cube = ALLOC(int,nvars);
- if (gen->gen.cubes.cube == NULL) {
- zdd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
-
- /* The maximum stack depth is one plus the number of variables.
- ** because a path may have nodes at all levels, including the
- ** constant level.
- */
- gen->stack.stack = ALLOC(DdNode *, nvars+1);
- if (gen->stack.stack == NULL) {
- zdd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen->gen.cubes.cube);
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
-
- /* Find the first path of the ZDD. */
- 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];
- }
- } else {
- gen->status = CUDD_GEN_NONEMPTY;
- gen->gen.cubes.value = cuddV(top);
- goto done;
- }
- }
-
-done:
- *path = gen->gen.cubes.cube;
- return(gen);
-
-} /* end of Cudd_zddFirstPath */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates the next path of a ZDD.]
-
- Description [Generates the next path of a ZDD onset,
- using generator gen. Returns 0 if the enumeration is completed; 1
- otherwise.]
-
- SideEffects [The path is returned as a side effect. The
- generator is modified.]
-
- SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree
- Cudd_IsGenEmpty]
-
-******************************************************************************/
-int
-Cudd_zddNextPath(
- DdGen * gen,
- int ** path)
-{
- DdNode *top, *next, *prev;
- DdManager *zdd = gen->manager;
-
- /* 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];
- 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(top);
- goto done;
- }
- }
-
-done:
- if (gen->status == CUDD_GEN_EMPTY) return(0);
- *path = gen->gen.cubes.cube;
- return(1);
-
-} /* end of Cudd_zddNextPath */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a path of a ZDD representing a cover to a string.]
-
- Description [Converts a path of a ZDD representing a cover to a
- string. The string represents an implicant of the cover. The path
- is typically produced by Cudd_zddForeachPath. Returns a pointer to
- the string if successful; NULL otherwise. If the str input is NULL,
- it allocates a new string. The string passed to this function must
- have enough room for all variables and for the terminator.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddForeachPath]
-
-******************************************************************************/
-char *
-Cudd_zddCoverPathToString(
- 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;
- int i;
- char *res;
-
- if (nvars & 1) return(NULL);
- nvars >>= 1;
- if (str == NULL) {
- res = ALLOC(char, nvars+1);
- if (res == NULL) return(NULL);
- } else {
- 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] = '?';
- }
- }
- res[nvars] = 0;
-
- return(res);
-
-} /* end of Cudd_zddCoverPathToString */
-
-
-/**Function********************************************************************
-
- Synopsis [Writes a dot file representing the argument ZDDs.]
-
- Description [Writes a file representing the argument ZDDs in a format
- suitable for the graph drawing program dot.
- It returns 1 in case of success; 0 otherwise (e.g., out-of-memory,
- file system full).
- Cudd_zddDumpDot does not close the file: This is the caller
- responsibility. Cudd_zddDumpDot uses a minimal unique subset of the
- hexadecimal address of a node as name for it.
- If the argument inames is non-null, it is assumed to hold the pointers
- to the names of the inputs. Similarly for onames.
- Cudd_zddDumpDot uses the following convention to draw arcs:
- <ul>
- <li> solid line: THEN arcs;
- <li> dashed line: ELSE arcs.
- </ul>
- The dot options are chosen so that the drawing fits on a letter-size
- sheet.
- ]
-
- SideEffects [None]
-
- SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug]
-
-******************************************************************************/
-int
-Cudd_zddDumpDot(
- DdManager * dd /* manager */,
- int n /* number of output nodes to be dumped */,
- 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 */)
-{
- 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;
-
- /* Build a bit array with the support of f. */
- sorted = ALLOC(int,nvars);
- if (sorted == NULL) {
- 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 = NULL; /* so that we do not try to free it in case of failure */
-
- /* Initialize symbol table for visited nodes. */
- visited = st_init_table(st_ptrcmp, st_ptrhash);
- if (visited == NULL) goto failure;
-
- /* 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;
- }
-
- /* Find how many most significant hex digits are identical
- ** in the addresses of all the nodes. Build a mask based
- ** on this knowledge, so that digits that carry no information
- ** will not be printed. This is done in two steps.
- ** 1. We scan the symbol table to find the bits that differ
- ** in at least 2 addresses.
- ** 2. We choose one of the possible masks. There are 8 possible
- ** masks for 32-bit integer, and 16 possible masks for 64-bit
- ** integers.
- */
-
- /* Find the bits that are different. */
- refAddr = (long) f[0];
- diff = 0;
- gen = st_init_gen(visited);
- while (st_gen(gen, (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;
- }
-
- /* 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");
- if (retval == EOF) return(0);
-
- /* Write the input name subgraph by scanning the support array. */
- retval = fprintf(fp,"{ node [shape = plaintext];\n");
- if (retval == EOF) goto failure;
- retval = fprintf(fp," edge [style = invis];\n");
- if (retval == EOF) goto failure;
- /* We use a name ("CONST NODES") with an embedded blank, because
- ** it is unlikely to appear as an input name.
- */
- retval = fprintf(fp," \"CONST NODES\" [style = invis];\n");
- 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 (retval == EOF) goto failure;
- }
- }
- retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
- if (retval == EOF) goto failure;
-
- /* Write the output node subgraph. */
- 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;
- }
-
- /* 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]]);
- }
- 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 (retval == EOF) goto failure;
- }
- scan = scan->next;
- }
- }
- 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]; ");
- 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 = scan->next;
- }
- }
- retval = fprintf(fp,"}\n}\n");
- if (retval == EOF) goto failure;
-
- /* 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;
- }
-
- /* 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;
- }
- 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 = scan->next;
- }
- }
-
- /* Write trailer and return. */
- retval = fprintf(fp,"}\n");
- if (retval == EOF) goto failure;
-
- st_free_table(visited);
- FREE(sorted);
- return(1);
-
-failure:
- if (sorted != NULL) FREE(sorted);
- if (support != NULL) Cudd_RecursiveDeref(dd,support);
- if (visited != NULL) st_free_table(visited);
- return(0);
-
-} /* end of Cudd_zddDumpBlif */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints a ZDD to the standard output. One line per node is
- printed.]
-
- Description [Prints a ZDD to the standard output. One line per node is
- printed. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_zddPrintDebug]
-
-******************************************************************************/
-int
-cuddZddP(
- DdManager * zdd,
- DdNode * f)
-{
- int retval;
- st_table *table = st_init_table(st_ptrcmp, st_ptrhash);
-
- if (table == NULL) return(0);
-
- retval = zp2(zdd, f, table);
- st_free_table(table);
- (void) fputc('\n', zdd->out);
- return(retval);
-
-} /* end of cuddZddP */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of cuddZddP.]
-
- Description [Performs the recursive step of cuddZddP. Returns 1 in
- case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-zp2(
- DdManager * zdd,
- DdNode * f,
- st_table * t)
-{
- DdNode *n;
- int T, E;
- DdNode *base = DD_ONE(zdd);
-
- if (f == NULL)
- return(0);
-
- if (Cudd_IsConstant(f)) {
- (void)fprintf(zdd->out, "ID = %d\n", (f == base));
- return(1);
- }
- if (st_is_member(t, (char *)f) == 1)
- return(1);
-
- if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM)
- 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);
-#else
- (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t",
- (unsigned)f / (unsigned) 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;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n /
- (unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode));
-#endif
- T = 0;
- }
-
- n = cuddE(f);
- if (Cudd_IsConstant(n)) {
- (void) fprintf(zdd->out, "E = %d\n", (n == base));
- E = 1;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n /
- (unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode));
-#endif
- E = 0;
- }
-
- if (E == 0)
- if (zp2(zdd, cuddE(f), t) == 0) return(0);
- if (T == 0)
- if (zp2(zdd, cuddT(f), t) == 0) return(0);
- return(1);
-
-} /* end of zp2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddPrintMinterm.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-zdd_print_minterm_aux(
- DdManager * zdd /* manager */,
- DdNode * node /* current node */,
- int level /* depth in the recursion */,
- int * list /* current recursion path */)
-{
- DdNode *Nv, *Nnv;
- int i, v;
- DdNode *base = DD_ONE(zdd);
-
- if (Cudd_IsConstant(node)) {
- 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 != 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;
- 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;
-
-} /* end of zdd_print_minterm_aux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_zddPrintCover.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-zddPrintCoverAux(
- DdManager * zdd /* manager */,
- DdNode * node /* current node */,
- int level /* depth in the recursion */,
- int * list /* current recursion path */)
-{
- DdNode *Nv, *Nnv;
- int i, v;
- DdNode *base = DD_ONE(zdd);
-
- if (Cudd_IsConstant(node)) {
- 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 != 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;
- 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 */
diff --git a/src/bdd/cudd/module.make b/src/bdd/cudd/module.make
deleted file mode 100644
index c526a50e..00000000
--- a/src/bdd/cudd/module.make
+++ /dev/null
@@ -1,61 +0,0 @@
-SRC += src/bdd/cudd/cuddAPI.c \
- src/bdd/cudd/cuddAddAbs.c \
- src/bdd/cudd/cuddAddApply.c \
- src/bdd/cudd/cuddAddFind.c \
- src/bdd/cudd/cuddAddInv.c \
- src/bdd/cudd/cuddAddIte.c \
- src/bdd/cudd/cuddAddNeg.c \
- src/bdd/cudd/cuddAddWalsh.c \
- src/bdd/cudd/cuddAndAbs.c \
- src/bdd/cudd/cuddAnneal.c \
- src/bdd/cudd/cuddApa.c \
- src/bdd/cudd/cuddApprox.c \
- src/bdd/cudd/cuddBddAbs.c \
- src/bdd/cudd/cuddBddCorr.c \
- src/bdd/cudd/cuddBddIte.c \
- src/bdd/cudd/cuddBridge.c \
- src/bdd/cudd/cuddCache.c \
- src/bdd/cudd/cuddCheck.c \
- src/bdd/cudd/cuddClip.c \
- src/bdd/cudd/cuddCof.c \
- src/bdd/cudd/cuddCompose.c \
- src/bdd/cudd/cuddDecomp.c \
- src/bdd/cudd/cuddEssent.c \
- src/bdd/cudd/cuddExact.c \
- src/bdd/cudd/cuddExport.c \
- src/bdd/cudd/cuddGenCof.c \
- src/bdd/cudd/cuddGenetic.c \
- src/bdd/cudd/cuddGroup.c \
- src/bdd/cudd/cuddHarwell.c \
- src/bdd/cudd/cuddInit.c \
- src/bdd/cudd/cuddInteract.c \
- src/bdd/cudd/cuddLCache.c \
- src/bdd/cudd/cuddLevelQ.c \
- src/bdd/cudd/cuddLinear.c \
- src/bdd/cudd/cuddLiteral.c \
- src/bdd/cudd/cuddMatMult.c \
- src/bdd/cudd/cuddPriority.c \
- src/bdd/cudd/cuddRead.c \
- src/bdd/cudd/cuddRef.c \
- src/bdd/cudd/cuddReorder.c \
- src/bdd/cudd/cuddSat.c \
- src/bdd/cudd/cuddSign.c \
- src/bdd/cudd/cuddSolve.c \
- src/bdd/cudd/cuddSplit.c \
- src/bdd/cudd/cuddSubsetHB.c \
- src/bdd/cudd/cuddSubsetSP.c \
- src/bdd/cudd/cuddSymmetry.c \
- src/bdd/cudd/cuddTable.c \
- src/bdd/cudd/cuddUtil.c \
- src/bdd/cudd/cuddWindow.c \
- src/bdd/cudd/cuddZddCount.c \
- src/bdd/cudd/cuddZddFuncs.c \
- src/bdd/cudd/cuddZddGroup.c \
- src/bdd/cudd/cuddZddIsop.c \
- src/bdd/cudd/cuddZddLin.c \
- src/bdd/cudd/cuddZddMisc.c \
- src/bdd/cudd/cuddZddPort.c \
- src/bdd/cudd/cuddZddReord.c \
- src/bdd/cudd/cuddZddSetop.c \
- src/bdd/cudd/cuddZddSymm.c \
- src/bdd/cudd/cuddZddUtil.c
diff --git a/src/bdd/cudd/r7x8.1.mat b/src/bdd/cudd/r7x8.1.mat
deleted file mode 100644
index b0dd0a0a..00000000
--- a/src/bdd/cudd/r7x8.1.mat
+++ /dev/null
@@ -1,53 +0,0 @@
-7 9
-0 0 1
-0 1 1
-0 2 1
-0 3 4
-0 4 3
-0 5 3
-0 6 3
-0 8 3
-1 0 4
-1 1 3
-1 2 2
-1 3 4
-1 4 1
-1 5 2
-1 6 4
-1 8 3
-2 0 1
-2 1 1
-2 2 4
-2 4 2
-2 5 3
-2 6 3
-2 8 3
-3 0 2
-3 1 1
-3 3 4
-3 4 4
-3 5 1
-3 8 1
-4 0 2
-4 1 3
-4 2 2
-4 3 4
-4 4 1
-4 5 1
-4 6 2
-4 8 2
-5 0 3
-5 1 3
-5 2 4
-5 3 4
-5 4 1
-5 5 3
-5 6 3
-5 8 4
-6 1 1
-6 2 1
-6 3 4
-6 4 2
-6 5 4
-6 6 4
-6 8 2
diff --git a/src/bdd/cudd/testcudd.c b/src/bdd/cudd/testcudd.c
deleted file mode 100644
index d8affadc..00000000
--- a/src/bdd/cudd/testcudd.c
+++ /dev/null
@@ -1,988 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [testcudd.c]
-
- PackageName [cudd]
-
- Synopsis [Sanity check tests for some CUDD functions.]
-
- Description [testcudd reads a matrix with real coefficients and
- transforms it into an ADD. It then performs various operations on
- the ADD and on the BDD corresponding to the ADD pattern. Finally,
- testcudd tests functions relate to Walsh matrices and matrix
- multiplication.]
-
- 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.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define TESTCUDD_VERSION "TestCudd Version #1.0, Release date 3/17/01"
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
-#endif
-
-static char *onames[] = { "C", "M" }; /* names of functions to be dumped */
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* 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));
-
-/**AutomaticEnd***************************************************************/
-
-
-/**Function********************************************************************
-
- Synopsis [Main function for testcudd.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-main(int argc, char **argv)
-{
- FILE *fp; /* pointer to input file */
- char *file = ""; /* 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 *M;
- DdNode **x; /* pointers to variables */
- DdNode **y; /* pointers to 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 */
- DdNode *ess; /* cube of essential variables */
- DdNode *shortP; /* BDD cube of shortest path */
- DdNode *largest; /* BDD of largest cube */
- DdNode *shortA; /* ADD cube of shortest path */
- DdNode *constN; /* value returned by evaluation of ADD */
- DdNode *ycube; /* cube of the negated y vars for c-proj */
- DdNode *CP; /* C-Projection of C */
- DdNode *CPr; /* C-Selection of C */
- int length; /* length of the shortest path */
- int nx; /* number of variables */
- int ny;
- int maxnx;
- int maxny;
- int m;
- int n;
- int N;
- int cmu; /* use CMU multiplication */
- int pr; /* verbose printout level */
- int harwell;
- int multiple; /* read multiple matrices */
- int ok;
- int c; /* variable to read in options */
- int approach; /* reordering approach */
- int autodyn; /* automatic reordering */
- int groupcheck; /* option for group sifting */
- int profile; /* print heap profile if != 0 */
- int keepperm; /* keep track of permutation */
- int clearcache; /* clear the cache after each matrix */
- int blifOrDot; /* dump format: 0 -> dot, 1 -> blif, ... */
- int retval; /* return value */
- int i; /* loop index */
- long startTime; /* initial time */
- long lapTime;
- int size;
- unsigned int cacheSize, maxMemory;
- unsigned int nvars,nslots;
-
- startTime = util_cpu_time();
-
- approach = CUDD_REORDER_NONE;
- autodyn = 0;
- pr = 0;
- harwell = 0;
- multiple = 0;
- profile = 0;
- keepperm = 0;
- cmu = 0;
- N = 4;
- nvars = 4;
- cacheSize = 127;
- maxMemory = 0;
- nslots = CUDD_UNIQUE_SLOTS;
- clearcache = 0;
- groupcheck = CUDD_GROUP_CHECK7;
- dfile = NULL;
- blifOrDot = 0; /* dot format */
-
- /* Parse command line. */
- while ((c = util_getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:"))
- != EOF) {
- switch(c) {
- case 'C':
- cmu = 1;
- break;
- case 'D':
- autodyn = 1;
- break;
- case 'H':
- harwell = 1;
- break;
- case 'M':
-#ifdef MNEMOSYNE
- (void) mnem_setrecording(0);
-#endif
- break;
- case 'P':
- profile = 1;
- break;
- case 'S':
- nslots = atoi(util_optarg);
- break;
- case 'X':
- maxMemory = atoi(util_optarg);
- break;
- case 'a':
- approach = atoi(util_optarg);
- break;
- case 'b':
- blifOrDot = 1; /* blif format */
- break;
- case 'c':
- clearcache = 1;
- break;
- case 'd':
- dfile = util_optarg;
- break;
- case 'g':
- groupcheck = atoi(util_optarg);
- break;
- case 'k':
- keepperm = 1;
- break;
- case 'm':
- multiple = 1;
- break;
- case 'n':
- N = atoi(util_optarg);
- break;
- case 'p':
- pr = atoi(util_optarg);
- break;
- case 'v':
- nvars = atoi(util_optarg);
- break;
- case 'x':
- cacheSize = atoi(util_optarg);
- break;
- case 'h':
- default:
- usage(argv[0]);
- break;
- }
- }
-
- if (argc - util_optind == 0) {
- file = "-";
- } else if (argc - util_optind == 1) {
- file = argv[util_optind];
- } else {
- usage(argv[0]);
- }
- if ((approach<0) || (approach>17)) {
- (void) fprintf(stderr,"Invalid approach: %d \n",approach);
- usage(argv[0]);
- }
-
- if (pr >= 0) {
- (void) printf("# %s\n", TESTCUDD_VERSION);
- /* Echo command line and arguments. */
- (void) printf("#");
- for (i = 0; i < argc; i++) {
- (void) printf(" %s", argv[i]);
- }
- (void) printf("\n");
- (void) fflush(stdout);
- }
-
- /* 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);
-
- /* Open input file. */
- fp = open_file(file, "r");
-
- /* Open dump file if requested */
- if (dfile != NULL) {
- dfp = open_file(dfile, "w");
- }
-
- x = y = xn = yn_ = NULL;
- do {
- /* We want to start anew for every matrix. */
- maxnx = maxny = 0;
- nx = maxnx; ny = maxny;
- if (pr>0) lapTime = util_cpu_time();
- if (harwell) {
- if (pr >= 0) (void) printf(":name: ");
- ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny,
- &m, &n, 0, 2, 1, 2, pr);
- } else {
- ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny,
- &m, &n, 0, 2, 1, 2);
- if (pr >= 0)
- (void) printf(":name: %s: %d rows %d columns\n", file, m, n);
- }
- if (!ok) {
- (void) fprintf(stderr, "Error reading matrix\n");
- exit(1);
- }
-
- if (nx > maxnx) maxnx = nx;
- if (ny > maxny) maxny = ny;
-
- /* Build cube of negated y's. */
- ycube = DD_ONE(dd);
- Cudd_Ref(ycube);
- for (i = maxny - 1; i >= 0; i--) {
- DdNode *tmpp;
- tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube);
- if (tmpp == NULL) exit(2);
- Cudd_Ref(tmpp);
- Cudd_RecursiveDeref(dd,ycube);
- ycube = tmpp;
- }
- /* Initialize vectors of BDD variables used by priority func. */
- xvars = ALLOC(DdNode *, nx);
- if (xvars == NULL) exit(2);
- for (i = 0; i < nx; i++) {
- xvars[i] = dd->vars[x[i]->index];
- }
- yvars = ALLOC(DdNode *, ny);
- if (yvars == NULL) exit(2);
- for (i = 0; i < ny; i++) {
- yvars[i] = dd->vars[y[i]->index];
- }
-
- /* Clean up */
- for (i=0; i < maxnx; i++) {
- Cudd_RecursiveDeref(dd, x[i]);
- Cudd_RecursiveDeref(dd, xn[i]);
- }
- FREE(x);
- FREE(xn);
- for (i=0; i < maxny; i++) {
- Cudd_RecursiveDeref(dd, y[i]);
- Cudd_RecursiveDeref(dd, yn_[i]);
- }
- FREE(y);
- FREE(yn_);
-
- if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);}
-
- if (pr>0) (void) printf(":2: time to read the matrix = %s\n",
- util_print_time(util_cpu_time() - lapTime));
-
- C = Cudd_addBddPattern(dd, M);
- if (C == 0) exit(2);
- Cudd_Ref(C);
- if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);}
-
- /* Test iterators. */
- retval = testIterators(dd,M,C,pr);
- if (retval == 0) exit(2);
-
- cuddCacheProfile(dd,stdout);
-
- /* Test XOR */
- retval = testXor(dd,C,pr,nx+ny);
- if (retval == 0) exit(2);
-
- /* Test Hamming distance functions. */
- retval = testHamming(dd,C,pr,nx+ny);
- if (retval == 0) exit(2);
-
- /* Test selection functions. */
- CP = Cudd_CProjection(dd,C,ycube);
- if (CP == NULL) exit(2);
- Cudd_Ref(CP);
- if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);}
- if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);}
-
- if (nx == ny) {
- CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL,
- (DdNode *)NULL,ny,Cudd_Xgty);
- if (CPr == NULL) exit(2);
- Cudd_Ref(CPr);
- if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);}
- if (CP != CPr) {
- (void) printf("CP != CPr!\n");
- }
- Cudd_RecursiveDeref(dd, CPr);
- }
- FREE(xvars); FREE(yvars);
-
- Cudd_RecursiveDeref(dd, CP);
- Cudd_RecursiveDeref(dd, ycube);
-
- /* Test functions for essential variables. */
- ess = Cudd_FindEssential(dd,C);
- if (ess == NULL) exit(2);
- Cudd_Ref(ess);
- if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);}
- Cudd_RecursiveDeref(dd, ess);
-
- /* Test functions for shortest paths. */
- shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length);
- if (shortP == NULL) exit(2);
- Cudd_Ref(shortP);
- if (pr>0) {
- (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr);
- }
- /* Test functions for largest cubes. */
- largest = Cudd_LargestCube(dd, Cudd_Not(C), &length);
- if (largest == NULL) exit(2);
- Cudd_Ref(largest);
- if (pr>0) {
- (void) printf(":5b: largest");
- Cudd_PrintDebug(dd,largest,nx+ny,pr);
- }
- Cudd_RecursiveDeref(dd, largest);
-
- /* Test Cudd_addEvalConst and Cudd_addIteConstant. */
- shortA = Cudd_BddToAdd(dd,shortP);
- if (shortA == NULL) exit(2);
- Cudd_Ref(shortA);
- Cudd_RecursiveDeref(dd, shortP);
- constN = Cudd_addEvalConst(dd,shortA,M);
- if (constN == DD_NON_CONSTANT) exit(2);
- if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2);
- if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));}
- Cudd_RecursiveDeref(dd, shortA);
-
- shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length);
- if (shortP == NULL) exit(2);
- Cudd_Ref(shortP);
- if (pr>0) {
- (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr);
- }
-
- /* Test Cudd_bddIteConstant and Cudd_bddLeq. */
- if (!Cudd_bddLeq(dd,shortP,C)) exit(2);
- if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),one,C) != one) exit(2);
- Cudd_RecursiveDeref(dd, shortP);
-
- if (profile) {
- retval = cuddHeapProfile(dd);
- }
-
- size = dd->size;
-
- if (pr>0) {
- (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd));
- }
-
- /* Reorder if so requested. */
- if (approach != CUDD_REORDER_NONE) {
-#ifndef DD_STATS
- retval = Cudd_EnableReorderingReporting(dd);
- if (retval == 0) {
- (void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n");
- exit(3);
- }
-#endif
-#ifdef DD_DEBUG
- retval = Cudd_DebugCheck(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
- exit(3);
- }
- retval = Cudd_CheckKeys(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
- exit(3);
- }
-#endif
- retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5);
- if (retval == 0) {
- (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n");
- exit(3);
- }
-#ifndef DD_STATS
- retval = Cudd_DisableReorderingReporting(dd);
- if (retval == 0) {
- (void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n");
- exit(3);
- }
-#endif
-#ifdef DD_DEBUG
- retval = Cudd_DebugCheck(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
- exit(3);
- }
- retval = Cudd_CheckKeys(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
- exit(3);
- }
-#endif
- if (approach == CUDD_REORDER_SYMM_SIFT ||
- approach == CUDD_REORDER_SYMM_SIFT_CONV) {
- Cudd_SymmProfile(dd,0,dd->size-1);
- }
-
- if (pr>0) {
- (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd));
- }
-
- if (keepperm) {
- /* Print variable permutation. */
- (void) printf("Variable Permutation:");
- for (i=0; i<size; i++) {
- if (i%20 == 0) (void) printf("\n");
- (void) printf("%d ", dd->invperm[i]);
- }
- (void) printf("\n");
- (void) printf("Inverse Permutation:");
- for (i=0; i<size; i++) {
- if (i%20 == 0) (void) printf("\n");
- (void) printf("%d ", dd->perm[i]);
- }
- (void) printf("\n");
- }
-
- if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);}
-
- if (profile) {
- retval = cuddHeapProfile(dd);
- }
-
- }
-
- /* Dump DDs of C and M if so requested. */
- if (dfile != NULL) {
- dfunc[0] = C;
- dfunc[1] = M;
- if (blifOrDot == 1) {
- /* Only dump C because blif cannot handle ADDs */
- retval = Cudd_DumpBlif(dd,1,dfunc,NULL,onames,NULL,dfp);
- } else {
- retval = Cudd_DumpDot(dd,2,dfunc,NULL,onames,dfp);
- }
- if (retval != 1) {
- (void) fprintf(stderr,"abnormal termination\n");
- exit(2);
- }
- }
-
- Cudd_RecursiveDeref(dd, C);
- Cudd_RecursiveDeref(dd, M);
-
- if (clearcache) {
- if (pr>0) {(void) printf("Clearing the cache... ");}
- for (i = dd->cacheSlots - 1; i>=0; i--) {
- dd->cache[i].data = NIL(DdNode);
- }
- if (pr>0) {(void) printf("done\n");}
- }
- 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);
- }
-
- } while (multiple && !feof(fp));
-
- fclose(fp);
- if (dfile != NULL) {
- fclose(dfp);
- }
-
- /* Second phase: experiment with Walsh matrices. */
- if (!testWalsh(dd,N,cmu,approach,pr)) {
- exit(2);
- }
-
- /* Check variable destruction. */
- assert(cuddDestroySubtables(dd,3));
- assert(Cudd_DebugCheck(dd) == 0);
- assert(Cudd_CheckKeys(dd) == 0);
-
- retval = Cudd_CheckZeroRef(dd);
- ok = retval != 0; /* ok == 0 means O.K. */
- if (retval != 0) {
- (void) fprintf(stderr,
- "%d non-zero DD reference counts after dereferencing\n", retval);
- }
-
- if (pr >= 0) {
- (void) Cudd_PrintInfo(dd,stdout);
- }
-
- Cudd_Quit(dd);
-
-#ifdef MNEMOSYNE
- mnem_writestats();
-#endif
-
- if (pr>0) (void) printf("total time = %s\n",
- util_print_time(util_cpu_time() - startTime));
-
- if (pr >= 0) util_print_cpu_stats(stdout);
- exit(ok);
- /* NOTREACHED */
-
-} /* end of main */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints usage info for testcudd.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static void
-usage(char *prog)
-{
- (void) fprintf(stderr, "usage: %s [options] [file]\n", prog);
- (void) fprintf(stderr, " -C\t\tuse CMU multiplication algorithm\n");
- (void) fprintf(stderr, " -D\t\tenable automatic dynamic reordering\n");
- (void) fprintf(stderr, " -H\t\tread matrix in Harwell format\n");
- (void) fprintf(stderr, " -M\t\tturns off memory allocation recording\n");
- (void) fprintf(stderr, " -P\t\tprint BDD heap profile\n");
- (void) fprintf(stderr, " -S n\t\tnumber of slots for each subtable\n");
- (void) fprintf(stderr, " -X n\t\ttarget maximum memory in bytes\n");
- (void) fprintf(stderr, " -a n\t\tchoose reordering approach (0-13)\n");
- (void) fprintf(stderr, " \t\t\t0: same as autoMethod\n");
- (void) fprintf(stderr, " \t\t\t1: no reordering (default)\n");
- (void) fprintf(stderr, " \t\t\t2: random\n");
- (void) fprintf(stderr, " \t\t\t3: pivot\n");
- (void) fprintf(stderr, " \t\t\t4: sifting\n");
- (void) fprintf(stderr, " \t\t\t5: sifting to convergence\n");
- (void) fprintf(stderr, " \t\t\t6: symmetric sifting\n");
- (void) fprintf(stderr, " \t\t\t7: symmetric sifting to convergence\n");
- (void) fprintf(stderr, " \t\t\t8-10: window of size 2-4\n");
- (void) fprintf(stderr, " \t\t\t11-13: window of size 2-4 to conv.\n");
- (void) fprintf(stderr, " \t\t\t14: group sifting\n");
- (void) fprintf(stderr, " \t\t\t15: group sifting to convergence\n");
- (void) fprintf(stderr, " \t\t\t16: simulated annealing\n");
- (void) fprintf(stderr, " \t\t\t17: genetic algorithm\n");
- (void) fprintf(stderr, " -b\t\tuse blif as format for dumps\n");
- (void) fprintf(stderr, " -c\t\tclear the cache after each matrix\n");
- (void) fprintf(stderr, " -d file\tdump DDs to file\n");
- (void) fprintf(stderr, " -g\t\tselect aggregation criterion (0,5,7)\n");
- (void) fprintf(stderr, " -h\t\tprints this message\n");
- (void) fprintf(stderr, " -k\t\tprint the variable permutation\n");
- (void) fprintf(stderr, " -m\t\tread multiple matrices (only with -H)\n");
- (void) fprintf(stderr, " -n n\t\tnumber of variables\n");
- (void) fprintf(stderr, " -p n\t\tcontrol verbosity\n");
- (void) fprintf(stderr, " -v n\t\tinitial variables in the unique table\n");
- (void) fprintf(stderr, " -x n\t\tinitial size of the cache\n");
- exit(2);
-} /* end of usage */
-
-
-/**Function********************************************************************
-
- Synopsis [Opens a file.]
-
- Description [Opens a file, or fails with an error message and exits.
- Allows '-' as a synonym for standard input.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static FILE *
-open_file(char *filename, char *mode)
-{
- FILE *fp;
-
- if (strcmp(filename, "-") == 0) {
- return mode[0] == 'r' ? stdin : stdout;
- } else if ((fp = fopen(filename, mode)) == NULL) {
- perror(filename);
- exit(1);
- }
- return fp;
-
-} /* end of open_file */
-
-
-/**Function********************************************************************
-
- Synopsis [Tests Walsh matrix multiplication.]
-
- Description [Tests Walsh matrix multiplication. Return 1 if successful;
- 0 otherwise.]
-
- SideEffects [May create new variables in the manager.]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-testWalsh(
- DdManager *dd /* manager */,
- int N /* number of variables */,
- int cmu /* use CMU approach to matrix multiplication */,
- int approach /* reordering approach */,
- int pr /* verbosity level */)
-{
- DdNode *walsh1, *walsh2, *wtw;
- DdNode **x, **v, **z;
- int i, retval;
- DdNode *one = DD_ONE(dd);
- DdNode *zero = DD_ZERO(dd);
-
- if (N > 3) {
- x = ALLOC(DdNode *,N);
- v = ALLOC(DdNode *,N);
- z = ALLOC(DdNode *,N);
-
- for (i = N-1; i >= 0; i--) {
- Cudd_Ref(x[i]=cuddUniqueInter(dd,3*i,one,zero));
- Cudd_Ref(v[i]=cuddUniqueInter(dd,3*i+1,one,zero));
- Cudd_Ref(z[i]=cuddUniqueInter(dd,3*i+2,one,zero));
- }
- Cudd_Ref(walsh1 = Cudd_addWalsh(dd,v,z,N));
- if (pr>0) {(void) printf("walsh1"); Cudd_PrintDebug(dd,walsh1,2*N,pr);}
- Cudd_Ref(walsh2 = Cudd_addWalsh(dd,x,v,N));
- if (cmu) {
- Cudd_Ref(wtw = Cudd_addTimesPlus(dd,walsh2,walsh1,v,N));
- } else {
- Cudd_Ref(wtw = Cudd_addMatrixMultiply(dd,walsh2,walsh1,v,N));
- }
- if (pr>0) {(void) printf("wtw"); Cudd_PrintDebug(dd,wtw,2*N,pr);}
-
- if (approach != CUDD_REORDER_NONE) {
-#ifdef DD_DEBUG
- retval = Cudd_DebugCheck(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
- return(0);
- }
-#endif
- retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5);
- if (retval == 0) {
- (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n");
- return(0);
- }
-#ifdef DD_DEBUG
- retval = Cudd_DebugCheck(dd);
- if (retval != 0) {
- (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
- return(0);
- }
-#endif
- if (approach == CUDD_REORDER_SYMM_SIFT ||
- approach == CUDD_REORDER_SYMM_SIFT_CONV) {
- Cudd_SymmProfile(dd,0,dd->size-1);
- }
- }
- /* Clean up. */
- Cudd_RecursiveDeref(dd, wtw);
- Cudd_RecursiveDeref(dd, walsh1);
- Cudd_RecursiveDeref(dd, walsh2);
- for (i=0; i < N; i++) {
- Cudd_RecursiveDeref(dd, x[i]);
- Cudd_RecursiveDeref(dd, v[i]);
- Cudd_RecursiveDeref(dd, z[i]);
- }
- FREE(x);
- FREE(v);
- FREE(z);
- }
- return(1);
-
-} /* end of testWalsh */
-
-/**Function********************************************************************
-
- Synopsis [Tests iterators.]
-
- Description [Tests iterators on cubes and nodes.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-testIterators(
- DdManager *dd,
- DdNode *M,
- DdNode *C,
- int pr)
-{
- int *cube;
- CUDD_VALUE_TYPE value;
- DdGen *gen;
- int q;
-
- /* Test iterator for cubes. */
- if (pr>1) {
- (void) printf("Testing iterator on cubes:\n");
- Cudd_ForeachCube(dd,M,gen,cube,value) {
- for (q = 0; q < dd->size; q++) {
- switch (cube[q]) {
- case 0:
- (void) printf("0");
- break;
- case 1:
- (void) printf("1");
- break;
- case 2:
- (void) printf("-");
- break;
- default:
- (void) printf("?");
- }
- }
- (void) printf(" %g\n",value);
- }
- (void) printf("\n");
- }
-
- if (pr>1) {
- (void) printf("Testing prime expansion of cubes:\n");
- if (!Cudd_bddPrintCover(dd,C,C)) return(0);
- }
-
- /* 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),
- Cudd_V(node));
-#else
- (void) printf("ID = 0x%x\tvalue = %-9g\n",
- (unsigned int) node /
- (unsigned int) 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),
- node->index, node->ref);
-#else
- (void) printf("ID = 0x%x\tindex = %d\tr = %d\n",
- (unsigned int) node /
- (unsigned int) sizeof(DdNode),
- node->index, node->ref);
-#endif
- }
- }
- (void) printf("\n");
- }
- return(1);
-
-} /* end of testIterators */
-
-
-/**Function********************************************************************
-
- Synopsis [Tests the functions related to the exclusive OR.]
-
- Description [Tests the functions related to the exclusive OR. It
- builds the boolean difference of the given function in three
- different ways and checks that the results is the same. Returns 1 if
- successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-testXor(DdManager *dd, DdNode *f, int pr, int nvars)
-{
- DdNode *f1, *f0, *res1, *res2;
- int x;
-
- /* Extract cofactors w.r.t. mid variable. */
- x = nvars / 2;
- f1 = Cudd_Cofactor(dd,f,dd->vars[x]);
- if (f1 == NULL) return(0);
- Cudd_Ref(f1);
-
- f0 = Cudd_Cofactor(dd,f,Cudd_Not(dd->vars[x]));
- if (f0 == NULL) {
- Cudd_RecursiveDeref(dd,f1);
- return(0);
- }
- Cudd_Ref(f0);
-
- /* Compute XOR of cofactors with ITE. */
- res1 = Cudd_bddIte(dd,f1,Cudd_Not(f0),f0);
- if (res1 == NULL) return(0);
- Cudd_Ref(res1);
-
- if (pr>0) {(void) printf("xor1"); Cudd_PrintDebug(dd,res1,nvars,pr);}
-
- /* Compute XOR of cofactors with XOR. */
- res2 = Cudd_bddXor(dd,f1,f0);
- if (res2 == NULL) {
- Cudd_RecursiveDeref(dd,res1);
- return(0);
- }
- Cudd_Ref(res2);
-
- if (res1 != res2) {
- if (pr>0) {(void) printf("xor2"); Cudd_PrintDebug(dd,res2,nvars,pr);}
- Cudd_RecursiveDeref(dd,res1);
- Cudd_RecursiveDeref(dd,res2);
- return(0);
- }
- Cudd_RecursiveDeref(dd,res1);
- Cudd_RecursiveDeref(dd,f1);
- Cudd_RecursiveDeref(dd,f0);
-
- /* Compute boolean difference directly. */
- res1 = Cudd_bddBooleanDiff(dd,f,x);
- if (res1 == NULL) {
- Cudd_RecursiveDeref(dd,res2);
- return(0);
- }
- Cudd_Ref(res1);
-
- if (res1 != res2) {
- if (pr>0) {(void) printf("xor3"); Cudd_PrintDebug(dd,res1,nvars,pr);}
- Cudd_RecursiveDeref(dd,res1);
- Cudd_RecursiveDeref(dd,res2);
- return(0);
- }
- Cudd_RecursiveDeref(dd,res1);
- Cudd_RecursiveDeref(dd,res2);
- return(1);
-
-} /* end of testXor */
-
-
-/**Function********************************************************************
-
- Synopsis [Tests the Hamming distance functions.]
-
- Description [Tests the Hammming distance functions. Returns
- 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-testHamming(
- DdManager *dd,
- DdNode *f,
- int pr,
- int nvars)
-{
- DdNode **vars, *minBdd, *zero, *scan;
- int i;
- int d;
- int *minterm;
- int size = Cudd_ReadSize(dd);
-
- vars = ALLOC(DdNode *, size);
- if (vars == NULL) return(0);
- for (i = 0; i < size; i++) {
- vars[i] = Cudd_bddIthVar(dd,i);
- }
-
- minBdd = Cudd_bddPickOneMinterm(dd,Cudd_Not(f),vars,size);
- Cudd_Ref(minBdd);
- if (pr > 0) {
- (void) printf("Chosen minterm for Hamming distance test: ");
- Cudd_PrintDebug(dd,minBdd,size,pr);
- }
-
- minterm = ALLOC(int,size);
- if (minterm == NULL) {
- FREE(vars);
- Cudd_RecursiveDeref(dd,minBdd);
- return(0);
- }
- scan = minBdd;
- zero = Cudd_Not(DD_ONE(dd));
- while (!Cudd_IsConstant(scan)) {
- DdNode *R = Cudd_Regular(scan);
- DdNode *T = Cudd_T(R);
- DdNode *E = Cudd_E(R);
- if (R != scan) {
- T = Cudd_Not(T);
- E = Cudd_Not(E);
- }
- if (T == zero) {
- minterm[R->index] = 0;
- scan = E;
- } else {
- minterm[R->index] = 1;
- scan = T;
- }
- }
- Cudd_RecursiveDeref(dd,minBdd);
-
- d = Cudd_MinHammingDist(dd,f,minterm,size);
-
- (void) printf("Minimum Hamming distance = %d\n", d);
-
- FREE(vars);
- FREE(minterm);
- return(1);
-
-} /* end of testHamming */