summaryrefslogtreecommitdiffstats
path: root/src/misc/extra
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2015-08-24 21:09:50 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2015-08-24 21:09:50 -0700
commit24f2a120f2203acc8038ccce4e8dd141564a7a04 (patch)
treed8c0d0efa6c2dc1ef656624f807ba3f4f6db8b9d /src/misc/extra
parenteb699bbaf80e4a6a0e85f87d7575ca1ffebef37f (diff)
downloadabc-24f2a120f2203acc8038ccce4e8dd141564a7a04.tar.gz
abc-24f2a120f2203acc8038ccce4e8dd141564a7a04.tar.bz2
abc-24f2a120f2203acc8038ccce4e8dd141564a7a04.zip
Changes to be able to compile ABC without CUDD.
Diffstat (limited to 'src/misc/extra')
-rw-r--r--src/misc/extra/extraBdd.h317
-rw-r--r--src/misc/extra/extraBddAuto.c1563
-rw-r--r--src/misc/extra/extraBddCas.c1235
-rw-r--r--src/misc/extra/extraBddImage.c1162
-rw-r--r--src/misc/extra/extraBddKmap.c876
-rw-r--r--src/misc/extra/extraBddMisc.c2342
-rw-r--r--src/misc/extra/extraBddSymm.c1474
-rw-r--r--src/misc/extra/extraBddTime.c660
-rw-r--r--src/misc/extra/extraBddUnate.c646
9 files changed, 0 insertions, 10275 deletions
diff --git a/src/misc/extra/extraBdd.h b/src/misc/extra/extraBdd.h
deleted file mode 100644
index 3dbc6264..00000000
--- a/src/misc/extra/extraBdd.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBdd.h]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [extra]
-
- Synopsis [Various reusable software utilities.]
-
- Description [This library contains a number of operators and
- traversal routines developed to extend the functionality of
- CUDD v.2.3.x, by Fabio Somenzi (http://vlsi.colorado.edu/~fabio/)
- To compile your code with the library, #include "extra.h"
- in your source files and link your project to CUDD and this
- library. Use the library at your own risk and with caution.
- Note that debugging of some operators still continues.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: extraBdd.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#ifndef ABC__misc__extra__extra_bdd_h
-#define ABC__misc__extra__extra_bdd_h
-
-
-#ifdef _WIN32
-#define inline __inline // compatible with MS VS 6.0
-#endif
-
-/*---------------------------------------------------------------------------*/
-/* Nested includes */
-/*---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "misc/st/st.h"
-#include "bdd/cudd/cuddInt.h"
-#include "misc/extra/extra.h"
-
-
-ABC_NAMESPACE_HEADER_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/* constants of the manager */
-#define b0 Cudd_Not((dd)->one)
-#define b1 (dd)->one
-#define z0 (dd)->zero
-#define z1 (dd)->one
-#define a0 (dd)->zero
-#define a1 (dd)->one
-
-// hash key macros
-#define hashKey1(a,TSIZE) \
-((ABC_PTRUINT_T)(a) % TSIZE)
-
-#define hashKey2(a,b,TSIZE) \
-(((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b) * DD_P1) % TSIZE)
-
-#define hashKey3(a,b,c,TSIZE) \
-(((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 ) % TSIZE)
-
-#define hashKey4(a,b,c,d,TSIZE) \
-((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
- (ABC_PTRUINT_T)(d)) * DD_P3) % TSIZE)
-
-#define hashKey5(a,b,c,d,e,TSIZE) \
-(((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
- (ABC_PTRUINT_T)(d)) * DD_P3 + (ABC_PTRUINT_T)(e)) * DD_P1) % TSIZE)
-
-/*===========================================================================*/
-/* Various Utilities */
-/*===========================================================================*/
-
-/*=== extraBddAuto.c ========================================================*/
-
-extern DdNode * Extra_bddSpaceFromFunctionFast( DdManager * dd, DdNode * bFunc );
-extern DdNode * Extra_bddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG );
-extern DdNode * extraBddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG );
-extern DdNode * Extra_bddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc );
-extern DdNode * extraBddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc );
-extern DdNode * Extra_bddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc );
-extern DdNode * extraBddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc );
-
-extern DdNode * Extra_bddSpaceCanonVars( DdManager * dd, DdNode * bSpace );
-extern DdNode * extraBddSpaceCanonVars( DdManager * dd, DdNode * bSpace );
-
-extern DdNode * Extra_bddSpaceEquations( DdManager * dd, DdNode * bSpace );
-extern DdNode * Extra_bddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace );
-extern DdNode * extraBddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace );
-extern DdNode * Extra_bddSpaceEquationsPos( DdManager * dd, DdNode * bSpace );
-extern DdNode * extraBddSpaceEquationsPos( DdManager * dd, DdNode * bSpace );
-
-extern DdNode * Extra_bddSpaceFromMatrixPos( DdManager * dd, DdNode * zA );
-extern DdNode * extraBddSpaceFromMatrixPos( DdManager * dd, DdNode * zA );
-extern DdNode * Extra_bddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA );
-extern DdNode * extraBddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA );
-
-extern DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars );
-extern DdNode ** Extra_bddSpaceExorGates( DdManager * dd, DdNode * bFuncRed, DdNode * zEquations );
-
-/*=== extraBddCas.c =============================================================*/
-
-/* performs the binary encoding of the set of function using the given vars */
-extern DdNode * Extra_bddEncodingBinary( DdManager * dd, DdNode ** pbFuncs, int nFuncs, DdNode ** pbVars, int nVars );
-/* solves the column encoding problem using a sophisticated method */
-extern DdNode * Extra_bddEncodingNonStrict( DdManager * dd, DdNode ** pbColumns, int nColumns, DdNode * bVarsCol, DdNode ** pCVars, int nMulti, int * pSimple );
-/* collects the nodes under the cut and, for each node, computes the sum of paths leading to it from the root */
-extern st__table * Extra_bddNodePathsUnderCut( DdManager * dd, DdNode * bFunc, int CutLevel );
-/* collects the nodes under the cut starting from the given set of ADD nodes */
-extern int Extra_bddNodePathsUnderCutArray( DdManager * dd, DdNode ** paNodes, DdNode ** pbCubes, int nNodes, DdNode ** paNodesRes, DdNode ** pbCubesRes, int CutLevel );
-/* find the profile of a DD (the number of edges crossing each level) */
-extern int Extra_ProfileWidth( DdManager * dd, DdNode * F, int * Profile, int CutLevel );
-
-/*=== extraBddImage.c ================================================================*/
-
-typedef struct Extra_ImageTree_t_ Extra_ImageTree_t;
-extern Extra_ImageTree_t * Extra_bddImageStart(
- DdManager * dd, DdNode * bCare,
- int nParts, DdNode ** pbParts,
- int nVars, DdNode ** pbVars, int fVerbose );
-extern DdNode * Extra_bddImageCompute( Extra_ImageTree_t * pTree, DdNode * bCare );
-extern void Extra_bddImageTreeDelete( Extra_ImageTree_t * pTree );
-extern DdNode * Extra_bddImageRead( Extra_ImageTree_t * pTree );
-
-typedef struct Extra_ImageTree2_t_ Extra_ImageTree2_t;
-extern Extra_ImageTree2_t * Extra_bddImageStart2(
- DdManager * dd, DdNode * bCare,
- int nParts, DdNode ** pbParts,
- int nVars, DdNode ** pbVars, int fVerbose );
-extern DdNode * Extra_bddImageCompute2( Extra_ImageTree2_t * pTree, DdNode * bCare );
-extern void Extra_bddImageTreeDelete2( Extra_ImageTree2_t * pTree );
-extern DdNode * Extra_bddImageRead2( Extra_ImageTree2_t * pTree );
-
-/*=== extraBddMisc.c ========================================================*/
-
-extern DdNode * Extra_TransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute );
-extern DdNode * Extra_TransferLevelByLevel( DdManager * ddSource, DdManager * ddDestination, DdNode * f );
-extern DdNode * Extra_bddRemapUp( DdManager * dd, DdNode * bF );
-extern DdNode * Extra_bddMove( DdManager * dd, DdNode * bF, int nVars );
-extern DdNode * extraBddMove( DdManager * dd, DdNode * bF, DdNode * bFlag );
-extern void Extra_StopManager( DdManager * dd );
-extern void Extra_bddPrint( DdManager * dd, DdNode * F );
-extern void Extra_bddPrintSupport( DdManager * dd, DdNode * F );
-extern void extraDecomposeCover( DdManager* dd, DdNode* zC, DdNode** zC0, DdNode** zC1, DdNode** zC2 );
-extern int Extra_bddSuppSize( DdManager * dd, DdNode * bSupp );
-extern int Extra_bddSuppContainVar( DdManager * dd, DdNode * bS, DdNode * bVar );
-extern int Extra_bddSuppOverlapping( DdManager * dd, DdNode * S1, DdNode * S2 );
-extern int Extra_bddSuppDifferentVars( DdManager * dd, DdNode * S1, DdNode * S2, int DiffMax );
-extern int Extra_bddSuppCheckContainment( DdManager * dd, DdNode * bL, DdNode * bH, DdNode ** bLarge, DdNode ** bSmall );
-extern int * Extra_SupportArray( DdManager * dd, DdNode * F, int * support );
-extern int * Extra_VectorSupportArray( DdManager * dd, DdNode ** F, int n, int * support );
-extern DdNode * Extra_bddFindOneCube( DdManager * dd, DdNode * bF );
-extern DdNode * Extra_bddGetOneCube( DdManager * dd, DdNode * bFunc );
-extern DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int iStop );
-extern DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst );
-extern DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f );
-extern int Extra_bddIsVar( DdNode * bFunc );
-extern DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars );
-extern DdNode * Extra_bddCreateOr( DdManager * dd, int nVars );
-extern DdNode * Extra_bddCreateExor( DdManager * dd, int nVars );
-extern DdNode * Extra_zddPrimes( DdManager * dd, DdNode * F );
-extern void Extra_bddPermuteArray( DdManager * dd, DdNode ** bNodesIn, DdNode ** bNodesOut, int nNodes, int *permut );
-extern DdNode * Extra_bddComputeCube( DdManager * dd, DdNode ** bXVars, int nVars );
-extern DdNode * Extra_bddChangePolarity( DdManager * dd, DdNode * bFunc, DdNode * bVars );
-extern DdNode * extraBddChangePolarity( DdManager * dd, DdNode * bFunc, DdNode * bVars );
-extern int Extra_bddVarIsInCube( DdNode * bCube, int iVar );
-extern DdNode * Extra_bddAndPermute( DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute );
-extern int Extra_bddCountCubes( DdManager * dd, DdNode ** pFuncs, int nFuncs, int fMode, int nLimit, int * pGuide );
-extern void Extra_zddDumpPla( DdManager * dd, DdNode * zCover, int nVars, char * pFileName );
-
-#ifndef ABC_PRB
-#define ABC_PRB(dd,f) printf("%s = ", #f); Extra_bddPrint(dd,f); printf("\n")
-#endif
-
-/*=== extraBddKmap.c ================================================================*/
-
-/* displays the Karnaugh Map of a function */
-extern void Extra_PrintKMap( FILE * pFile, DdManager * dd, DdNode * OnSet, DdNode * OffSet, int nVars, DdNode ** XVars, int fSuppType, char ** pVarNames );
-/* displays the Karnaugh Map of a relation */
-extern void Extra_PrintKMapRelation( FILE * pFile, DdManager * dd, DdNode * OnSet, DdNode * OffSet, int nXVars, int nYVars, DdNode ** XVars, DdNode ** YVars );
-
-/*=== extraBddSymm.c =================================================================*/
-
-typedef struct Extra_SymmInfo_t_ Extra_SymmInfo_t;
-struct Extra_SymmInfo_t_ {
- int nVars; // the number of variables in the support
- int nVarsMax; // the number of variables in the DD manager
- int nSymms; // the number of pair-wise symmetries
- int nNodes; // the number of nodes in a ZDD (if applicable)
- int * pVars; // the list of all variables present in the support
- char ** pSymms; // the symmetry information
-};
-
-/* computes the classical symmetry information for the function - recursive */
-extern Extra_SymmInfo_t * Extra_SymmPairsCompute( DdManager * dd, DdNode * bFunc );
-/* computes the classical symmetry information for the function - using naive approach */
-extern Extra_SymmInfo_t * Extra_SymmPairsComputeNaive( DdManager * dd, DdNode * bFunc );
-extern int Extra_bddCheckVarsSymmetricNaive( DdManager * dd, DdNode * bF, int iVar1, int iVar2 );
-
-/* allocates the data structure */
-extern Extra_SymmInfo_t * Extra_SymmPairsAllocate( int nVars );
-/* deallocates the data structure */
-extern void Extra_SymmPairsDissolve( Extra_SymmInfo_t * );
-/* print the contents the data structure */
-extern void Extra_SymmPairsPrint( Extra_SymmInfo_t * );
-/* converts the ZDD into the Extra_SymmInfo_t structure */
-extern Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bVars );
-
-/* computes the classical symmetry information as a ZDD */
-extern DdNode * Extra_zddSymmPairsCompute( DdManager * dd, DdNode * bF, DdNode * bVars );
-extern DdNode * extraZddSymmPairsCompute( DdManager * dd, DdNode * bF, DdNode * bVars );
-/* returns a singleton-set ZDD containing all variables that are symmetric with the given one */
-extern DdNode * Extra_zddGetSymmetricVars( DdManager * dd, DdNode * bF, DdNode * bG, DdNode * bVars );
-extern DdNode * extraZddGetSymmetricVars( DdManager * dd, DdNode * bF, DdNode * bG, DdNode * bVars );
-/* converts a set of variables into a set of singleton subsets */
-extern DdNode * Extra_zddGetSingletons( DdManager * dd, DdNode * bVars );
-extern DdNode * extraZddGetSingletons( DdManager * dd, DdNode * bVars );
-/* filters the set of variables using the support of the function */
-extern DdNode * Extra_bddReduceVarSet( DdManager * dd, DdNode * bVars, DdNode * bF );
-extern DdNode * extraBddReduceVarSet( DdManager * dd, DdNode * bVars, DdNode * bF );
-
-/* checks the possibility that the two vars are symmetric */
-extern int Extra_bddCheckVarsSymmetric( DdManager * dd, DdNode * bF, int iVar1, int iVar2 );
-extern DdNode * extraBddCheckVarsSymmetric( DdManager * dd, DdNode * bF, DdNode * bVars );
-
-/* build the set of all tuples of K variables out of N from the BDD cube */
-extern DdNode * Extra_zddTuplesFromBdd( DdManager * dd, int K, DdNode * bVarsN );
-extern DdNode * extraZddTuplesFromBdd( DdManager * dd, DdNode * bVarsK, DdNode * bVarsN );
-/* selects one subset from a ZDD representing the set of subsets */
-extern DdNode * Extra_zddSelectOneSubset( DdManager * dd, DdNode * zS );
-extern DdNode * extraZddSelectOneSubset( DdManager * dd, DdNode * zS );
-
-/*=== extraBddUnate.c =================================================================*/
-
-extern DdNode * Extra_bddAndTime( DdManager * dd, DdNode * f, DdNode * g, int TimeOut );
-extern DdNode * Extra_bddAndAbstractTime( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube, int TimeOut );
-extern DdNode * Extra_TransferPermuteTime( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute, int TimeOut );
-
-/*=== extraBddUnate.c =================================================================*/
-
-typedef struct Extra_UnateVar_t_ Extra_UnateVar_t;
-struct Extra_UnateVar_t_ {
- unsigned iVar : 30; // index of the variable
- unsigned Pos : 1; // 1 if positive unate
- unsigned Neg : 1; // 1 if negative unate
-};
-
-typedef struct Extra_UnateInfo_t_ Extra_UnateInfo_t;
-struct Extra_UnateInfo_t_ {
- int nVars; // the number of variables in the support
- int nVarsMax; // the number of variables in the DD manager
- int nUnate; // the number of unate variables
- Extra_UnateVar_t * pVars; // the array of variables present in the support
-};
-
-/* allocates the data structure */
-extern Extra_UnateInfo_t * Extra_UnateInfoAllocate( int nVars );
-/* deallocates the data structure */
-extern void Extra_UnateInfoDissolve( Extra_UnateInfo_t * );
-/* print the contents the data structure */
-extern void Extra_UnateInfoPrint( Extra_UnateInfo_t * );
-/* converts the ZDD into the Extra_SymmInfo_t structure */
-extern Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd( DdManager * dd, DdNode * zUnate, DdNode * bVars );
-/* naive check of unateness of one variable */
-extern int Extra_bddCheckUnateNaive( DdManager * dd, DdNode * bF, int iVar );
-
-/* computes the unateness information for the function */
-extern Extra_UnateInfo_t * Extra_UnateComputeFast( DdManager * dd, DdNode * bFunc );
-extern Extra_UnateInfo_t * Extra_UnateComputeSlow( DdManager * dd, DdNode * bFunc );
-
-/* computes the classical symmetry information as a ZDD */
-extern DdNode * Extra_zddUnateInfoCompute( DdManager * dd, DdNode * bF, DdNode * bVars );
-extern DdNode * extraZddUnateInfoCompute( DdManager * dd, DdNode * bF, DdNode * bVars );
-
-/* converts a set of variables into a set of singleton subsets */
-extern DdNode * Extra_zddGetSingletonsBoth( DdManager * dd, DdNode * bVars );
-extern DdNode * extraZddGetSingletonsBoth( DdManager * dd, DdNode * bVars );
-
-/**AutomaticEnd***************************************************************/
-
-
-
-ABC_NAMESPACE_HEADER_END
-
-
-
-#endif /* __EXTRA_H__ */
diff --git a/src/misc/extra/extraBddAuto.c b/src/misc/extra/extraBddAuto.c
deleted file mode 100644
index 5fb38aec..00000000
--- a/src/misc/extra/extraBddAuto.c
+++ /dev/null
@@ -1,1563 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddAuto.c]
-
- PackageName [extra]
-
- Synopsis [Computation of autosymmetries.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddAuto.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticEnd***************************************************************/
-
-
-/*
- LinearSpace(f) = Space(f,f)
-
- Space(f,g)
- {
- if ( f = const )
- {
- if ( f = g ) return 1;
- else return 0;
- }
- if ( g = const ) return 0;
- return x' * Space(fx',gx') * Space(fx,gx) + x * Space(fx',gx) * Space(fx,gx');
- }
-
- Equations(s) = Pos(s) + Neg(s);
-
- Pos(s)
- {
- if ( s = 0 ) return 1;
- if ( s = 1 ) return 0;
- if ( sx'= 0 ) return Pos(sx) + x;
- if ( sx = 0 ) return Pos(sx');
- return 1 * [Pos(sx') & Pos(sx)] + x * [Pos(sx') & Neg(sx)];
- }
-
- Neg(s)
- {
- if ( s = 0 ) return 1;
- if ( s = 1 ) return 0;
- if ( sx'= 0 ) return Neg(sx);
- if ( sx = 0 ) return Neg(sx') + x;
- return 1 * [Neg(sx') & Neg(sx)] + x * [Neg(sx') & Pos(sx)];
- }
-
-
- SpaceP(A)
- {
- if ( A = 0 ) return 1;
- if ( A = 1 ) return 1;
- return x' * SpaceP(Ax') * SpaceP(Ax) + x * SpaceP(Ax') * SpaceN(Ax);
- }
-
- SpaceN(A)
- {
- if ( A = 0 ) return 1;
- if ( A = 1 ) return 0;
- return x' * SpaceN(Ax') * SpaceN(Ax) + x * SpaceN(Ax') * SpaceP(Ax);
- }
-
-
- LinInd(A)
- {
- if ( A = const ) return 1;
- if ( !LinInd(Ax') ) return 0;
- if ( !LinInd(Ax) ) return 0;
- if ( LinSumOdd(Ax') & LinSumEven(Ax) != 0 ) return 0;
- if ( LinSumEven(Ax') & LinSumEven(Ax) != 0 ) return 0;
- return 1;
- }
-
- LinSumOdd(A)
- {
- if ( A = 0 ) return 0; // Odd0 ---e-- Odd1
- if ( A = 1 ) return 1; // \ o
- Odd0 = LinSumOdd(Ax'); // x is absent // \
- Even0 = LinSumEven(Ax'); // x is absent // / o
- Odd1 = LinSumOdd(Ax); // x is present // Even0 ---e-- Even1
- Even1 = LinSumEven(Ax); // x is absent
- return 1 * [Odd0 + ExorP(Odd0, Even1)] + x * [Odd1 + ExorP(Odd1, Even0)];
- }
-
- LinSumEven(A)
- {
- if ( A = 0 ) return 0;
- if ( A = 1 ) return 0;
- Odd0 = LinSumOdd(Ax'); // x is absent
- Even0 = LinSumEven(Ax'); // x is absent
- Odd1 = LinSumOdd(Ax); // x is present
- Even1 = LinSumEven(Ax); // x is absent
- return 1 * [Even0 + Even1 + ExorP(Even0, Even1)] + x * [ExorP(Odd0, Odd1)];
- }
-
-*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromFunctionFast( DdManager * dd, DdNode * bFunc )
-{
- int * pSupport;
- int * pPermute;
- int * pPermuteBack;
- DdNode ** pCompose;
- DdNode * bCube, * bTemp;
- DdNode * bSpace, * bFunc1, * bFunc2, * bSpaceShift;
- int nSupp, Counter;
- int i, lev;
-
- // get the support
- pSupport = ABC_ALLOC( int, ddMax(dd->size,dd->sizeZ) );
- Extra_SupportArray( dd, bFunc, pSupport );
- nSupp = 0;
- for ( i = 0; i < dd->size; i++ )
- if ( pSupport[i] )
- nSupp++;
-
- // make sure the manager has enough variables
- if ( 2*nSupp > dd->size )
- {
- printf( "Cannot derive linear space, because DD manager does not have enough variables.\n" );
- fflush( stdout );
- ABC_FREE( pSupport );
- return NULL;
- }
-
- // create the permutation arrays
- pPermute = ABC_ALLOC( int, dd->size );
- pPermuteBack = ABC_ALLOC( int, dd->size );
- pCompose = ABC_ALLOC( DdNode *, dd->size );
- for ( i = 0; i < dd->size; i++ )
- {
- pPermute[i] = i;
- pPermuteBack[i] = i;
- pCompose[i] = dd->vars[i]; Cudd_Ref( pCompose[i] );
- }
-
- // remap the function in such a way that the variables are interleaved
- Counter = 0;
- bCube = b1; Cudd_Ref( bCube );
- for ( lev = 0; lev < dd->size; lev++ )
- if ( pSupport[ dd->invperm[lev] ] )
- { // var "dd->invperm[lev]" on level "lev" should go to level 2*Counter;
- pPermute[ dd->invperm[lev] ] = dd->invperm[2*Counter];
- // var from level 2*Counter+1 should go back to the place of this var
- pPermuteBack[ dd->invperm[2*Counter+1] ] = dd->invperm[lev];
- // the permutation should be defined in such a way that variable
- // on level 2*Counter is replaced by an EXOR of itself and var on the next level
- Cudd_Deref( pCompose[ dd->invperm[2*Counter] ] );
- pCompose[ dd->invperm[2*Counter] ] =
- Cudd_bddXor( dd, dd->vars[ dd->invperm[2*Counter] ], dd->vars[ dd->invperm[2*Counter+1] ] );
- Cudd_Ref( pCompose[ dd->invperm[2*Counter] ] );
- // add this variable to the cube
- bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[ dd->invperm[2*Counter] ] ); Cudd_Ref( bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- // increment the counter
- Counter ++;
- }
-
- // permute the functions
- bFunc1 = Cudd_bddPermute( dd, bFunc, pPermute ); Cudd_Ref( bFunc1 );
- // compose to gate the function depending on both vars
- bFunc2 = Cudd_bddVectorCompose( dd, bFunc1, pCompose ); Cudd_Ref( bFunc2 );
- // gate the vector space
- // L(a) = ForAll x [ F(x) = F(x+a) ] = Not( Exist x [ F(x) (+) F(x+a) ] )
- bSpaceShift = Cudd_bddXorExistAbstract( dd, bFunc1, bFunc2, bCube ); Cudd_Ref( bSpaceShift );
- bSpaceShift = Cudd_Not( bSpaceShift );
- // permute the space back into the original mapping
- bSpace = Cudd_bddPermute( dd, bSpaceShift, pPermuteBack ); Cudd_Ref( bSpace );
- Cudd_RecursiveDeref( dd, bFunc1 );
- Cudd_RecursiveDeref( dd, bFunc2 );
- Cudd_RecursiveDeref( dd, bSpaceShift );
- Cudd_RecursiveDeref( dd, bCube );
-
- for ( i = 0; i < dd->size; i++ )
- Cudd_RecursiveDeref( dd, pCompose[i] );
- ABC_FREE( pPermute );
- ABC_FREE( pPermuteBack );
- ABC_FREE( pCompose );
- ABC_FREE( pSupport );
-
- Cudd_Deref( bSpace );
- return bSpace;
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceFromFunction( dd, bF, bG );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceFromFunctionPos( dd, bFunc );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceFromFunctionNeg( dd, bFunc );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceCanonVars( DdManager * dd, DdNode * bSpace )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceCanonVars( dd, bSpace );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars )
-{
- DdNode * bNegCube;
- DdNode * bResult;
- bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars ); Cudd_Ref( bNegCube );
- bResult = Cudd_Cofactor( dd, bFunc, bNegCube ); Cudd_Ref( bResult );
- Cudd_RecursiveDeref( dd, bNegCube );
- Cudd_Deref( bResult );
- return bResult;
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceEquations( DdManager * dd, DdNode * bSpace )
-{
- DdNode * zRes;
- DdNode * zEquPos;
- DdNode * zEquNeg;
- zEquPos = Extra_bddSpaceEquationsPos( dd, bSpace ); Cudd_Ref( zEquPos );
- zEquNeg = Extra_bddSpaceEquationsNeg( dd, bSpace ); Cudd_Ref( zEquNeg );
- zRes = Cudd_zddUnion( dd, zEquPos, zEquNeg ); Cudd_Ref( zRes );
- Cudd_RecursiveDerefZdd( dd, zEquPos );
- Cudd_RecursiveDerefZdd( dd, zEquNeg );
- Cudd_Deref( zRes );
- return zRes;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceEquationsPos( DdManager * dd, DdNode * bSpace )
-{
- DdNode * zRes;
- do {
- dd->reordered = 0;
- zRes = extraBddSpaceEquationsPos( dd, bSpace );
- } while (dd->reordered == 1);
- return zRes;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace )
-{
- DdNode * zRes;
- do {
- dd->reordered = 0;
- zRes = extraBddSpaceEquationsNeg( dd, bSpace );
- } while (dd->reordered == 1);
- return zRes;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromMatrixPos( DdManager * dd, DdNode * zA )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceFromMatrixPos( dd, zA );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA )
-{
- DdNode * bRes;
- do {
- dd->reordered = 0;
- bRes = extraBddSpaceFromMatrixNeg( dd, zA );
- } while (dd->reordered == 1);
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of literals in one combination.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Extra_zddLitCountComb( DdManager * dd, DdNode * zComb )
-{
- int Counter;
- if ( zComb == z0 )
- return 0;
- Counter = 0;
- for ( ; zComb != z1; zComb = cuddT(zComb) )
- Counter++;
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description [Returns the array of ZDDs with the number equal to the number of
- vars in the DD manager. If the given var is non-canonical, this array contains
- the referenced ZDD representing literals in the corresponding EXOR equation.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode ** Extra_bddSpaceExorGates( DdManager * dd, DdNode * bFuncRed, DdNode * zEquations )
-{
- DdNode ** pzRes;
- int * pVarsNonCan;
- DdNode * zEquRem;
- int iVarNonCan;
- DdNode * zExor, * zTemp;
-
- // get the set of non-canonical variables
- pVarsNonCan = ABC_ALLOC( int, ddMax(dd->size,dd->sizeZ) );
- Extra_SupportArray( dd, bFuncRed, pVarsNonCan );
-
- // allocate storage for the EXOR sets
- pzRes = ABC_ALLOC( DdNode *, dd->size );
- memset( pzRes, 0, sizeof(DdNode *) * dd->size );
-
- // go through all the equations
- zEquRem = zEquations; Cudd_Ref( zEquRem );
- while ( zEquRem != z0 )
- {
- // extract one product
- zExor = Extra_zddSelectOneSubset( dd, zEquRem ); Cudd_Ref( zExor );
- // remove it from the set
- zEquRem = Cudd_zddDiff( dd, zTemp = zEquRem, zExor ); Cudd_Ref( zEquRem );
- Cudd_RecursiveDerefZdd( dd, zTemp );
-
- // locate the non-canonical variable
- iVarNonCan = -1;
- for ( zTemp = zExor; zTemp != z1; zTemp = cuddT(zTemp) )
- {
- if ( pVarsNonCan[zTemp->index/2] == 1 )
- {
- assert( iVarNonCan == -1 );
- iVarNonCan = zTemp->index/2;
- }
- }
- assert( iVarNonCan != -1 );
-
- if ( Extra_zddLitCountComb( dd, zExor ) > 1 )
- pzRes[ iVarNonCan ] = zExor; // takes ref
- else
- Cudd_RecursiveDerefZdd( dd, zExor );
- }
- Cudd_RecursiveDerefZdd( dd, zEquRem );
-
- ABC_FREE( pVarsNonCan );
- return pzRes;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive steps of Extra_bddSpaceFromFunction.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraBddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG )
-{
- DdNode * bRes;
- DdNode * bFR, * bGR;
-
- bFR = Cudd_Regular( bF );
- bGR = Cudd_Regular( bG );
- if ( cuddIsConstant(bFR) )
- {
- if ( bF == bG )
- return b1;
- else
- return b0;
- }
- if ( cuddIsConstant(bGR) )
- return b0;
- // both bFunc and bCore are not constants
-
- // the operation is commutative - normalize the problem
- if ( (unsigned)(ABC_PTRUINT_T)bF > (unsigned)(ABC_PTRUINT_T)bG )
- return extraBddSpaceFromFunction(dd, bG, bF);
-
-
- if ( (bRes = cuddCacheLookup2(dd, extraBddSpaceFromFunction, bF, bG)) )
- return bRes;
- else
- {
- DdNode * bF0, * bF1;
- DdNode * bG0, * bG1;
- DdNode * bTemp1, * bTemp2;
- DdNode * bRes0, * bRes1;
- int LevelF, LevelG;
- int index;
-
- LevelF = dd->perm[bFR->index];
- LevelG = dd->perm[bGR->index];
- if ( LevelF <= LevelG )
- {
- index = dd->invperm[LevelF];
- if ( bFR != bF )
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
- }
- else
- {
- index = dd->invperm[LevelG];
- bF0 = bF1 = bF;
- }
-
- if ( LevelG <= LevelF )
- {
- if ( bGR != bG )
- {
- bG0 = Cudd_Not( cuddE(bGR) );
- bG1 = Cudd_Not( cuddT(bGR) );
- }
- else
- {
- bG0 = cuddE(bGR);
- bG1 = cuddT(bGR);
- }
- }
- else
- bG0 = bG1 = bG;
-
- bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG0 );
- if ( bTemp1 == NULL )
- return NULL;
- cuddRef( bTemp1 );
-
- bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG1 );
- if ( bTemp2 == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp1 );
- return NULL;
- }
- cuddRef( bTemp2 );
-
-
- bRes0 = cuddBddAndRecur( dd, bTemp1, bTemp2 );
- if ( bRes0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp1 );
- Cudd_RecursiveDeref( dd, bTemp2 );
- return NULL;
- }
- cuddRef( bRes0 );
- Cudd_RecursiveDeref( dd, bTemp1 );
- Cudd_RecursiveDeref( dd, bTemp2 );
-
-
- bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG1 );
- if ( bTemp1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bTemp1 );
-
- bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG0 );
- if ( bTemp2 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bTemp1 );
- return NULL;
- }
- cuddRef( bTemp2 );
-
- bRes1 = cuddBddAndRecur( dd, bTemp1, bTemp2 );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bTemp1 );
- Cudd_RecursiveDeref( dd, bTemp2 );
- return NULL;
- }
- cuddRef( bRes1 );
- Cudd_RecursiveDeref( dd, bTemp1 );
- Cudd_RecursiveDeref( dd, bTemp2 );
-
-
-
- // consider the case when Res0 and Res1 are the same node
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- // consider the case when Res1 is complemented
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter(dd, index, Cudd_Not(bRes1), Cudd_Not(bRes0));
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, index, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
-
- // insert the result into cache
- cuddCacheInsert2(dd, extraBddSpaceFromFunction, bF, bG, bRes);
- return bRes;
- }
-} /* end of extraBddSpaceFromFunction */
-
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceFromFunctionPos( DdManager * dd, DdNode * bF )
-{
- DdNode * bRes, * bFR;
- statLine( dd );
-
- bFR = Cudd_Regular(bF);
- if ( cuddIsConstant(bFR) )
- return b1;
-
- if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionPos, bF)) )
- return bRes;
- else
- {
- DdNode * bF0, * bF1;
- DdNode * bPos0, * bPos1;
- DdNode * bNeg0, * bNeg1;
- DdNode * bRes0, * bRes1;
-
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
-
- bPos0 = extraBddSpaceFromFunctionPos( dd, bF0 );
- if ( bPos0 == NULL )
- return NULL;
- cuddRef( bPos0 );
-
- bPos1 = extraBddSpaceFromFunctionPos( dd, bF1 );
- if ( bPos1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bPos0 );
- return NULL;
- }
- cuddRef( bPos1 );
-
- bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 );
- if ( bRes0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bPos0 );
- Cudd_RecursiveDeref( dd, bPos1 );
- return NULL;
- }
- cuddRef( bRes0 );
- Cudd_RecursiveDeref( dd, bPos0 );
- Cudd_RecursiveDeref( dd, bPos1 );
-
-
- bNeg0 = extraBddSpaceFromFunctionNeg( dd, bF0 );
- if ( bNeg0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bNeg0 );
-
- bNeg1 = extraBddSpaceFromFunctionNeg( dd, bF1 );
- if ( bNeg1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- return NULL;
- }
- cuddRef( bNeg1 );
-
- bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- Cudd_RecursiveDeref( dd, bNeg1 );
- return NULL;
- }
- cuddRef( bRes1 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- Cudd_RecursiveDeref( dd, bNeg1 );
-
-
- // consider the case when Res0 and Res1 are the same node
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- // consider the case when Res1 is complemented
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
-
- cuddCacheInsert1( dd, extraBddSpaceFromFunctionPos, bF, bRes );
- return bRes;
- }
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceFromFunctionNeg( DdManager * dd, DdNode * bF )
-{
- DdNode * bRes, * bFR;
- statLine( dd );
-
- bFR = Cudd_Regular(bF);
- if ( cuddIsConstant(bFR) )
- return b0;
-
- if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionNeg, bF)) )
- return bRes;
- else
- {
- DdNode * bF0, * bF1;
- DdNode * bPos0, * bPos1;
- DdNode * bNeg0, * bNeg1;
- DdNode * bRes0, * bRes1;
-
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
-
- bPos0 = extraBddSpaceFromFunctionNeg( dd, bF0 );
- if ( bPos0 == NULL )
- return NULL;
- cuddRef( bPos0 );
-
- bPos1 = extraBddSpaceFromFunctionNeg( dd, bF1 );
- if ( bPos1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bPos0 );
- return NULL;
- }
- cuddRef( bPos1 );
-
- bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 );
- if ( bRes0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bPos0 );
- Cudd_RecursiveDeref( dd, bPos1 );
- return NULL;
- }
- cuddRef( bRes0 );
- Cudd_RecursiveDeref( dd, bPos0 );
- Cudd_RecursiveDeref( dd, bPos1 );
-
-
- bNeg0 = extraBddSpaceFromFunctionPos( dd, bF0 );
- if ( bNeg0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bNeg0 );
-
- bNeg1 = extraBddSpaceFromFunctionPos( dd, bF1 );
- if ( bNeg1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- return NULL;
- }
- cuddRef( bNeg1 );
-
- bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- Cudd_RecursiveDeref( dd, bNeg1 );
- return NULL;
- }
- cuddRef( bRes1 );
- Cudd_RecursiveDeref( dd, bNeg0 );
- Cudd_RecursiveDeref( dd, bNeg1 );
-
-
- // consider the case when Res0 and Res1 are the same node
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- // consider the case when Res1 is complemented
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
-
- cuddCacheInsert1( dd, extraBddSpaceFromFunctionNeg, bF, bRes );
- return bRes;
- }
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceCanonVars().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceCanonVars( DdManager * dd, DdNode * bF )
-{
- DdNode * bRes, * bFR;
- statLine( dd );
-
- bFR = Cudd_Regular(bF);
- if ( cuddIsConstant(bFR) )
- return bF;
-
- if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceCanonVars, bF)) )
- return bRes;
- else
- {
- DdNode * bF0, * bF1;
- DdNode * bRes, * bRes0;
-
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- if ( bF0 == b0 )
- {
- bRes = extraBddSpaceCanonVars( dd, bF1 );
- if ( bRes == NULL )
- return NULL;
- }
- else if ( bF1 == b0 )
- {
- bRes = extraBddSpaceCanonVars( dd, bF0 );
- if ( bRes == NULL )
- return NULL;
- }
- else
- {
- bRes0 = extraBddSpaceCanonVars( dd, bF0 );
- if ( bRes0 == NULL )
- return NULL;
- cuddRef( bRes0 );
-
- bRes = cuddUniqueInter( dd, bFR->index, bRes0, b0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref( dd,bRes0 );
- return NULL;
- }
- cuddDeref( bRes0 );
- }
-
- cuddCacheInsert1( dd, extraBddSpaceCanonVars, bF, bRes );
- return bRes;
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceEquationsPos().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceEquationsPos( DdManager * dd, DdNode * bF )
-{
- DdNode * zRes;
- statLine( dd );
-
- if ( bF == b0 )
- return z1;
- if ( bF == b1 )
- return z0;
-
- if ( (zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsPos, bF)) )
- return zRes;
- else
- {
- DdNode * bFR, * bF0, * bF1;
- DdNode * zPos0, * zPos1, * zNeg1;
- DdNode * zRes, * zRes0, * zRes1;
-
- bFR = Cudd_Regular(bF);
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- if ( bF0 == b0 )
- {
- zRes1 = extraBddSpaceEquationsPos( dd, bF1 );
- if ( zRes1 == NULL )
- return NULL;
- cuddRef( zRes1 );
-
- // add the current element to the set
- zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes1 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes1);
- return NULL;
- }
- cuddDeref( zRes1 );
- }
- else if ( bF1 == b0 )
- {
- zRes = extraBddSpaceEquationsPos( dd, bF0 );
- if ( zRes == NULL )
- return NULL;
- }
- else
- {
- zPos0 = extraBddSpaceEquationsPos( dd, bF0 );
- if ( zPos0 == NULL )
- return NULL;
- cuddRef( zPos0 );
-
- zPos1 = extraBddSpaceEquationsPos( dd, bF1 );
- if ( zPos1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zPos0);
- return NULL;
- }
- cuddRef( zPos1 );
-
- zNeg1 = extraBddSpaceEquationsNeg( dd, bF1 );
- if ( zNeg1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zNeg1 );
-
-
- zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
- if ( zRes0 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zRes0 );
-
- zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes0);
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zRes1 );
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- // only zRes0 and zRes1 are refed at this point
-
- zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes0);
- Cudd_RecursiveDerefZdd(dd, zRes1);
- return NULL;
- }
- cuddDeref( zRes0 );
- cuddDeref( zRes1 );
- }
-
- cuddCacheInsert1( dd, extraBddSpaceEquationsPos, bF, zRes );
- return zRes;
- }
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceEquationsNev().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceEquationsNeg( DdManager * dd, DdNode * bF )
-{
- DdNode * zRes;
- statLine( dd );
-
- if ( bF == b0 )
- return z1;
- if ( bF == b1 )
- return z0;
-
- if ( (zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsNeg, bF)) )
- return zRes;
- else
- {
- DdNode * bFR, * bF0, * bF1;
- DdNode * zPos0, * zPos1, * zNeg1;
- DdNode * zRes, * zRes0, * zRes1;
-
- bFR = Cudd_Regular(bF);
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- if ( bF0 == b0 )
- {
- zRes = extraBddSpaceEquationsNeg( dd, bF1 );
- if ( zRes == NULL )
- return NULL;
- }
- else if ( bF1 == b0 )
- {
- zRes0 = extraBddSpaceEquationsNeg( dd, bF0 );
- if ( zRes0 == NULL )
- return NULL;
- cuddRef( zRes0 );
-
- // add the current element to the set
- zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes0 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes0);
- return NULL;
- }
- cuddDeref( zRes0 );
- }
- else
- {
- zPos0 = extraBddSpaceEquationsNeg( dd, bF0 );
- if ( zPos0 == NULL )
- return NULL;
- cuddRef( zPos0 );
-
- zPos1 = extraBddSpaceEquationsNeg( dd, bF1 );
- if ( zPos1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zPos0);
- return NULL;
- }
- cuddRef( zPos1 );
-
- zNeg1 = extraBddSpaceEquationsPos( dd, bF1 );
- if ( zNeg1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zNeg1 );
-
-
- zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
- if ( zRes0 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zRes0 );
-
- zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes0);
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- return NULL;
- }
- cuddRef( zRes1 );
- Cudd_RecursiveDerefZdd(dd, zNeg1);
- Cudd_RecursiveDerefZdd(dd, zPos0);
- Cudd_RecursiveDerefZdd(dd, zPos1);
- // only zRes0 and zRes1 are refed at this point
-
- zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zRes0);
- Cudd_RecursiveDerefZdd(dd, zRes1);
- return NULL;
- }
- cuddDeref( zRes0 );
- cuddDeref( zRes1 );
- }
-
- cuddCacheInsert1( dd, extraBddSpaceEquationsNeg, bF, zRes );
- return zRes;
- }
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceFromMatrixPos( DdManager * dd, DdNode * zA )
-{
- DdNode * bRes;
- statLine( dd );
-
- if ( zA == z0 )
- return b1;
- if ( zA == z1 )
- return b1;
-
- if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixPos, zA)) )
- return bRes;
- else
- {
- DdNode * bP0, * bP1;
- DdNode * bN0, * bN1;
- DdNode * bRes0, * bRes1;
-
- bP0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
- if ( bP0 == NULL )
- return NULL;
- cuddRef( bP0 );
-
- bP1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
- if ( bP1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bP0 );
- return NULL;
- }
- cuddRef( bP1 );
-
- bRes0 = cuddBddAndRecur( dd, bP0, bP1 );
- if ( bRes0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bP0 );
- Cudd_RecursiveDeref( dd, bP1 );
- return NULL;
- }
- cuddRef( bRes0 );
- Cudd_RecursiveDeref( dd, bP0 );
- Cudd_RecursiveDeref( dd, bP1 );
-
-
- bN0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
- if ( bN0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bN0 );
-
- bN1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
- if ( bN1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bN0 );
- return NULL;
- }
- cuddRef( bN1 );
-
- bRes1 = cuddBddAndRecur( dd, bN0, bN1 );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bN0 );
- Cudd_RecursiveDeref( dd, bN1 );
- return NULL;
- }
- cuddRef( bRes1 );
- Cudd_RecursiveDeref( dd, bN0 );
- Cudd_RecursiveDeref( dd, bN1 );
-
-
- // consider the case when Res0 and Res1 are the same node
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- // consider the case when Res1 is complemented
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
-
- cuddCacheInsert1( dd, extraBddSpaceFromMatrixPos, zA, bRes );
- return bRes;
- }
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA )
-{
- DdNode * bRes;
- statLine( dd );
-
- if ( zA == z0 )
- return b1;
- if ( zA == z1 )
- return b0;
-
- if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixNeg, zA)) )
- return bRes;
- else
- {
- DdNode * bP0, * bP1;
- DdNode * bN0, * bN1;
- DdNode * bRes0, * bRes1;
-
- bP0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
- if ( bP0 == NULL )
- return NULL;
- cuddRef( bP0 );
-
- bP1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
- if ( bP1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bP0 );
- return NULL;
- }
- cuddRef( bP1 );
-
- bRes0 = cuddBddAndRecur( dd, bP0, bP1 );
- if ( bRes0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bP0 );
- Cudd_RecursiveDeref( dd, bP1 );
- return NULL;
- }
- cuddRef( bRes0 );
- Cudd_RecursiveDeref( dd, bP0 );
- Cudd_RecursiveDeref( dd, bP1 );
-
-
- bN0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
- if ( bN0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bN0 );
-
- bN1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
- if ( bN1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bN0 );
- return NULL;
- }
- cuddRef( bN1 );
-
- bRes1 = cuddBddAndRecur( dd, bN0, bN1 );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bN0 );
- Cudd_RecursiveDeref( dd, bN1 );
- return NULL;
- }
- cuddRef( bRes1 );
- Cudd_RecursiveDeref( dd, bN0 );
- Cudd_RecursiveDeref( dd, bN1 );
-
-
- // consider the case when Res0 and Res1 are the same node
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- // consider the case when Res1 is complemented
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
-
- cuddCacheInsert1( dd, extraBddSpaceFromMatrixNeg, zA, bRes );
- return bRes;
- }
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddCas.c b/src/misc/extra/extraBddCas.c
deleted file mode 100644
index 024e4462..00000000
--- a/src/misc/extra/extraBddCas.c
+++ /dev/null
@@ -1,1235 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddCas.c]
-
- PackageName [extra]
-
- Synopsis [Procedures related to LUT cascade synthesis.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddCas.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-// the table to store cofactor operations
-#define _TABLESIZE_COF 51113
-typedef struct
-{
- unsigned Sign;
- DdNode * Arg1;
-} _HashEntry_cof;
-_HashEntry_cof HHTable1[_TABLESIZE_COF];
-
-// the table to store the result of computation of the number of minterms
-#define _TABLESIZE_MINT 15113
-typedef struct
-{
- DdNode * Arg1;
- unsigned Arg2;
- unsigned Res;
-} _HashEntry_mint;
-_HashEntry_mint HHTable2[_TABLESIZE_MINT];
-
-typedef struct
-{
- int nEdges; // the number of in-coming edges of the node
- DdNode * bSum; // the sum of paths of the incoming edges
-} traventry;
-
-// the signature used for hashing
-static unsigned s_Signature = 1;
-
-static int s_CutLevel = 0;
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-// because the proposed solution to the optimal encoding problem has exponential complexity
-// we limit the depth of the branch and bound procedure to 5 levels
-static int s_MaxDepth = 5;
-
-static int s_nVarsBest; // the number of vars in the best ordering
-static int s_VarOrderBest[32]; // storing the best ordering of vars in the "simple encoding"
-static int s_VarOrderCur[32]; // storing the current ordering of vars
-
-// the place to store the supports of the encoded function
-static DdNode * s_Field[8][256]; // the size should be K, 2^K, where K is no less than MaxDepth
-static DdNode * s_Encoded; // this is the original function
-static DdNode * s_VarAll; // the set of all column variables
-static int s_MultiStart; // the total number of encoding variables used
-// the array field now stores the supports
-
-static DdNode ** s_pbTemp; // the temporary storage for the columns
-
-static int s_BackTracks;
-static int s_BackTrackLimit = 100;
-
-static DdNode * s_Terminal; // the terminal value for counting minterms
-
-
-static int s_EncodingVarsLevel;
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * CreateTheCodes_rec( DdManager * dd, DdNode * bEncoded, int Level, DdNode ** pCVars );
-static void EvaluateEncodings_rec( DdManager * dd, DdNode * bVarsCol, int nVarsCol, int nMulti, int Level );
-// functions called from EvaluateEncodings_rec()
-static DdNode * ComputeVarSetAndCountMinterms( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost );
-static DdNode * ComputeVarSetAndCountMinterms2( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost );
-unsigned Extra_CountCofactorMinterms( DdManager * dd, DdNode * bFunc, DdNode * bVarsCof, DdNode * bVarsAll );
-static unsigned Extra_CountMintermsSimple( DdNode * bFunc, unsigned max );
-
-static void CountNodeVisits_rec( DdManager * dd, DdNode * aFunc, st__table * Visited );
-static void CollectNodesAndComputePaths_rec( DdManager * dd, DdNode * aFunc, DdNode * bCube, st__table * Visited, st__table * CutNodes );
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs the binary encoding of the set of function using the given vars.]
-
- Description [Performs a straight binary encoding of the set of functions using
- the variable cubes formed from the given set of variables. ]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-Extra_bddEncodingBinary(
- DdManager * dd,
- DdNode ** pbFuncs, // pbFuncs is the array of columns to be encoded
- int nFuncs, // nFuncs is the number of columns in the array
- DdNode ** pbVars, // pbVars is the array of variables to use for the codes
- int nVars ) // nVars is the column multiplicity, [log2(nFuncs)]
-{
- int i;
- DdNode * bResult;
- DdNode * bCube, * bTemp, * bProd;
-
- assert( nVars >= Abc_Base2Log(nFuncs) );
-
- bResult = b0; Cudd_Ref( bResult );
- for ( i = 0; i < nFuncs; i++ )
- {
- bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube );
- bProd = Cudd_bddAnd( dd, bCube, pbFuncs[i] ); Cudd_Ref( bProd );
- Cudd_RecursiveDeref( dd, bCube );
-
- bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bProd );
- }
-
- Cudd_Deref( bResult );
- return bResult;
-} /* end of Extra_bddEncodingBinary */
-
-
-/**Function********************************************************************
-
- Synopsis [Solves the column encoding problem using a sophisticated method.]
-
- Description [The encoding is based on the idea of deriving functions which
- depend on only one variable, which corresponds to the case of non-disjoint
- decompostion. It is assumed that the variables pCVars are ordered below the variables
- representing the solumns, and the first variable pCVars[0] is the topmost one.]
-
- SideEffects []
-
- SeeAlso [Extra_bddEncodingBinary]
-
-******************************************************************************/
-
-DdNode *
-Extra_bddEncodingNonStrict(
- DdManager * dd,
- DdNode ** pbColumns, // pbColumns is the array of columns to be encoded;
- int nColumns, // nColumns is the number of columns in the array
- DdNode * bVarsCol, // bVarsCol is the cube of variables on which the columns depend
- DdNode ** pCVars, // pCVars is the array of variables to use for the codes
- int nMulti, // nMulti is the column multiplicity, [log2(nColumns)]
- int * pSimple ) // pSimple gets the number of code variables taken from the input varibles without change
-{
- DdNode * bEncoded, * bResult;
- int nVarsCol = Cudd_SupportSize(dd,bVarsCol);
- abctime clk;
-
- // cannot work with more that 32-bit codes
- assert( nMulti < 32 );
-
- // perform the preliminary encoding using the straight binary code
- bEncoded = Extra_bddEncodingBinary( dd, pbColumns, nColumns, pCVars, nMulti ); Cudd_Ref( bEncoded );
- //printf( "Node count = %d", Cudd_DagSize(bEncoded) );
-
- // set the backgroup value for counting minterms
- s_Terminal = b0;
- // set the level of the encoding variables
- s_EncodingVarsLevel = dd->invperm[pCVars[0]->index];
-
- // the current number of backtracks
- s_BackTracks = 0;
- // the variables that are cofactored on the topmost level where everything starts (no vars)
- s_Field[0][0] = b1;
- // the size of the best set of "simple" encoding variables found so far
- s_nVarsBest = 0;
-
- // set the relation to be accessible to traversal procedures
- s_Encoded = bEncoded;
- // the set of all vars to be accessible to traversal procedures
- s_VarAll = bVarsCol;
- // the column multiplicity
- s_MultiStart = nMulti;
-
-
- clk = Abc_Clock();
- // find the simplest encoding
- if ( nColumns > 2 )
- EvaluateEncodings_rec( dd, bVarsCol, nVarsCol, nMulti, 1 );
-// printf( "The number of backtracks = %d\n", s_BackTracks );
-// s_EncSearchTime += Abc_Clock() - clk;
-
- // allocate the temporary storage for the columns
- s_pbTemp = (DdNode **)ABC_ALLOC( char, nColumns * sizeof(DdNode *) );
-
-// clk = Abc_Clock();
- bResult = CreateTheCodes_rec( dd, bEncoded, 0, pCVars ); Cudd_Ref( bResult );
-// s_EncComputeTime += Abc_Clock() - clk;
-
- // delocate the preliminarily encoded set
- Cudd_RecursiveDeref( dd, bEncoded );
-// Cudd_RecursiveDeref( dd, aEncoded );
-
- ABC_FREE( s_pbTemp );
-
- *pSimple = s_nVarsBest;
- Cudd_Deref( bResult );
- return bResult;
-}
-
-/**Function********************************************************************
-
- Synopsis [Collects the nodes under the cut and, for each node, computes the sum of paths leading to it from the root.]
-
- Description [The table returned contains the set of BDD nodes pointed to under the cut
- and, for each node, the BDD of the sum of paths leading to this node from the root
- The sums of paths in the table are referenced. CutLevel is the first DD level
- considered to be under the cut.]
-
- SideEffects []
-
- SeeAlso [Extra_bddNodePaths]
-
-******************************************************************************/
- st__table * Extra_bddNodePathsUnderCut( DdManager * dd, DdNode * bFunc, int CutLevel )
-{
- st__table * Visited; // temporary table to remember the visited nodes
- st__table * CutNodes; // the result goes here
- st__table * Result; // the result goes here
- DdNode * aFunc;
-
- s_CutLevel = CutLevel;
-
- Result = st__init_table( st__ptrcmp, st__ptrhash);;
- // the terminal cases
- if ( Cudd_IsConstant( bFunc ) )
- {
- if ( bFunc == b1 )
- {
- st__insert( Result, (char*)b1, (char*)b1 );
- Cudd_Ref( b1 );
- Cudd_Ref( b1 );
- }
- else
- {
- st__insert( Result, (char*)b0, (char*)b0 );
- Cudd_Ref( b0 );
- Cudd_Ref( b0 );
- }
- return Result;
- }
-
- // create the ADD to simplify processing (no complemented edges)
- aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
-
- // Step 1: Start the tables and collect information about the nodes above the cut
- // this information tells how many edges point to each node
- Visited = st__init_table( st__ptrcmp, st__ptrhash);;
- CutNodes = st__init_table( st__ptrcmp, st__ptrhash);;
-
- CountNodeVisits_rec( dd, aFunc, Visited );
-
- // Step 2: Traverse the BDD using the visited table and compute the sum of paths
- CollectNodesAndComputePaths_rec( dd, aFunc, b1, Visited, CutNodes );
-
- // at this point the table of cut nodes is ready and the table of visited is useless
- {
- st__generator * gen;
- DdNode * aNode;
- traventry * p;
- st__foreach_item( Visited, gen, (const char**)&aNode, (char**)&p )
- {
- Cudd_RecursiveDeref( dd, p->bSum );
- ABC_FREE( p );
- }
- st__free_table( Visited );
- }
-
- // go through the table CutNodes and create the BDD and the path to be returned
- {
- st__generator * gen;
- DdNode * aNode, * bNode, * bSum;
- st__foreach_item( CutNodes, gen, (const char**)&aNode, (char**)&bSum)
- {
- // aNode is not referenced, because aFunc is holding it
- bNode = Cudd_addBddPattern( dd, aNode ); Cudd_Ref( bNode );
- st__insert( Result, (char*)bNode, (char*)bSum );
- // the new table takes both refs
- }
- st__free_table( CutNodes );
- }
-
- // dereference the ADD
- Cudd_RecursiveDeref( dd, aFunc );
-
- // return the table
- return Result;
-
-} /* end of Extra_bddNodePathsUnderCut */
-
-/**Function********************************************************************
-
- Synopsis [Collects the nodes under the cut in the ADD starting from the given set of ADD nodes.]
-
- Description [Takes the array, paNodes, of ADD nodes to start the traversal,
- the array, pbCubes, of BDD cubes to start the traversal with in each node,
- and the number, nNodes, of ADD nodes and BDD cubes in paNodes and pbCubes.
- Returns the number of columns found. Fills in paNodesRes (pbCubesRes)
- with the set of ADD columns (BDD paths). These arrays should be allocated
- by the user.]
-
- SideEffects []
-
- SeeAlso [Extra_bddNodePaths]
-
-******************************************************************************/
-int Extra_bddNodePathsUnderCutArray( DdManager * dd, DdNode ** paNodes, DdNode ** pbCubes, int nNodes, DdNode ** paNodesRes, DdNode ** pbCubesRes, int CutLevel )
-{
- st__table * Visited; // temporary table to remember the visited nodes
- st__table * CutNodes; // the nodes under the cut go here
- int i, Counter;
-
- s_CutLevel = CutLevel;
-
- // there should be some nodes
- assert( nNodes > 0 );
- if ( nNodes == 1 && Cudd_IsConstant( paNodes[0] ) )
- {
- if ( paNodes[0] == a1 )
- {
- paNodesRes[0] = a1; Cudd_Ref( a1 );
- pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
- }
- else
- {
- paNodesRes[0] = a0; Cudd_Ref( a0 );
- pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
- }
- return 1;
- }
-
- // Step 1: Start the table and collect information about the nodes above the cut
- // this information tells how many edges point to each node
- CutNodes = st__init_table( st__ptrcmp, st__ptrhash);;
- Visited = st__init_table( st__ptrcmp, st__ptrhash);;
-
- for ( i = 0; i < nNodes; i++ )
- CountNodeVisits_rec( dd, paNodes[i], Visited );
-
- // Step 2: Traverse the BDD using the visited table and compute the sum of paths
- for ( i = 0; i < nNodes; i++ )
- CollectNodesAndComputePaths_rec( dd, paNodes[i], pbCubes[i], Visited, CutNodes );
-
- // at this point, the table of cut nodes is ready and the table of visited is useless
- {
- st__generator * gen;
- DdNode * aNode;
- traventry * p;
- st__foreach_item( Visited, gen, (const char**)&aNode, (char**)&p )
- {
- Cudd_RecursiveDeref( dd, p->bSum );
- ABC_FREE( p );
- }
- st__free_table( Visited );
- }
-
- // go through the table CutNodes and create the BDD and the path to be returned
- {
- st__generator * gen;
- DdNode * aNode, * bSum;
- Counter = 0;
- st__foreach_item( CutNodes, gen, (const char**)&aNode, (char**)&bSum)
- {
- paNodesRes[Counter] = aNode; Cudd_Ref( aNode );
- pbCubesRes[Counter] = bSum;
- Counter++;
- }
- st__free_table( CutNodes );
- }
-
- // return the number of cofactors found
- return Counter;
-
-} /* end of Extra_bddNodePathsUnderCutArray */
-
-/**Function*************************************************************
-
- Synopsis [Collects all the BDD nodes into the table.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void extraCollectNodes( DdNode * Func, st__table * tNodes )
-{
- DdNode * FuncR;
- FuncR = Cudd_Regular(Func);
- if ( st__find_or_add( tNodes, (char*)FuncR, NULL ) )
- return;
- if ( cuddIsConstant(FuncR) )
- return;
- extraCollectNodes( cuddE(FuncR), tNodes );
- extraCollectNodes( cuddT(FuncR), tNodes );
-}
-
-/**Function*************************************************************
-
- Synopsis [Collects all the nodes of one DD into the table.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
- st__table * Extra_CollectNodes( DdNode * Func )
-{
- st__table * tNodes;
- tNodes = st__init_table( st__ptrcmp, st__ptrhash );
- extraCollectNodes( Func, tNodes );
- return tNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Updates the topmost level from which the given node is referenced.]
-
- Description [Takes the table which maps each BDD nodes (including the constants)
- into the topmost level on which this node counts as a cofactor. Takes the topmost
- level, on which this node counts as a cofactor (see Extra_ProfileWidthFast().
- Takes the node, for which the table entry should be updated.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void extraProfileUpdateTopLevel( st__table * tNodeTopRef, int TopLevelNew, DdNode * node )
-{
- int * pTopLevel;
-
- if ( st__find_or_add( tNodeTopRef, (char*)node, (char***)&pTopLevel ) )
- { // the node is already referenced
- // the current top level should be updated if it is larger than the new level
- if ( *pTopLevel > TopLevelNew )
- *pTopLevel = TopLevelNew;
- }
- else
- { // the node is not referenced
- // its level should be set to the current new level
- *pTopLevel = TopLevelNew;
- }
-}
-/**Function*************************************************************
-
- Synopsis [Fast computation of the BDD profile.]
-
- Description [The array to store the profile is given by the user and should
- contain at least as many entries as there is the maximum of the BDD/ZDD
- size of the manager PLUS ONE.
- When we say that the widths of the DD on level L is W, we mean the following.
- Let us create the cut between the level L-1 and the level L and count the number
- of different DD nodes pointed to across the cut. This number is the width W.
- From this it follows the on level 0, the width is equal to the number of external
- pointers to the considered DDs. If there is only one DD, then the profile on
- level 0 is always 1. If this DD is rooted in the topmost variable, then the width
- on level 1 is always 2, etc. The width at the level equal to dd->size is the
- number of terminal nodes in the DD. (Because we consider the first level #0
- and the last level #dd->size, the profile array should contain dd->size+1 entries.)
- ]
-
- SideEffects [This procedure will not work for BDDs w/ complement edges, only for ADDs and ZDDs]
-
- SeeAlso []
-
-***********************************************************************/
-int Extra_ProfileWidth( DdManager * dd, DdNode * Func, int * pProfile, int CutLevel )
-{
- st__generator * gen;
- st__table * tNodeTopRef; // this table stores the top level from which this node is pointed to
- st__table * tNodes;
- DdNode * node;
- DdNode * nodeR;
- int LevelStart, Limit;
- int i, size;
- int WidthMax;
-
- // start the mapping table
- tNodeTopRef = st__init_table( st__ptrcmp, st__ptrhash);;
- // add the topmost node to the profile
- extraProfileUpdateTopLevel( tNodeTopRef, 0, Func );
-
- // collect all nodes
- tNodes = Extra_CollectNodes( Func );
- // go though all the nodes and set the top level the cofactors are pointed from
-// Cudd_ForeachNode( dd, Func, genDD, node )
- st__foreach_item( tNodes, gen, (const char**)&node, NULL )
- {
-// assert( Cudd_Regular(node) ); // this procedure works only with ADD/ZDD (not BDD w/ compl.edges)
- nodeR = Cudd_Regular(node);
- if ( cuddIsConstant(nodeR) )
- continue;
- // this node is not a constant - consider its cofactors
- extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddE(nodeR) );
- extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddT(nodeR) );
- }
- st__free_table( tNodes );
-
- // clean the profile
- size = ddMax(dd->size, dd->sizeZ) + 1;
- for ( i = 0; i < size; i++ )
- pProfile[i] = 0;
-
- // create the profile
- st__foreach_item( tNodeTopRef, gen, (const char**)&node, (char**)&LevelStart )
- {
- nodeR = Cudd_Regular(node);
- Limit = (cuddIsConstant(nodeR))? dd->size: dd->perm[nodeR->index];
- for ( i = LevelStart; i <= Limit; i++ )
- pProfile[i]++;
- }
-
- if ( CutLevel != -1 && CutLevel != 0 )
- size = CutLevel;
-
- // get the max width
- WidthMax = 0;
- for ( i = 0; i < size; i++ )
- if ( WidthMax < pProfile[i] )
- WidthMax = pProfile[i];
-
- // deref the table
- st__free_table( tNodeTopRef );
-
- return WidthMax;
-} /* end of Extra_ProfileWidth */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Computes the non-strict codes when evaluation is finished.]
-
- Description [The information about the best code is stored in s_VarOrderBest,
- which has s_nVarsBest entries.]
-
- SideEffects [None]
-
-******************************************************************************/
-DdNode * CreateTheCodes_rec( DdManager * dd, DdNode * bEncoded, int Level, DdNode ** pCVars )
-// bEncoded is the preliminarily encoded set of columns
-// Level is the current level in the recursion
-// pCVars are the variables to be used for encoding
-{
- DdNode * bRes;
- if ( Level == s_nVarsBest )
- { // the terminal case, when we need to remap the encoded function
- // from the preliminary encoded variables to the new ones
- st__table * CutNodes;
- int nCols;
-// double nMints;
-/*
-#ifdef _DEBUG
-
- {
- DdNode * bTemp;
- // make sure that the given number of variables is enough
- bTemp = Cudd_bddExistAbstract( dd, bEncoded, s_VarAll ); Cudd_Ref( bTemp );
-// nMints = Cudd_CountMinterm( dd, bTemp, s_MultiStart );
- nMints = Extra_CountMintermsSimple( bTemp, (1<<s_MultiStart) );
- if ( nMints > Extra_Power2( s_MultiStart-Level ) )
- { // the number of minterms is too large to encode the columns
- // using the given minimum number of encoding variables
- assert( 0 );
- }
- Cudd_RecursiveDeref( dd, bTemp );
- }
-#endif
-*/
- // get the columns to be re-encoded
- CutNodes = Extra_bddNodePathsUnderCut( dd, bEncoded, s_EncodingVarsLevel );
- // LUT size is the cut level because because the temporary encoding variables
- // are above the functional variables - this is not true!!!
- // the temporary variables are below!
-
- // put the entries from the table into the temporary array
- {
- st__generator * gen;
- DdNode * bColumn, * bCode;
- nCols = 0;
- st__foreach_item( CutNodes, gen, (const char**)&bCode, (char**)&bColumn )
- {
- if ( bCode == b0 )
- { // the unused part of the columns
- Cudd_RecursiveDeref( dd, bColumn );
- Cudd_RecursiveDeref( dd, bCode );
- continue;
- }
- else
- {
- s_pbTemp[ nCols ] = bColumn; // takes ref
- Cudd_RecursiveDeref( dd, bCode );
- nCols++;
- }
- }
- st__free_table( CutNodes );
-// assert( nCols == (int)nMints );
- }
-
- // encode the columns
- if ( s_MultiStart-Level == 0 ) // we reached the bottom level of recursion
- {
- assert( nCols == 1 );
-// assert( (int)nMints == 1 );
- bRes = s_pbTemp[0]; Cudd_Ref( bRes );
- }
- else
- {
- bRes = Extra_bddEncodingBinary( dd, s_pbTemp, nCols, pCVars+Level, s_MultiStart-Level ); Cudd_Ref( bRes );
- }
-
- // deref the columns
- {
- int i;
- for ( i = 0; i < nCols; i++ )
- Cudd_RecursiveDeref( dd, s_pbTemp[i] );
- }
- }
- else
- {
- // cofactor the problem as specified in the best solution
- DdNode * bCof0, * bCof1;
- DdNode * bRes0, * bRes1;
- DdNode * bProd0, * bProd1;
- DdNode * bTemp;
- DdNode * bVarNext = dd->vars[ s_VarOrderBest[Level] ];
-
- bCof0 = Cudd_Cofactor( dd, bEncoded, Cudd_Not( bVarNext ) ); Cudd_Ref( bCof0 );
- bCof1 = Cudd_Cofactor( dd, bEncoded, bVarNext ); Cudd_Ref( bCof1 );
-
- // call recursively
- bRes0 = CreateTheCodes_rec( dd, bCof0, Level+1, pCVars ); Cudd_Ref( bRes0 );
- bRes1 = CreateTheCodes_rec( dd, bCof1, Level+1, pCVars ); Cudd_Ref( bRes1 );
-
- Cudd_RecursiveDeref( dd, bCof0 );
- Cudd_RecursiveDeref( dd, bCof1 );
-
- // compose the result using the identity (bVarNext <=> pCVars[Level]) - this is wrong!
- // compose the result as follows: x'y'F0 + xyF1
- bProd0 = Cudd_bddAnd( dd, Cudd_Not(bVarNext), Cudd_Not(pCVars[Level]) ); Cudd_Ref( bProd0 );
- bProd1 = Cudd_bddAnd( dd, bVarNext , pCVars[Level] ); Cudd_Ref( bProd1 );
-
- bProd0 = Cudd_bddAnd( dd, bTemp = bProd0, bRes0 ); Cudd_Ref( bProd0 );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bRes0 );
-
- bProd1 = Cudd_bddAnd( dd, bTemp = bProd1, bRes1 ); Cudd_Ref( bProd1 );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bRes1 );
-
- bRes = Cudd_bddOr( dd, bProd0, bProd1 ); Cudd_Ref( bRes );
-
- Cudd_RecursiveDeref( dd, bProd0 );
- Cudd_RecursiveDeref( dd, bProd1 );
- }
- Cudd_Deref( bRes );
- return bRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Computes the current set of variables and counts the number of minterms.]
-
- Description [Old implementation.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void EvaluateEncodings_rec( DdManager * dd, DdNode * bVarsCol, int nVarsCol, int nMulti, int Level )
-// bVarsCol is the set of remaining variables
-// nVarsCol is the number of remaining variables
-// nMulti is the number of encoding variables to be used
-// Level is the level of recursion, from which this function is called
-// if we successfully finish this procedure, Level also stands for how many encoding variabled we saved
-{
- int i, k;
- int nEntries = (1<<(Level-1)); // the number of entries in the field of the previous level
- DdNode * bVars0, * bVars1; // the cofactors
- unsigned nMint0, nMint1; // the number of minterms
- DdNode * bTempV;
- DdNode * bVarTop;
- int fBreak;
-
-
- // there is no need to search above this level
- if ( Level > s_MaxDepth )
- return;
-
- // if there are no variables left, quit the research
- if ( bVarsCol == b1 )
- return;
-
- if ( s_BackTracks > s_BackTrackLimit )
- return;
-
- s_BackTracks++;
-
- // otherwise, go through the remaining variables
- for ( bTempV = bVarsCol; bTempV != b1; bTempV = cuddT(bTempV) )
- {
- // the currently tested variable
- bVarTop = dd->vars[bTempV->index];
-
- // put it into the array
- s_VarOrderCur[Level-1] = bTempV->index;
-
- // go through the entries and fill them out by cofactoring
- fBreak = 0;
- for ( i = 0; i < nEntries; i++ )
- {
- bVars0 = ComputeVarSetAndCountMinterms( dd, s_Field[Level-1][i], Cudd_Not(bVarTop), &nMint0 );
- Cudd_Ref( bVars0 );
-
- if ( nMint0 > Extra_Power2( nMulti-1 ) )
- {
- // there is no way to encode - dereference and return
- Cudd_RecursiveDeref( dd, bVars0 );
- fBreak = 1;
- break;
- }
-
- bVars1 = ComputeVarSetAndCountMinterms( dd, s_Field[Level-1][i], bVarTop, &nMint1 );
- Cudd_Ref( bVars1 );
-
- if ( nMint1 > Extra_Power2( nMulti-1 ) )
- {
- // there is no way to encode - dereference and return
- Cudd_RecursiveDeref( dd, bVars0 );
- Cudd_RecursiveDeref( dd, bVars1 );
- fBreak = 1;
- break;
- }
-
- // otherwise, add these two cofactors
- s_Field[Level][2*i + 0] = bVars0; // takes ref
- s_Field[Level][2*i + 1] = bVars1; // takes ref
- }
-
- if ( !fBreak )
- {
- DdNode * bVarsRem;
- // if we ended up here, it means that the cofactors w.r.t. variable bVarTop satisfy the condition
- // save this situation
- if ( s_nVarsBest < Level )
- {
- s_nVarsBest = Level;
- // copy the variable assignment
- for ( k = 0; k < Level; k++ )
- s_VarOrderBest[k] = s_VarOrderCur[k];
- }
-
- // call recursively
- // get the new variable set
- if ( nMulti-1 > 0 )
- {
- bVarsRem = Cudd_bddExistAbstract( dd, bVarsCol, bVarTop ); Cudd_Ref( bVarsRem );
- EvaluateEncodings_rec( dd, bVarsRem, nVarsCol-1, nMulti-1, Level+1 );
- Cudd_RecursiveDeref( dd, bVarsRem );
- }
- }
-
- // deref the contents of the array
- for ( k = 0; k < i; k++ )
- {
- Cudd_RecursiveDeref( dd, s_Field[Level][2*k + 0] );
- Cudd_RecursiveDeref( dd, s_Field[Level][2*k + 1] );
- }
-
- // if the solution is found, there is no need to continue
- if ( s_nVarsBest == s_MaxDepth )
- return;
-
- // if the solution is found, there is no need to continue
- if ( s_nVarsBest == s_MultiStart )
- return;
- }
- // at this point, we have tried all possible directions in the space of variables
-}
-
-/**Function********************************************************************
-
- Synopsis [Computes the current set of variables and counts the number of minterms.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * ComputeVarSetAndCountMinterms( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost )
-// takes bVars - the variables cofactored so far (some of them may be in negative polarity)
-// bVarTop - the topmost variable w.r.t. which to cofactor (may be in negative polarity)
-// returns the cost and the new set of variables (bVars & bVarTop)
-{
- DdNode * bVarsRes;
-
- // get the resulting set of variables
- bVarsRes = Cudd_bddAnd( dd, bVars, bVarTop ); Cudd_Ref( bVarsRes );
-
- // increment signature before calling Cudd_CountCofactorMinterms()
- s_Signature++;
- *Cost = Extra_CountCofactorMinterms( dd, s_Encoded, bVarsRes, s_VarAll );
-
- Cudd_Deref( bVarsRes );
-// s_CountCalls++;
- return bVarsRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Computes the current set of variables and counts the number of minterms.]
-
- Description [The old implementation, which is approximately 4 times slower.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * ComputeVarSetAndCountMinterms2( DdManager * dd, DdNode * bVars, DdNode * bVarTop, unsigned * Cost )
-{
- DdNode * bVarsRes;
- DdNode * bCof, * bFun;
-
- bVarsRes = Cudd_bddAnd( dd, bVars, bVarTop ); Cudd_Ref( bVarsRes );
-
- bCof = Cudd_Cofactor( dd, s_Encoded, bVarsRes ); Cudd_Ref( bCof );
- bFun = Cudd_bddExistAbstract( dd, bCof, s_VarAll ); Cudd_Ref( bFun );
- *Cost = (unsigned)Cudd_CountMinterm( dd, bFun, s_MultiStart );
- Cudd_RecursiveDeref( dd, bFun );
- Cudd_RecursiveDeref( dd, bCof );
-
- Cudd_Deref( bVarsRes );
-// s_CountCalls++;
- return bVarsRes;
-}
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of encoding minterms pointed to by the cofactor of the function.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-unsigned Extra_CountCofactorMinterms( DdManager * dd, DdNode * bFunc, DdNode * bVarsCof, DdNode * bVarsAll )
-// this function computes how many minterms depending on the encoding variables
-// are there in the cofactor of bFunc w.r.t. variables bVarsCof
-// bFunc is assumed to depend on variables s_VarsAll
-// the variables s_VarsAll should be ordered above the encoding variables
-{
- unsigned HKey;
- DdNode * bFuncR;
-
- // if the function is zero, there are no minterms
-// if ( bFunc == b0 )
-// return 0;
-
-// if ( st__lookup(Visited, (char*)bFunc, NULL) )
-// return 0;
-
-// HKey = hashKey2c( s_Signature, bFuncR );
-// if ( HHTable1[HKey].Sign == s_Signature && HHTable1[HKey].Arg1 == bFuncR ) // this node is visited
-// return 0;
-
-
- // check the hash-table
- bFuncR = Cudd_Regular(bFunc);
-// HKey = hashKey2( s_Signature, bFuncR, _TABLESIZE_COF );
- HKey = hashKey2( s_Signature, bFunc, _TABLESIZE_COF );
- for ( ; HHTable1[HKey].Sign == s_Signature; HKey = (HKey+1) % _TABLESIZE_COF )
-// if ( HHTable1[HKey].Arg1 == bFuncR ) // this node is visited
- if ( HHTable1[HKey].Arg1 == bFunc ) // this node is visited
- return 0;
-
-
- // if the function is already the code
- if ( dd->perm[bFuncR->index] >= s_EncodingVarsLevel )
- {
-// st__insert(Visited, (char*)bFunc, NULL);
-
-// HHTable1[HKey].Sign = s_Signature;
-// HHTable1[HKey].Arg1 = bFuncR;
-
- assert( HHTable1[HKey].Sign != s_Signature );
- HHTable1[HKey].Sign = s_Signature;
-// HHTable1[HKey].Arg1 = bFuncR;
- HHTable1[HKey].Arg1 = bFunc;
-
- return Extra_CountMintermsSimple( bFunc, (1<<s_MultiStart) );
- }
- else
- {
- DdNode * bFunc0, * bFunc1;
- DdNode * bVarsCof0, * bVarsCof1;
- DdNode * bVarsCofR = Cudd_Regular(bVarsCof);
- unsigned Res;
-
- // get the levels
- int LevelF = dd->perm[bFuncR->index];
- int LevelC = cuddI(dd,bVarsCofR->index);
- int LevelA = dd->perm[bVarsAll->index];
-
- int LevelTop = LevelF;
-
- if ( LevelTop > LevelC )
- LevelTop = LevelC;
-
- if ( LevelTop > LevelA )
- LevelTop = LevelA;
-
- // the top var in the function or in cofactoring vars always belongs to the set of all vars
- assert( !( LevelTop == LevelF || LevelTop == LevelC ) || LevelTop == LevelA );
-
- // cofactor the function
- if ( LevelTop == LevelF )
- {
- if ( bFuncR != bFunc ) // bFunc is complemented
- {
- bFunc0 = Cudd_Not( cuddE(bFuncR) );
- bFunc1 = Cudd_Not( cuddT(bFuncR) );
- }
- else
- {
- bFunc0 = cuddE(bFuncR);
- bFunc1 = cuddT(bFuncR);
- }
- }
- else // bVars is higher in the variable order
- bFunc0 = bFunc1 = bFunc;
-
- // cofactor the cube
- if ( LevelTop == LevelC )
- {
- if ( bVarsCofR != bVarsCof ) // bFunc is complemented
- {
- bVarsCof0 = Cudd_Not( cuddE(bVarsCofR) );
- bVarsCof1 = Cudd_Not( cuddT(bVarsCofR) );
- }
- else
- {
- bVarsCof0 = cuddE(bVarsCofR);
- bVarsCof1 = cuddT(bVarsCofR);
- }
- }
- else // bVars is higher in the variable order
- bVarsCof0 = bVarsCof1 = bVarsCof;
-
- // there are two cases:
- // (1) the top variable belongs to the cofactoring variables
- // (2) the top variable does not belong to the cofactoring variables
-
- // (1) the top variable belongs to the cofactoring variables
- Res = 0;
- if ( LevelTop == LevelC )
- {
- if ( bVarsCof1 == b0 ) // this is a negative cofactor
- {
- if ( bFunc0 != b0 )
- Res = Extra_CountCofactorMinterms( dd, bFunc0, bVarsCof0, cuddT(bVarsAll) );
- }
- else // this is a positive cofactor
- {
- if ( bFunc1 != b0 )
- Res = Extra_CountCofactorMinterms( dd, bFunc1, bVarsCof1, cuddT(bVarsAll) );
- }
- }
- else
- {
- if ( bFunc0 != b0 )
- Res += Extra_CountCofactorMinterms( dd, bFunc0, bVarsCof0, cuddT(bVarsAll) );
-
- if ( bFunc1 != b0 )
- Res += Extra_CountCofactorMinterms( dd, bFunc1, bVarsCof1, cuddT(bVarsAll) );
- }
-
-// st__insert(Visited, (char*)bFunc, NULL);
-
-// HHTable1[HKey].Sign = s_Signature;
-// HHTable1[HKey].Arg1 = bFuncR;
-
- // skip through the entries with the same signatures
- // (these might have been created at the time of recursive calls)
- for ( ; HHTable1[HKey].Sign == s_Signature; HKey = (HKey+1) % _TABLESIZE_COF );
- assert( HHTable1[HKey].Sign != s_Signature );
- HHTable1[HKey].Sign = s_Signature;
-// HHTable1[HKey].Arg1 = bFuncR;
- HHTable1[HKey].Arg1 = bFunc;
-
- return Res;
- }
-}
-
-/**Function********************************************************************
-
- Synopsis [Counts the number of minterms.]
-
- Description [This function counts minterms for functions up to 32 variables
- using a local cache. The terminal value (s_Termina) should be adjusted for
- BDDs and ADDs.]
-
- SideEffects [None]
-
-******************************************************************************/
-unsigned Extra_CountMintermsSimple( DdNode * bFunc, unsigned max )
-{
- unsigned HKey;
-
- // normalize
- if ( Cudd_IsComplement(bFunc) )
- return max - Extra_CountMintermsSimple( Cudd_Not(bFunc), max );
-
- // now it is known that the function is not complemented
- if ( cuddIsConstant(bFunc) )
- return ((bFunc==s_Terminal)? 0: max);
-
- // check cache
- HKey = hashKey2( bFunc, max, _TABLESIZE_MINT );
- if ( HHTable2[HKey].Arg1 == bFunc && HHTable2[HKey].Arg2 == max )
- return HHTable2[HKey].Res;
- else
- {
- // min = min0/2 + min1/2;
- unsigned min = (Extra_CountMintermsSimple( cuddE(bFunc), max ) >> 1) +
- (Extra_CountMintermsSimple( cuddT(bFunc), max ) >> 1);
-
- HHTable2[HKey].Arg1 = bFunc;
- HHTable2[HKey].Arg2 = max;
- HHTable2[HKey].Res = min;
-
- return min;
- }
-} /* end of Extra_CountMintermsSimple */
-
-
-/**Function********************************************************************
-
- Synopsis [Visits the nodes.]
-
- Description [Visits the nodes above the cut and the nodes pointed to below the cut;
- collects the visited nodes, counts how many times each node is visited, and sets
- the path-sum to be the constant zero BDD.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void CountNodeVisits_rec( DdManager * dd, DdNode * aFunc, st__table * Visited )
-
-{
- traventry * p;
- char **slot;
- if ( st__find_or_add(Visited, (char*)aFunc, &slot) )
- { // the entry already exists
- p = (traventry*) *slot;
- // increment the counter of incoming edges
- p->nEdges++;
- return;
- }
- // this node has not been visited
- assert( !Cudd_IsComplement(aFunc) );
-
- // create the new traversal entry
- p = (traventry *) ABC_ALLOC( char, sizeof(traventry) );
- // set the initial sum of edges to zero BDD
- p->bSum = b0; Cudd_Ref( b0 );
- // set the starting number of incoming edges
- p->nEdges = 1;
- // set this entry into the slot
- *slot = (char*)p;
-
- // recur if the node is above the cut
- if ( cuddI(dd,aFunc->index) < s_CutLevel )
- {
- CountNodeVisits_rec( dd, cuddE(aFunc), Visited );
- CountNodeVisits_rec( dd, cuddT(aFunc), Visited );
- }
-} /* end of CountNodeVisits_rec */
-
-
-/**Function********************************************************************
-
- Synopsis [Revisits the nodes and computes the paths.]
-
- Description [This function visits the nodes above the cut having the goal of
- summing all the incomming BDD edges; when this function comes across the node
- below the cut, it saves this node in the CutNode table.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void CollectNodesAndComputePaths_rec( DdManager * dd, DdNode * aFunc, DdNode * bCube, st__table * Visited, st__table * CutNodes )
-{
- // find the node in the visited table
- DdNode * bTemp;
- traventry * p;
- char **slot;
- if ( st__find_or_add(Visited, (char*)aFunc, &slot) )
- { // the node is found
- // get the pointer to the traversal entry
- p = (traventry*) *slot;
-
- // make sure that the counter of incoming edges is positive
- assert( p->nEdges > 0 );
-
- // add the cube to the currently accumulated cubes
- p->bSum = Cudd_bddOr( dd, bTemp = p->bSum, bCube ); Cudd_Ref( p->bSum );
- Cudd_RecursiveDeref( dd, bTemp );
-
- // decrement the number of visits
- p->nEdges--;
-
- // if more visits to this node are expected, return
- if ( p->nEdges )
- return;
- else // if ( p->nEdges == 0 )
- { // this is the last visit - propagate the cube
-
- // check where this node is
- if ( cuddI(dd,aFunc->index) < s_CutLevel )
- { // the node is above the cut
- DdNode * bCube0, * bCube1;
-
- // get the top-most variable
- DdNode * bVarTop = dd->vars[aFunc->index];
-
- // compute the propagated cubes
- bCube0 = Cudd_bddAnd( dd, p->bSum, Cudd_Not( bVarTop ) ); Cudd_Ref( bCube0 );
- bCube1 = Cudd_bddAnd( dd, p->bSum, bVarTop ); Cudd_Ref( bCube1 );
-
- // call recursively
- CollectNodesAndComputePaths_rec( dd, cuddE(aFunc), bCube0, Visited, CutNodes );
- CollectNodesAndComputePaths_rec( dd, cuddT(aFunc), bCube1, Visited, CutNodes );
-
- // dereference the cubes
- Cudd_RecursiveDeref( dd, bCube0 );
- Cudd_RecursiveDeref( dd, bCube1 );
- return;
- }
- else
- { // the node is below the cut
- // add this node to the cut node table, if it is not yet there
-
-// DdNode * bNode;
-// bNode = Cudd_addBddPattern( dd, aFunc ); Cudd_Ref( bNode );
- if ( st__find_or_add(CutNodes, (char*)aFunc, &slot) )
- { // the node exists - should never happen
- assert( 0 );
- }
- *slot = (char*) p->bSum; Cudd_Ref( p->bSum );
- // the table takes the reference of bNode
- return;
- }
- }
- }
-
- // the node does not exist in the visited table - should never happen
- assert(0);
-
-} /* end of CollectNodesAndComputePaths_rec */
-
-
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddImage.c b/src/misc/extra/extraBddImage.c
deleted file mode 100644
index 46afb4f2..00000000
--- a/src/misc/extra/extraBddImage.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddImage.c]
-
- PackageName [extra]
-
- Synopsis [Various reusable software utilities.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddImage.c,v 1.0 2003/09/01 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*
- The ideas implemented in this file are inspired by the paper:
- Pankaj Chauhan, Edmund Clarke, Somesh Jha, Jim Kukula, Tom Shiple,
- Helmut Veith, Dong Wang. Non-linear Quantification Scheduling in
- Image Computation. ICCAD, 2001.
-*/
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-typedef struct Extra_ImageNode_t_ Extra_ImageNode_t;
-typedef struct Extra_ImagePart_t_ Extra_ImagePart_t;
-typedef struct Extra_ImageVar_t_ Extra_ImageVar_t;
-
-struct Extra_ImageTree_t_
-{
- Extra_ImageNode_t * pRoot; // the root of quantification tree
- Extra_ImageNode_t * pCare; // the leaf node with the care set
- DdNode * bCareSupp; // the cube to quantify from the care
- int fVerbose; // the verbosity flag
- int nNodesMax; // the max number of nodes in one iter
- int nNodesMaxT; // the overall max number of nodes
- int nIter; // the number of iterations with this tree
-};
-
-struct Extra_ImageNode_t_
-{
- DdManager * dd; // the manager
- DdNode * bCube; // the cube to quantify
- DdNode * bImage; // the partial image
- Extra_ImageNode_t * pNode1; // the first branch
- Extra_ImageNode_t * pNode2; // the second branch
- Extra_ImagePart_t * pPart; // the partition (temporary)
-};
-
-struct Extra_ImagePart_t_
-{
- DdNode * bFunc; // the partition
- DdNode * bSupp; // the support of this partition
- int nNodes; // the number of BDD nodes
- short nSupp; // the number of support variables
- short iPart; // the number of this partition
-};
-
-struct Extra_ImageVar_t_
-{
- int iNum; // the BDD index of this variable
- DdNode * bParts; // the partition numbers
- int nParts; // the number of partitions
-};
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static Extra_ImagePart_t ** Extra_CreateParts( DdManager * dd,
- int nParts, DdNode ** pbParts, DdNode * bCare );
-static Extra_ImageVar_t ** Extra_CreateVars( DdManager * dd,
- int nParts, Extra_ImagePart_t ** pParts,
- int nVars, DdNode ** pbVarsNs );
-static Extra_ImageNode_t ** Extra_CreateNodes( DdManager * dd,
- int nParts, Extra_ImagePart_t ** pParts,
- int nVars, Extra_ImageVar_t ** pVars );
-static void Extra_DeleteParts_rec( Extra_ImageNode_t * pNode );
-static int Extra_BuildTreeNode( DdManager * dd,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int nVars, Extra_ImageVar_t ** pVars );
-static Extra_ImageNode_t * Extra_MergeTopNodes( DdManager * dd,
- int nNodes, Extra_ImageNode_t ** pNodes );
-static void Extra_bddImageTreeDelete_rec( Extra_ImageNode_t * pNode );
-static void Extra_bddImageCompute_rec( Extra_ImageTree_t * pTree, Extra_ImageNode_t * pNode );
-static int Extra_FindBestVariable( DdManager * dd,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int nVars, Extra_ImageVar_t ** pVars );
-static void Extra_FindBestPartitions( DdManager * dd, DdNode * bParts,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int * piNode1, int * piNode2 );
-static Extra_ImageNode_t * Extra_CombineTwoNodes( DdManager * dd, DdNode * bCube,
- Extra_ImageNode_t * pNode1, Extra_ImageNode_t * pNode2 );
-
-static void Extra_bddImagePrintLatchDependency( DdManager * dd, DdNode * bCare,
- int nParts, DdNode ** pbParts,
- int nVars, DdNode ** pbVars );
-static void Extra_bddImagePrintLatchDependencyOne( DdManager * dd, DdNode * bFunc,
- DdNode * bVarsCs, DdNode * bVarsNs, int iPart );
-
-static void Extra_bddImagePrintTree( Extra_ImageTree_t * pTree );
-static void Extra_bddImagePrintTree_rec( Extra_ImageNode_t * pNode, int nOffset );
-
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function*************************************************************
-
- Synopsis [Starts the image computation using tree-based scheduling.]
-
- Description [This procedure starts the image computation. It uses
- the given care set to test-run the image computation and creates the
- quantification tree by scheduling variable quantifications. The tree can
- be used to compute images for other care sets without rescheduling.
- In this case, Extra_bddImageCompute() should be called.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageTree_t * Extra_bddImageStart(
- DdManager * dd, DdNode * bCare, // the care set
- int nParts, DdNode ** pbParts, // the partitions for image computation
- int nVars, DdNode ** pbVars, int fVerbose ) // the NS and parameter variables (not quantified!)
-{
- Extra_ImageTree_t * pTree;
- Extra_ImagePart_t ** pParts;
- Extra_ImageVar_t ** pVars;
- Extra_ImageNode_t ** pNodes;
- int v;
-
- if ( fVerbose && dd->size <= 80 )
- Extra_bddImagePrintLatchDependency( dd, bCare, nParts, pbParts, nVars, pbVars );
-
- // create variables, partitions and leaf nodes
- pParts = Extra_CreateParts( dd, nParts, pbParts, bCare );
- pVars = Extra_CreateVars( dd, nParts + 1, pParts, nVars, pbVars );
- pNodes = Extra_CreateNodes( dd, nParts + 1, pParts, dd->size, pVars );
-
- // create the tree
- pTree = ABC_ALLOC( Extra_ImageTree_t, 1 );
- memset( pTree, 0, sizeof(Extra_ImageTree_t) );
- pTree->pCare = pNodes[nParts];
- pTree->fVerbose = fVerbose;
-
- // process the nodes
- while ( Extra_BuildTreeNode( dd, nParts + 1, pNodes, dd->size, pVars ) );
-
- // make sure the variables are gone
- for ( v = 0; v < dd->size; v++ )
- assert( pVars[v] == NULL );
- ABC_FREE( pVars );
-
- // merge the topmost nodes
- while ( (pTree->pRoot = Extra_MergeTopNodes( dd, nParts + 1, pNodes )) == NULL );
-
- // make sure the nodes are gone
- for ( v = 0; v < nParts + 1; v++ )
- assert( pNodes[v] == NULL );
- ABC_FREE( pNodes );
-
-// if ( fVerbose )
-// Extra_bddImagePrintTree( pTree );
-
- // set the support of the care set
- pTree->bCareSupp = Cudd_Support( dd, bCare ); Cudd_Ref( pTree->bCareSupp );
-
- // clean the partitions
- Extra_DeleteParts_rec( pTree->pRoot );
- ABC_FREE( pParts );
- return pTree;
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute the image.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddImageCompute( Extra_ImageTree_t * pTree, DdNode * bCare )
-{
- DdManager * dd = pTree->pCare->dd;
- DdNode * bSupp, * bRem;
-
- pTree->nIter++;
-
- // make sure the supports are okay
- bSupp = Cudd_Support( dd, bCare ); Cudd_Ref( bSupp );
- if ( bSupp != pTree->bCareSupp )
- {
- bRem = Cudd_bddExistAbstract( dd, bSupp, pTree->bCareSupp ); Cudd_Ref( bRem );
- if ( bRem != b1 )
- {
-printf( "Original care set support: " );
-ABC_PRB( dd, pTree->bCareSupp );
-printf( "Current care set support: " );
-ABC_PRB( dd, bSupp );
- Cudd_RecursiveDeref( dd, bSupp );
- Cudd_RecursiveDeref( dd, bRem );
- printf( "The care set depends on some vars that were not in the care set during scheduling.\n" );
- return NULL;
- }
- Cudd_RecursiveDeref( dd, bRem );
- }
- Cudd_RecursiveDeref( dd, bSupp );
-
- // remove the previous image
- Cudd_RecursiveDeref( dd, pTree->pCare->bImage );
- pTree->pCare->bImage = bCare; Cudd_Ref( bCare );
-
- // compute the image
- pTree->nNodesMax = 0;
- Extra_bddImageCompute_rec( pTree, pTree->pRoot );
- if ( pTree->nNodesMaxT < pTree->nNodesMax )
- pTree->nNodesMaxT = pTree->nNodesMax;
-
-// if ( pTree->fVerbose )
-// printf( "Iter %2d : Max nodes = %5d.\n", pTree->nIter, pTree->nNodesMax );
- return pTree->pRoot->bImage;
-}
-
-/**Function*************************************************************
-
- Synopsis [Delete the tree.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImageTreeDelete( Extra_ImageTree_t * pTree )
-{
- if ( pTree->bCareSupp )
- Cudd_RecursiveDeref( pTree->pRoot->dd, pTree->bCareSupp );
- Extra_bddImageTreeDelete_rec( pTree->pRoot );
- ABC_FREE( pTree );
-}
-
-/**Function*************************************************************
-
- Synopsis [Reads the image from the tree.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddImageRead( Extra_ImageTree_t * pTree )
-{
- return pTree->pRoot->bImage;
-}
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static Functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function*************************************************************
-
- Synopsis [Creates partitions.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImagePart_t ** Extra_CreateParts( DdManager * dd,
- int nParts, DdNode ** pbParts, DdNode * bCare )
-{
- Extra_ImagePart_t ** pParts;
- int i;
-
- // start the partitions
- pParts = ABC_ALLOC( Extra_ImagePart_t *, nParts + 1 );
- // create structures for each variable
- for ( i = 0; i < nParts; i++ )
- {
- pParts[i] = ABC_ALLOC( Extra_ImagePart_t, 1 );
- pParts[i]->bFunc = pbParts[i]; Cudd_Ref( pParts[i]->bFunc );
- pParts[i]->bSupp = Cudd_Support( dd, pParts[i]->bFunc ); Cudd_Ref( pParts[i]->bSupp );
- pParts[i]->nSupp = Extra_bddSuppSize( dd, pParts[i]->bSupp );
- pParts[i]->nNodes = Cudd_DagSize( pParts[i]->bFunc );
- pParts[i]->iPart = i;
- }
- // add the care set as the last partition
- pParts[nParts] = ABC_ALLOC( Extra_ImagePart_t, 1 );
- pParts[nParts]->bFunc = bCare; Cudd_Ref( pParts[nParts]->bFunc );
- pParts[nParts]->bSupp = Cudd_Support( dd, pParts[nParts]->bFunc ); Cudd_Ref( pParts[nParts]->bSupp );
- pParts[nParts]->nSupp = Extra_bddSuppSize( dd, pParts[nParts]->bSupp );
- pParts[nParts]->nNodes = Cudd_DagSize( pParts[nParts]->bFunc );
- pParts[nParts]->iPart = nParts;
- return pParts;
-}
-
-/**Function*************************************************************
-
- Synopsis [Creates variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageVar_t ** Extra_CreateVars( DdManager * dd,
- int nParts, Extra_ImagePart_t ** pParts,
- int nVars, DdNode ** pbVars )
-{
- Extra_ImageVar_t ** pVars;
- DdNode ** pbFuncs;
- DdNode * bCubeNs, * bSupp, * bParts, * bTemp, * bSuppTemp;
- int nVarsTotal, iVar, p, Counter;
-
- // put all the functions into one array
- pbFuncs = ABC_ALLOC( DdNode *, nParts );
- for ( p = 0; p < nParts; p++ )
- pbFuncs[p] = pParts[p]->bSupp;
- bSupp = Cudd_VectorSupport( dd, pbFuncs, nParts ); Cudd_Ref( bSupp );
- ABC_FREE( pbFuncs );
-
- // remove the NS vars
- bCubeNs = Cudd_bddComputeCube( dd, pbVars, NULL, nVars ); Cudd_Ref( bCubeNs );
- bSupp = Cudd_bddExistAbstract( dd, bTemp = bSupp, bCubeNs ); Cudd_Ref( bSupp );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bCubeNs );
-
- // get the number of I and CS variables to be quantified
- nVarsTotal = Extra_bddSuppSize( dd, bSupp );
-
- // start the variables
- pVars = ABC_ALLOC( Extra_ImageVar_t *, dd->size );
- memset( pVars, 0, sizeof(Extra_ImageVar_t *) * dd->size );
- // create structures for each variable
- for ( bSuppTemp = bSupp; bSuppTemp != b1; bSuppTemp = cuddT(bSuppTemp) )
- {
- iVar = bSuppTemp->index;
- pVars[iVar] = ABC_ALLOC( Extra_ImageVar_t, 1 );
- pVars[iVar]->iNum = iVar;
- // collect all the parts this var belongs to
- Counter = 0;
- bParts = b1; Cudd_Ref( bParts );
- for ( p = 0; p < nParts; p++ )
- if ( Cudd_bddLeq( dd, pParts[p]->bSupp, dd->vars[bSuppTemp->index] ) )
- {
- bParts = Cudd_bddAnd( dd, bTemp = bParts, dd->vars[p] ); Cudd_Ref( bParts );
- Cudd_RecursiveDeref( dd, bTemp );
- Counter++;
- }
- pVars[iVar]->bParts = bParts; // takes ref
- pVars[iVar]->nParts = Counter;
- }
- Cudd_RecursiveDeref( dd, bSupp );
- return pVars;
-}
-
-/**Function*************************************************************
-
- Synopsis [Creates variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageNode_t ** Extra_CreateNodes( DdManager * dd,
- int nParts, Extra_ImagePart_t ** pParts,
- int nVars, Extra_ImageVar_t ** pVars )
-{
- Extra_ImageNode_t ** pNodes;
- Extra_ImageNode_t * pNode;
- DdNode * bTemp;
- int i, v, iPart;
-/*
- DdManager * dd; // the manager
- DdNode * bCube; // the cube to quantify
- DdNode * bImage; // the partial image
- Extra_ImageNode_t * pNode1; // the first branch
- Extra_ImageNode_t * pNode2; // the second branch
- Extra_ImagePart_t * pPart; // the partition (temporary)
-*/
- // start the partitions
- pNodes = ABC_ALLOC( Extra_ImageNode_t *, nParts );
- // create structures for each leaf nodes
- for ( i = 0; i < nParts; i++ )
- {
- pNodes[i] = ABC_ALLOC( Extra_ImageNode_t, 1 );
- memset( pNodes[i], 0, sizeof(Extra_ImageNode_t) );
- pNodes[i]->dd = dd;
- pNodes[i]->pPart = pParts[i];
- }
- // find the quantification cubes for each leaf node
- for ( v = 0; v < nVars; v++ )
- {
- if ( pVars[v] == NULL )
- continue;
- assert( pVars[v]->nParts > 0 );
- if ( pVars[v]->nParts > 1 )
- continue;
- iPart = pVars[v]->bParts->index;
- if ( pNodes[iPart]->bCube == NULL )
- {
- pNodes[iPart]->bCube = dd->vars[v];
- Cudd_Ref( dd->vars[v] );
- }
- else
- {
- pNodes[iPart]->bCube = Cudd_bddAnd( dd, bTemp = pNodes[iPart]->bCube, dd->vars[v] );
- Cudd_Ref( pNodes[iPart]->bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- // remove these variables
- Cudd_RecursiveDeref( dd, pVars[v]->bParts );
- ABC_FREE( pVars[v] );
- }
-
- // assign the leaf node images
- for ( i = 0; i < nParts; i++ )
- {
- pNode = pNodes[i];
- if ( pNode->bCube )
- {
- // update the partition
- pParts[i]->bFunc = Cudd_bddExistAbstract( dd, bTemp = pParts[i]->bFunc, pNode->bCube );
- Cudd_Ref( pParts[i]->bFunc );
- Cudd_RecursiveDeref( dd, bTemp );
- // update the support the partition
- pParts[i]->bSupp = Cudd_bddExistAbstract( dd, bTemp = pParts[i]->bSupp, pNode->bCube );
- Cudd_Ref( pParts[i]->bSupp );
- Cudd_RecursiveDeref( dd, bTemp );
- // update the numbers
- pParts[i]->nSupp = Extra_bddSuppSize( dd, pParts[i]->bSupp );
- pParts[i]->nNodes = Cudd_DagSize( pParts[i]->bFunc );
- // get rid of the cube
- // save the last (care set) quantification cube
- if ( i < nParts - 1 )
- {
- Cudd_RecursiveDeref( dd, pNode->bCube );
- pNode->bCube = NULL;
- }
- }
- // copy the function
- pNode->bImage = pParts[i]->bFunc; Cudd_Ref( pNode->bImage );
- }
-/*
- for ( i = 0; i < nParts; i++ )
- {
- pNode = pNodes[i];
-ABC_PRB( dd, pNode->bCube );
-ABC_PRB( dd, pNode->pPart->bFunc );
-ABC_PRB( dd, pNode->pPart->bSupp );
-printf( "\n" );
- }
-*/
- return pNodes;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Delete the partitions from the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_DeleteParts_rec( Extra_ImageNode_t * pNode )
-{
- Extra_ImagePart_t * pPart;
- if ( pNode->pNode1 )
- Extra_DeleteParts_rec( pNode->pNode1 );
- if ( pNode->pNode2 )
- Extra_DeleteParts_rec( pNode->pNode2 );
- pPart = pNode->pPart;
- Cudd_RecursiveDeref( pNode->dd, pPart->bFunc );
- Cudd_RecursiveDeref( pNode->dd, pPart->bSupp );
- ABC_FREE( pNode->pPart );
-}
-
-/**Function*************************************************************
-
- Synopsis [Delete the partitions from the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImageTreeDelete_rec( Extra_ImageNode_t * pNode )
-{
- if ( pNode->pNode1 )
- Extra_bddImageTreeDelete_rec( pNode->pNode1 );
- if ( pNode->pNode2 )
- Extra_bddImageTreeDelete_rec( pNode->pNode2 );
- if ( pNode->bCube )
- Cudd_RecursiveDeref( pNode->dd, pNode->bCube );
- if ( pNode->bImage )
- Cudd_RecursiveDeref( pNode->dd, pNode->bImage );
- assert( pNode->pPart == NULL );
- ABC_FREE( pNode );
-}
-
-/**Function*************************************************************
-
- Synopsis [Recompute the image.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImageCompute_rec( Extra_ImageTree_t * pTree, Extra_ImageNode_t * pNode )
-{
- DdManager * dd = pNode->dd;
- DdNode * bTemp;
- int nNodes;
-
- // trivial case
- if ( pNode->pNode1 == NULL )
- {
- if ( pNode->bCube )
- {
- pNode->bImage = Cudd_bddExistAbstract( dd, bTemp = pNode->bImage, pNode->bCube );
- Cudd_Ref( pNode->bImage );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- return;
- }
-
- // compute the children
- if ( pNode->pNode1 )
- Extra_bddImageCompute_rec( pTree, pNode->pNode1 );
- if ( pNode->pNode2 )
- Extra_bddImageCompute_rec( pTree, pNode->pNode2 );
-
- // clean the old image
- if ( pNode->bImage )
- Cudd_RecursiveDeref( dd, pNode->bImage );
- pNode->bImage = NULL;
-
- // compute the new image
- if ( pNode->bCube )
- pNode->bImage = Cudd_bddAndAbstract( dd,
- pNode->pNode1->bImage, pNode->pNode2->bImage, pNode->bCube );
- else
- pNode->bImage = Cudd_bddAnd( dd, pNode->pNode1->bImage, pNode->pNode2->bImage );
- Cudd_Ref( pNode->bImage );
-
- if ( pTree->fVerbose )
- {
- nNodes = Cudd_DagSize( pNode->bImage );
- if ( pTree->nNodesMax < nNodes )
- pTree->nNodesMax = nNodes;
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Builds the tree.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Extra_BuildTreeNode( DdManager * dd,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int nVars, Extra_ImageVar_t ** pVars )
-{
- Extra_ImageNode_t * pNode1, * pNode2;
- Extra_ImageVar_t * pVar;
- Extra_ImageNode_t * pNode;
- DdNode * bCube, * bTemp, * bSuppTemp, * bParts;
- int iNode1, iNode2;
- int iVarBest, nSupp, v;
-
- // find the best variable
- iVarBest = Extra_FindBestVariable( dd, nNodes, pNodes, nVars, pVars );
- if ( iVarBest == -1 )
- return 0;
-
- pVar = pVars[iVarBest];
-
- // this var cannot appear in one partition only
- nSupp = Extra_bddSuppSize( dd, pVar->bParts );
- assert( nSupp == pVar->nParts );
- assert( nSupp != 1 );
-
- // if it appears in only two partitions, quantify it
- if ( pVar->nParts == 2 )
- {
- // get the nodes
- iNode1 = pVar->bParts->index;
- iNode2 = cuddT(pVar->bParts)->index;
- pNode1 = pNodes[iNode1];
- pNode2 = pNodes[iNode2];
-
- // get the quantification cube
- bCube = dd->vars[pVar->iNum]; Cudd_Ref( bCube );
- // add the variables that appear only in these partitions
- for ( v = 0; v < nVars; v++ )
- if ( pVars[v] && v != iVarBest && pVars[v]->bParts == pVars[iVarBest]->bParts )
- {
- // add this var
- bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[pVars[v]->iNum] ); Cudd_Ref( bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- // clean this var
- Cudd_RecursiveDeref( dd, pVars[v]->bParts );
- ABC_FREE( pVars[v] );
- }
- // clean the best var
- Cudd_RecursiveDeref( dd, pVars[iVarBest]->bParts );
- ABC_FREE( pVars[iVarBest] );
-
- // combines two nodes
- pNode = Extra_CombineTwoNodes( dd, bCube, pNode1, pNode2 );
- Cudd_RecursiveDeref( dd, bCube );
- }
- else // if ( pVar->nParts > 2 )
- {
- // find two smallest BDDs that have this var
- Extra_FindBestPartitions( dd, pVar->bParts, nNodes, pNodes, &iNode1, &iNode2 );
- pNode1 = pNodes[iNode1];
- pNode2 = pNodes[iNode2];
-
- // it is not possible that a var appears only in these two
- // otherwise, it would have a different cost
- bParts = Cudd_bddAnd( dd, dd->vars[iNode1], dd->vars[iNode2] ); Cudd_Ref( bParts );
- for ( v = 0; v < nVars; v++ )
- if ( pVars[v] && pVars[v]->bParts == bParts )
- assert( 0 );
- Cudd_RecursiveDeref( dd, bParts );
-
- // combines two nodes
- pNode = Extra_CombineTwoNodes( dd, b1, pNode1, pNode2 );
- }
-
- // clean the old nodes
- pNodes[iNode1] = pNode;
- pNodes[iNode2] = NULL;
-
- // update the variables that appear in pNode[iNode2]
- for ( bSuppTemp = pNode2->pPart->bSupp; bSuppTemp != b1; bSuppTemp = cuddT(bSuppTemp) )
- {
- pVar = pVars[bSuppTemp->index];
- if ( pVar == NULL ) // this variable is not be quantified
- continue;
- // quantify this var
- assert( Cudd_bddLeq( dd, pVar->bParts, dd->vars[iNode2] ) );
- pVar->bParts = Cudd_bddExistAbstract( dd, bTemp = pVar->bParts, dd->vars[iNode2] ); Cudd_Ref( pVar->bParts );
- Cudd_RecursiveDeref( dd, bTemp );
- // add the new var
- pVar->bParts = Cudd_bddAnd( dd, bTemp = pVar->bParts, dd->vars[iNode1] ); Cudd_Ref( pVar->bParts );
- Cudd_RecursiveDeref( dd, bTemp );
- // update the score
- pVar->nParts = Extra_bddSuppSize( dd, pVar->bParts );
- }
- return 1;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Merges the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageNode_t * Extra_MergeTopNodes(
- DdManager * dd, int nNodes, Extra_ImageNode_t ** pNodes )
-{
- Extra_ImageNode_t * pNode;
- int n1 = -1, n2 = -1, n;
-
- // find the first and the second non-empty spots
- for ( n = 0; n < nNodes; n++ )
- if ( pNodes[n] )
- {
- if ( n1 == -1 )
- n1 = n;
- else if ( n2 == -1 )
- {
- n2 = n;
- break;
- }
- }
- assert( n1 != -1 );
- // check the situation when only one such node is detected
- if ( n2 == -1 )
- {
- // save the node
- pNode = pNodes[n1];
- // clean the node
- pNodes[n1] = NULL;
- return pNode;
- }
-
- // combines two nodes
- pNode = Extra_CombineTwoNodes( dd, b1, pNodes[n1], pNodes[n2] );
-
- // clean the old nodes
- pNodes[n1] = pNode;
- pNodes[n2] = NULL;
- return NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis [Merges two nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageNode_t * Extra_CombineTwoNodes( DdManager * dd, DdNode * bCube,
- Extra_ImageNode_t * pNode1, Extra_ImageNode_t * pNode2 )
-{
- Extra_ImageNode_t * pNode;
- Extra_ImagePart_t * pPart;
-
- // create a new partition
- pPart = ABC_ALLOC( Extra_ImagePart_t, 1 );
- memset( pPart, 0, sizeof(Extra_ImagePart_t) );
- // create the function
- pPart->bFunc = Cudd_bddAndAbstract( dd, pNode1->pPart->bFunc, pNode2->pPart->bFunc, bCube );
- Cudd_Ref( pPart->bFunc );
- // update the support the partition
- pPart->bSupp = Cudd_bddAndAbstract( dd, pNode1->pPart->bSupp, pNode2->pPart->bSupp, bCube );
- Cudd_Ref( pPart->bSupp );
- // update the numbers
- pPart->nSupp = Extra_bddSuppSize( dd, pPart->bSupp );
- pPart->nNodes = Cudd_DagSize( pPart->bFunc );
- pPart->iPart = -1;
-/*
-ABC_PRB( dd, pNode1->pPart->bSupp );
-ABC_PRB( dd, pNode2->pPart->bSupp );
-ABC_PRB( dd, pPart->bSupp );
-*/
- // create a new node
- pNode = ABC_ALLOC( Extra_ImageNode_t, 1 );
- memset( pNode, 0, sizeof(Extra_ImageNode_t) );
- pNode->dd = dd;
- pNode->pPart = pPart;
- pNode->pNode1 = pNode1;
- pNode->pNode2 = pNode2;
- // compute the image
- pNode->bImage = Cudd_bddAndAbstract( dd, pNode1->bImage, pNode2->bImage, bCube );
- Cudd_Ref( pNode->bImage );
- // save the cube
- if ( bCube != b1 )
- {
- pNode->bCube = bCube; Cudd_Ref( bCube );
- }
- return pNode;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the best variable.]
-
- Description [The variables is the best if the sum of squares of the
- BDD sizes of the partitions, in which it participates, is the minimum.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Extra_FindBestVariable( DdManager * dd,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int nVars, Extra_ImageVar_t ** pVars )
-{
- DdNode * bTemp;
- int iVarBest, v;
- double CostBest, CostCur;
-
- CostBest = 100000000000000.0;
- iVarBest = -1;
- for ( v = 0; v < nVars; v++ )
- if ( pVars[v] )
- {
- CostCur = 0;
- for ( bTemp = pVars[v]->bParts; bTemp != b1; bTemp = cuddT(bTemp) )
- CostCur += pNodes[bTemp->index]->pPart->nNodes *
- pNodes[bTemp->index]->pPart->nNodes;
- if ( CostBest > CostCur )
- {
- CostBest = CostCur;
- iVarBest = v;
- }
- }
- return iVarBest;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes two smallest partions that have this var.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_FindBestPartitions( DdManager * dd, DdNode * bParts,
- int nNodes, Extra_ImageNode_t ** pNodes,
- int * piNode1, int * piNode2 )
-{
- DdNode * bTemp;
- int iPart1, iPart2;
- int CostMin1, CostMin2, Cost;
-
- // go through the partitions
- iPart1 = iPart2 = -1;
- CostMin1 = CostMin2 = 1000000;
- for ( bTemp = bParts; bTemp != b1; bTemp = cuddT(bTemp) )
- {
- Cost = pNodes[bTemp->index]->pPart->nNodes;
- if ( CostMin1 > Cost )
- {
- CostMin2 = CostMin1; iPart2 = iPart1;
- CostMin1 = Cost; iPart1 = bTemp->index;
- }
- else if ( CostMin2 > Cost )
- {
- CostMin2 = Cost; iPart2 = bTemp->index;
- }
- }
-
- *piNode1 = iPart1;
- *piNode2 = iPart2;
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints the latch dependency matrix.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImagePrintLatchDependency(
- DdManager * dd, DdNode * bCare, // the care set
- int nParts, DdNode ** pbParts, // the partitions for image computation
- int nVars, DdNode ** pbVars ) // the NS and parameter variables (not quantified!)
-{
- int i;
- DdNode * bVarsCs, * bVarsNs;
-
- bVarsCs = Cudd_Support( dd, bCare ); Cudd_Ref( bVarsCs );
- bVarsNs = Cudd_bddComputeCube( dd, pbVars, NULL, nVars ); Cudd_Ref( bVarsNs );
-
- printf( "The latch dependency matrix:\n" );
- printf( "Partitions = %d Variables: total = %d non-quantifiable = %d\n",
- nParts, dd->size, nVars );
- printf( " : " );
- for ( i = 0; i < dd->size; i++ )
- printf( "%d", i % 10 );
- printf( "\n" );
-
- for ( i = 0; i < nParts; i++ )
- Extra_bddImagePrintLatchDependencyOne( dd, pbParts[i], bVarsCs, bVarsNs, i );
- Extra_bddImagePrintLatchDependencyOne( dd, bCare, bVarsCs, bVarsNs, nParts );
-
- Cudd_RecursiveDeref( dd, bVarsCs );
- Cudd_RecursiveDeref( dd, bVarsNs );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints one row of the latch dependency matrix.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImagePrintLatchDependencyOne(
- DdManager * dd, DdNode * bFunc, // the function
- DdNode * bVarsCs, DdNode * bVarsNs, // the current/next state vars
- int iPart )
-{
- DdNode * bSupport;
- int v;
- bSupport = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupport );
- printf( " %3d : ", iPart );
- for ( v = 0; v < dd->size; v++ )
- {
- if ( Cudd_bddLeq( dd, bSupport, dd->vars[v] ) )
- {
- if ( Cudd_bddLeq( dd, bVarsCs, dd->vars[v] ) )
- printf( "c" );
- else if ( Cudd_bddLeq( dd, bVarsNs, dd->vars[v] ) )
- printf( "n" );
- else
- printf( "i" );
- }
- else
- printf( "." );
- }
- printf( "\n" );
- Cudd_RecursiveDeref( dd, bSupport );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Prints the tree for quenstification scheduling.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImagePrintTree( Extra_ImageTree_t * pTree )
-{
- printf( "The quantification scheduling tree:\n" );
- Extra_bddImagePrintTree_rec( pTree->pRoot, 1 );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints the tree for quenstification scheduling.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImagePrintTree_rec( Extra_ImageNode_t * pNode, int Offset )
-{
- DdNode * Cube;
- int i;
-
- Cube = pNode->bCube;
-
- if ( pNode->pNode1 == NULL )
- {
- printf( "<%d> ", pNode->pPart->iPart );
- if ( Cube != NULL )
- {
- ABC_PRB( pNode->dd, Cube );
- }
- else
- printf( "\n" );
- return;
- }
-
- printf( "<*> " );
- if ( Cube != NULL )
- {
- ABC_PRB( pNode->dd, Cube );
- }
- else
- printf( "\n" );
-
- for ( i = 0; i < Offset; i++ )
- printf( " " );
- Extra_bddImagePrintTree_rec( pNode->pNode1, Offset + 1 );
-
- for ( i = 0; i < Offset; i++ )
- printf( " " );
- Extra_bddImagePrintTree_rec( pNode->pNode2, Offset + 1 );
-}
-
-
-
-
-
-struct Extra_ImageTree2_t_
-{
- DdManager * dd;
- DdNode * bRel;
- DdNode * bCube;
- DdNode * bImage;
-};
-
-/**Function*************************************************************
-
- Synopsis [Starts the monolithic image computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Extra_ImageTree2_t * Extra_bddImageStart2(
- DdManager * dd, DdNode * bCare,
- int nParts, DdNode ** pbParts,
- int nVars, DdNode ** pbVars, int fVerbose )
-{
- Extra_ImageTree2_t * pTree;
- DdNode * bCubeAll, * bCubeNot, * bTemp;
- int i;
-
- pTree = ABC_ALLOC( Extra_ImageTree2_t, 1 );
- pTree->dd = dd;
- pTree->bImage = NULL;
-
- bCubeAll = Extra_bddComputeCube( dd, dd->vars, dd->size ); Cudd_Ref( bCubeAll );
- bCubeNot = Extra_bddComputeCube( dd, pbVars, nVars ); Cudd_Ref( bCubeNot );
- pTree->bCube = Cudd_bddExistAbstract( dd, bCubeAll, bCubeNot ); Cudd_Ref( pTree->bCube );
- Cudd_RecursiveDeref( dd, bCubeAll );
- Cudd_RecursiveDeref( dd, bCubeNot );
-
- // derive the monolithic relation
- pTree->bRel = b1; Cudd_Ref( pTree->bRel );
- for ( i = 0; i < nParts; i++ )
- {
- pTree->bRel = Cudd_bddAnd( dd, bTemp = pTree->bRel, pbParts[i] ); Cudd_Ref( pTree->bRel );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Extra_bddImageCompute2( pTree, bCare );
- return pTree;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddImageCompute2( Extra_ImageTree2_t * pTree, DdNode * bCare )
-{
- if ( pTree->bImage )
- Cudd_RecursiveDeref( pTree->dd, pTree->bImage );
- pTree->bImage = Cudd_bddAndAbstract( pTree->dd, pTree->bRel, bCare, pTree->bCube );
- Cudd_Ref( pTree->bImage );
- return pTree->bImage;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_bddImageTreeDelete2( Extra_ImageTree2_t * pTree )
-{
- if ( pTree->bRel )
- Cudd_RecursiveDeref( pTree->dd, pTree->bRel );
- if ( pTree->bCube )
- Cudd_RecursiveDeref( pTree->dd, pTree->bCube );
- if ( pTree->bImage )
- Cudd_RecursiveDeref( pTree->dd, pTree->bImage );
- ABC_FREE( pTree );
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns the previously computed image.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddImageRead2( Extra_ImageTree2_t * pTree )
-{
- return pTree->bImage;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddKmap.c b/src/misc/extra/extraBddKmap.c
deleted file mode 100644
index aa5efe75..00000000
--- a/src/misc/extra/extraBddKmap.c
+++ /dev/null
@@ -1,876 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddKmap.c]
-
- PackageName [extra]
-
- Synopsis [Visualizing the K-map.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddKmap.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
-
-***********************************************************************/
-
-/// K-map visualization using pseudo graphics ///
-/// Version 1.0. Started - August 20, 2000 ///
-/// Version 2.0. Added to EXTRA - July 17, 2001 ///
-
-#include "extraBdd.h"
-
-#ifdef WIN32
-#include <windows.h>
-#endif
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-// the maximum number of variables in the Karnaugh Map
-#define MAXVARS 20
-
-/*
-// single line
-#define SINGLE_VERTICAL (char)179
-#define SINGLE_HORIZONTAL (char)196
-#define SINGLE_TOP_LEFT (char)218
-#define SINGLE_TOP_RIGHT (char)191
-#define SINGLE_BOT_LEFT (char)192
-#define SINGLE_BOT_RIGHT (char)217
-
-// double line
-#define DOUBLE_VERTICAL (char)186
-#define DOUBLE_HORIZONTAL (char)205
-#define DOUBLE_TOP_LEFT (char)201
-#define DOUBLE_TOP_RIGHT (char)187
-#define DOUBLE_BOT_LEFT (char)200
-#define DOUBLE_BOT_RIGHT (char)188
-
-// line intersections
-#define SINGLES_CROSS (char)197
-#define DOUBLES_CROSS (char)206
-#define S_HOR_CROSS_D_VER (char)215
-#define S_VER_CROSS_D_HOR (char)216
-
-// single line joining
-#define S_JOINS_S_VER_LEFT (char)180
-#define S_JOINS_S_VER_RIGHT (char)195
-#define S_JOINS_S_HOR_TOP (char)193
-#define S_JOINS_S_HOR_BOT (char)194
-
-// double line joining
-#define D_JOINS_D_VER_LEFT (char)185
-#define D_JOINS_D_VER_RIGHT (char)204
-#define D_JOINS_D_HOR_TOP (char)202
-#define D_JOINS_D_HOR_BOT (char)203
-
-// single line joining double line
-#define S_JOINS_D_VER_LEFT (char)182
-#define S_JOINS_D_VER_RIGHT (char)199
-#define S_JOINS_D_HOR_TOP (char)207
-#define S_JOINS_D_HOR_BOT (char)209
-*/
-
-// single line
-#define SINGLE_VERTICAL (char)'|'
-#define SINGLE_HORIZONTAL (char)'-'
-#define SINGLE_TOP_LEFT (char)'+'
-#define SINGLE_TOP_RIGHT (char)'+'
-#define SINGLE_BOT_LEFT (char)'+'
-#define SINGLE_BOT_RIGHT (char)'+'
-
-// double line
-#define DOUBLE_VERTICAL (char)'|'
-#define DOUBLE_HORIZONTAL (char)'-'
-#define DOUBLE_TOP_LEFT (char)'+'
-#define DOUBLE_TOP_RIGHT (char)'+'
-#define DOUBLE_BOT_LEFT (char)'+'
-#define DOUBLE_BOT_RIGHT (char)'+'
-
-// line intersections
-#define SINGLES_CROSS (char)'+'
-#define DOUBLES_CROSS (char)'+'
-#define S_HOR_CROSS_D_VER (char)'+'
-#define S_VER_CROSS_D_HOR (char)'+'
-
-// single line joining
-#define S_JOINS_S_VER_LEFT (char)'+'
-#define S_JOINS_S_VER_RIGHT (char)'+'
-#define S_JOINS_S_HOR_TOP (char)'+'
-#define S_JOINS_S_HOR_BOT (char)'+'
-
-// double line joining
-#define D_JOINS_D_VER_LEFT (char)'+'
-#define D_JOINS_D_VER_RIGHT (char)'+'
-#define D_JOINS_D_HOR_TOP (char)'+'
-#define D_JOINS_D_HOR_BOT (char)'+'
-
-// single line joining double line
-#define S_JOINS_D_VER_LEFT (char)'+'
-#define S_JOINS_D_VER_RIGHT (char)'+'
-#define S_JOINS_D_HOR_TOP (char)'+'
-#define S_JOINS_D_HOR_BOT (char)'+'
-
-
-// other symbols
-#define UNDERSCORE (char)95
-//#define SYMBOL_ZERO (char)248 // degree sign
-//#define SYMBOL_ZERO (char)'o'
-#ifdef WIN32
-#define SYMBOL_ZERO (char)'0'
-#else
-#define SYMBOL_ZERO (char)' '
-#endif
-#define SYMBOL_ONE (char)'1'
-#define SYMBOL_DC (char)'-'
-#define SYMBOL_OVERLAP (char)'?'
-
-// full cells and half cells
-#define CELL_FREE (char)32
-#define CELL_FULL (char)219
-#define HALF_UPPER (char)223
-#define HALF_LOWER (char)220
-#define HALF_LEFT (char)221
-#define HALF_RIGHT (char)222
-
-
-/*---------------------------------------------------------------------------*/
-/* Structure declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-// the array of BDD variables used internally
-static DdNode * s_XVars[MAXVARS];
-
-// flag which determines where the horizontal variable names are printed
-static int fHorizontalVarNamesPrintedAbove = 1;
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-// Oleg's way of generating the gray code
-static int GrayCode( int BinCode );
-static int BinCode ( int GrayCode );
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the K-map of the function.]
-
- Description [If the pointer to the array of variables XVars is NULL,
- fSuppType determines how the support will be determined.
- fSuppType == 0 -- takes the first nVars of the manager
- fSuppType == 1 -- takes the topmost nVars of the manager
- fSuppType == 2 -- determines support from the on-set and the offset
- ]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_PrintKMap(
- FILE * Output, /* the output stream */
- DdManager * dd,
- DdNode * OnSet,
- DdNode * OffSet,
- int nVars,
- DdNode ** XVars,
- int fSuppType, /* the flag which determines how support is computed */
- char ** pVarNames )
-{
- int fPrintTruth = 1;
- int d, p, n, s, v, h, w;
- int nVarsVer;
- int nVarsHor;
- int nCellsVer;
- int nCellsHor;
- int nSkipSpaces;
-
- // make sure that on-set and off-set do not overlap
- if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
- {
- fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
- return;
- }
- if ( nVars == 0 )
- { printf( "Function is constant %d.\n", !Cudd_IsComplement(OnSet) ); return; }
-
- // print truth table for debugging
- if ( fPrintTruth )
- {
- DdNode * bCube, * bPart;
- printf( "Truth table: " );
- if ( nVars == 0 )
- printf( "Constant" );
- else if ( nVars == 1 )
- printf( "1-var function" );
- else
- {
-// printf( "0x" );
- for ( d = (1<<(nVars-2)) - 1; d >= 0; d-- )
- {
- int Value = 0;
- for ( s = 0; s < 4; s++ )
- {
- bCube = Extra_bddBitsToCube( dd, 4*d+s, nVars, dd->vars, 0 ); Cudd_Ref( bCube );
- bPart = Cudd_Cofactor( dd, OnSet, bCube ); Cudd_Ref( bPart );
- Value |= ((int)(bPart == b1) << s);
- Cudd_RecursiveDeref( dd, bPart );
- Cudd_RecursiveDeref( dd, bCube );
- }
- if ( Value < 10 )
- fprintf( stdout, "%d", Value );
- else
- fprintf( stdout, "%c", 'a' + Value-10 );
- }
- }
- printf( "\n" );
- }
-
-
-/*
- if ( OnSet == b1 )
- {
- fprintf( Output, "PrintKMap(): Constant 1\n" );
- return;
- }
- if ( OffSet == b1 )
- {
- fprintf( Output, "PrintKMap(): Constant 0\n" );
- return;
- }
-*/
- if ( nVars < 0 || nVars > MAXVARS )
- {
- fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
- return;
- }
-
- // determine the support if it is not given
- if ( XVars == NULL )
- {
- if ( fSuppType == 0 )
- { // assume that the support includes the first nVars of the manager
- assert( nVars );
- for ( v = 0; v < nVars; v++ )
- s_XVars[v] = Cudd_bddIthVar( dd, v );
- }
- else if ( fSuppType == 1 )
- { // assume that the support includes the topmost nVars of the manager
- assert( nVars );
- for ( v = 0; v < nVars; v++ )
- s_XVars[v] = Cudd_bddIthVar( dd, dd->invperm[v] );
- }
- else // determine the support
- {
- DdNode * SuppOn, * SuppOff, * Supp;
- int cVars = 0;
- DdNode * TempSupp;
-
- // determine support
- SuppOn = Cudd_Support( dd, OnSet ); Cudd_Ref( SuppOn );
- SuppOff = Cudd_Support( dd, OffSet ); Cudd_Ref( SuppOff );
- Supp = Cudd_bddAnd( dd, SuppOn, SuppOff ); Cudd_Ref( Supp );
- Cudd_RecursiveDeref( dd, SuppOn );
- Cudd_RecursiveDeref( dd, SuppOff );
-
- nVars = Cudd_SupportSize( dd, Supp );
- if ( nVars > MAXVARS )
- {
- fprintf( Output, "PrintKMap(): The number of variables is more than %d\n", MAXVARS );
- Cudd_RecursiveDeref( dd, Supp );
- return;
- }
-
- // assign variables
- for ( TempSupp = Supp; TempSupp != dd->one; TempSupp = Cudd_T(TempSupp), cVars++ )
- s_XVars[cVars] = Cudd_bddIthVar( dd, TempSupp->index );
-
- Cudd_RecursiveDeref( dd, TempSupp );
- }
- }
- else
- {
- // copy variables
- assert( XVars );
- for ( v = 0; v < nVars; v++ )
- s_XVars[v] = XVars[v];
- }
-
- ////////////////////////////////////////////////////////////////////
- // determine the Karnaugh map parameters
- nVarsVer = nVars/2;
- nVarsHor = nVars - nVarsVer;
-
- nCellsVer = (1<<nVarsVer);
- nCellsHor = (1<<nVarsHor);
- nSkipSpaces = nVarsVer + 1;
-
- ////////////////////////////////////////////////////////////////////
- // print variable names
- fprintf( Output, "\n" );
- for ( w = 0; w < nVarsVer; w++ )
- if ( pVarNames == NULL )
- fprintf( Output, "%c", 'a'+nVarsHor+w );
- else
- fprintf( Output, " %s", pVarNames[nVarsHor+w] );
-
- if ( fHorizontalVarNamesPrintedAbove )
- {
- fprintf( Output, " \\ " );
- for ( w = 0; w < nVarsHor; w++ )
- if ( pVarNames == NULL )
- fprintf( Output, "%c", 'a'+w );
- else
- fprintf( Output, "%s ", pVarNames[w] );
- }
- fprintf( Output, "\n" );
-
- if ( fHorizontalVarNamesPrintedAbove )
- {
- ////////////////////////////////////////////////////////////////////
- // print horizontal digits
- for ( d = 0; d < nVarsHor; d++ )
- {
- for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nCellsHor; n++ )
- if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
- fprintf( Output, "1 " );
- else
- fprintf( Output, "0 " );
- fprintf( Output, "\n" );
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // print the upper line
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- fprintf( Output, "%c", DOUBLE_TOP_LEFT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
- else
- fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
- }
- }
- fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
- fprintf( Output, "\n" );
-
- ////////////////////////////////////////////////////////////////////
- // print the map
- for ( v = 0; v < nCellsVer; v++ )
- {
- DdNode * CubeVerBDD;
-
- // print horizontal digits
-// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nVarsVer; n++ )
- if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
- fprintf( Output, "1" );
- else
- fprintf( Output, "0" );
- fprintf( Output, " " );
-
- // find vertical cube
- CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor, 1 ); Cudd_Ref( CubeVerBDD );
-
- // print text line
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- for ( h = 0; h < nCellsHor; h++ )
- {
- DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
-
- fprintf( Output, " " );
-// fprintf( Output, "x" );
- ///////////////////////////////////////////////////////////////
- // determine what should be printed
- CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars, 1 ); Cudd_Ref( CubeHorBDD );
- Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
- Cudd_RecursiveDeref( dd, CubeHorBDD );
-
- ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
- ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
- Cudd_RecursiveDeref( dd, Prod );
-
-#ifdef WIN32
- {
- HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
- char Symb = 0, Color = 0;
- if ( ValueOnSet == b1 && ValueOffSet == b0 )
- Symb = SYMBOL_ONE, Color = 14; // yellow
- else if ( ValueOnSet == b0 && ValueOffSet == b1 )
- Symb = SYMBOL_ZERO, Color = 11; // blue
- else if ( ValueOnSet == b0 && ValueOffSet == b0 )
- Symb = SYMBOL_DC, Color = 10; // green
- else if ( ValueOnSet == b1 && ValueOffSet == b1 )
- Symb = SYMBOL_OVERLAP, Color = 12; // red
- else
- assert(0);
- SetConsoleTextAttribute( hConsole, Color );
- fprintf( Output, "%c", Symb );
- SetConsoleTextAttribute( hConsole, 7 );
- }
-#else
- {
- if ( ValueOnSet == b1 && ValueOffSet == b0 )
- fprintf( Output, "%c", SYMBOL_ONE );
- else if ( ValueOnSet == b0 && ValueOffSet == b1 )
- fprintf( Output, "%c", SYMBOL_ZERO );
- else if ( ValueOnSet == b0 && ValueOffSet == b0 )
- fprintf( Output, "%c", SYMBOL_DC );
- else if ( ValueOnSet == b1 && ValueOffSet == b1 )
- fprintf( Output, "%c", SYMBOL_OVERLAP );
- else
- assert(0);
- }
-#endif
-
- Cudd_RecursiveDeref( dd, ValueOnSet );
- Cudd_RecursiveDeref( dd, ValueOffSet );
- ///////////////////////////////////////////////////////////////
- fprintf( Output, " " );
-
- if ( h != nCellsHor-1 )
- {
- if ( h&1 )
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- else
- fprintf( Output, "%c", SINGLE_VERTICAL );
- }
- }
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- fprintf( Output, "\n" );
-
- Cudd_RecursiveDeref( dd, CubeVerBDD );
-
- if ( v != nCellsVer-1 )
- // print separator line
- {
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- if ( v&1 )
- {
- fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", DOUBLES_CROSS );
- else
- fprintf( Output, "%c", S_VER_CROSS_D_HOR );
- }
- }
- fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
- }
- else
- {
- fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", S_HOR_CROSS_D_VER );
- else
- fprintf( Output, "%c", SINGLES_CROSS );
- }
- }
- fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
- }
- fprintf( Output, "\n" );
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // print the lower line
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- fprintf( Output, "%c", DOUBLE_BOT_LEFT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
- else
- fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
- }
- }
- fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
- fprintf( Output, "\n" );
-
- if ( !fHorizontalVarNamesPrintedAbove )
- {
- ////////////////////////////////////////////////////////////////////
- // print horizontal digits
- for ( d = 0; d < nVarsHor; d++ )
- {
- for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nCellsHor; n++ )
- if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
- fprintf( Output, "1 " );
- else
- fprintf( Output, "0 " );
-
- /////////////////////////////////
- fprintf( Output, "%c", (char)('a'+d) );
- /////////////////////////////////
- fprintf( Output, "\n" );
- }
- }
-}
-
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the K-map of the relation.]
-
- Description [Assumes that the relation depends the first nXVars of XVars and
- the first nYVars of YVars. Draws X and Y vars and vertical and horizontal vars.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_PrintKMapRelation(
- FILE * Output, /* the output stream */
- DdManager * dd,
- DdNode * OnSet,
- DdNode * OffSet,
- int nXVars,
- int nYVars,
- DdNode ** XVars,
- DdNode ** YVars ) /* the flag which determines how support is computed */
-{
- int d, p, n, s, v, h, w;
- int nVars;
- int nVarsVer;
- int nVarsHor;
- int nCellsVer;
- int nCellsHor;
- int nSkipSpaces;
-
- // make sure that on-set and off-set do not overlap
- if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
- {
- fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
- return;
- }
-
- if ( OnSet == b1 )
- {
- fprintf( Output, "PrintKMap(): Constant 1\n" );
- return;
- }
- if ( OffSet == b1 )
- {
- fprintf( Output, "PrintKMap(): Constant 0\n" );
- return;
- }
-
- nVars = nXVars + nYVars;
- if ( nVars < 0 || nVars > MAXVARS )
- {
- fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
- return;
- }
-
-
- ////////////////////////////////////////////////////////////////////
- // determine the Karnaugh map parameters
- nVarsVer = nXVars;
- nVarsHor = nYVars;
- nCellsVer = (1<<nVarsVer);
- nCellsHor = (1<<nVarsHor);
- nSkipSpaces = nVarsVer + 1;
-
- ////////////////////////////////////////////////////////////////////
- // print variable names
- fprintf( Output, "\n" );
- for ( w = 0; w < nVarsVer; w++ )
- fprintf( Output, "%c", 'a'+nVarsHor+w );
- if ( fHorizontalVarNamesPrintedAbove )
- {
- fprintf( Output, " \\ " );
- for ( w = 0; w < nVarsHor; w++ )
- fprintf( Output, "%c", 'a'+w );
- }
- fprintf( Output, "\n" );
-
- if ( fHorizontalVarNamesPrintedAbove )
- {
- ////////////////////////////////////////////////////////////////////
- // print horizontal digits
- for ( d = 0; d < nVarsHor; d++ )
- {
- for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nCellsHor; n++ )
- if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
- fprintf( Output, "1 " );
- else
- fprintf( Output, "0 " );
- fprintf( Output, "\n" );
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // print the upper line
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- fprintf( Output, "%c", DOUBLE_TOP_LEFT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
- else
- fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
- }
- }
- fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
- fprintf( Output, "\n" );
-
- ////////////////////////////////////////////////////////////////////
- // print the map
- for ( v = 0; v < nCellsVer; v++ )
- {
- DdNode * CubeVerBDD;
-
- // print horizontal digits
-// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nVarsVer; n++ )
- if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
- fprintf( Output, "1" );
- else
- fprintf( Output, "0" );
- fprintf( Output, " " );
-
- // find vertical cube
-// CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor ); Cudd_Ref( CubeVerBDD );
- CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nXVars, XVars, 1 ); Cudd_Ref( CubeVerBDD );
-
- // print text line
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- for ( h = 0; h < nCellsHor; h++ )
- {
- DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
-
- fprintf( Output, " " );
-// fprintf( Output, "x" );
- ///////////////////////////////////////////////////////////////
- // determine what should be printed
-// CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars ); Cudd_Ref( CubeHorBDD );
- CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nYVars, YVars, 1 ); Cudd_Ref( CubeHorBDD );
- Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
- Cudd_RecursiveDeref( dd, CubeHorBDD );
-
- ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
- ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
- Cudd_RecursiveDeref( dd, Prod );
-
- if ( ValueOnSet == b1 && ValueOffSet == b0 )
- fprintf( Output, "%c", SYMBOL_ONE );
- else if ( ValueOnSet == b0 && ValueOffSet == b1 )
- fprintf( Output, "%c", SYMBOL_ZERO );
- else if ( ValueOnSet == b0 && ValueOffSet == b0 )
- fprintf( Output, "%c", SYMBOL_DC );
- else if ( ValueOnSet == b1 && ValueOffSet == b1 )
- fprintf( Output, "%c", SYMBOL_OVERLAP );
- else
- assert(0);
-
- Cudd_RecursiveDeref( dd, ValueOnSet );
- Cudd_RecursiveDeref( dd, ValueOffSet );
- ///////////////////////////////////////////////////////////////
- fprintf( Output, " " );
-
- if ( h != nCellsHor-1 )
- {
- if ( h&1 )
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- else
- fprintf( Output, "%c", SINGLE_VERTICAL );
- }
- }
- fprintf( Output, "%c", DOUBLE_VERTICAL );
- fprintf( Output, "\n" );
-
- Cudd_RecursiveDeref( dd, CubeVerBDD );
-
- if ( v != nCellsVer-1 )
- // print separator line
- {
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- if ( v&1 )
- {
- fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", DOUBLES_CROSS );
- else
- fprintf( Output, "%c", S_VER_CROSS_D_HOR );
- }
- }
- fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
- }
- else
- {
- fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- fprintf( Output, "%c", SINGLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", S_HOR_CROSS_D_VER );
- else
- fprintf( Output, "%c", SINGLES_CROSS );
- }
- }
- fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
- }
- fprintf( Output, "\n" );
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // print the lower line
- for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
- fprintf( Output, "%c", DOUBLE_BOT_LEFT );
- for ( s = 0; s < nCellsHor; s++ )
- {
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- fprintf( Output, "%c", DOUBLE_HORIZONTAL );
- if ( s != nCellsHor-1 )
- {
- if ( s&1 )
- fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
- else
- fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
- }
- }
- fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
- fprintf( Output, "\n" );
-
- if ( !fHorizontalVarNamesPrintedAbove )
- {
- ////////////////////////////////////////////////////////////////////
- // print horizontal digits
- for ( d = 0; d < nVarsHor; d++ )
- {
- for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
- for ( n = 0; n < nCellsHor; n++ )
- if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
- fprintf( Output, "1 " );
- else
- fprintf( Output, "0 " );
-
- /////////////////////////////////
- fprintf( Output, "%c", (char)('a'+d) );
- /////////////////////////////////
- fprintf( Output, "\n" );
- }
- }
-}
-
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int GrayCode ( int BinCode )
-{
- return BinCode ^ ( BinCode >> 1 );
-}
-
-/**Function********************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int BinCode ( int GrayCode )
-{
- int bc = GrayCode;
- while( GrayCode >>= 1 ) bc ^= GrayCode;
- return bc;
-}
-
-
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddMisc.c b/src/misc/extra/extraBddMisc.c
deleted file mode 100644
index a2ba4036..00000000
--- a/src/misc/extra/extraBddMisc.c
+++ /dev/null
@@ -1,2342 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddMisc.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [extra]
-
- Synopsis [DD-based utilities.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: extraBddMisc.c,v 1.4 2005/10/04 00:19:54 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-// file "extraDdTransfer.c"
-static DdNode * extraTransferPermuteRecur( DdManager * ddS, DdManager * ddD, DdNode * f, st__table * table, int * Permute );
-static DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute );
-static DdNode * cuddBddPermuteRecur ARGS( ( DdManager * manager, DdHashTable * table, DdNode * node, int *permut ) );
-
-static DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute );
-
-// file "cuddUtils.c"
-static void ddSupportStep(DdNode *f, int *support);
-static void ddClearFlag(DdNode *f);
-
-static DdNode* extraZddPrimes( DdManager *dd, DdNode* F );
-
-/**AutomaticEnd***************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]
-
- Description [Convert a {A,B}DD from a manager to another one. The orders of the
- variables in the two managers may be different. Returns a
- pointer to the {A,B}DD in the destination manager if successful; NULL
- otherwise. The i-th entry in the array Permute tells what is the index
- of the i-th variable from the old manager in the new manager.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_TransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute )
-{
- DdNode * bRes;
- do
- {
- ddDestination->reordered = 0;
- bRes = extraTransferPermute( ddSource, ddDestination, f, Permute );
- }
- while ( ddDestination->reordered == 1 );
- return ( bRes );
-
-} /* end of Extra_TransferPermute */
-
-/**Function********************************************************************
-
- Synopsis [Transfers the BDD from one manager into another level by level.]
-
- Description [Transfers the BDD from one manager into another while
- preserving the correspondence between variables level by level.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_TransferLevelByLevel( DdManager * ddSource, DdManager * ddDestination, DdNode * f )
-{
- DdNode * bRes;
- int * pPermute;
- int nMin, nMax, i;
-
- nMin = ddMin(ddSource->size, ddDestination->size);
- nMax = ddMax(ddSource->size, ddDestination->size);
- pPermute = ABC_ALLOC( int, nMax );
- // set up the variable permutation
- for ( i = 0; i < nMin; i++ )
- pPermute[ ddSource->invperm[i] ] = ddDestination->invperm[i];
- if ( ddSource->size > ddDestination->size )
- {
- for ( ; i < nMax; i++ )
- pPermute[ ddSource->invperm[i] ] = -1;
- }
- bRes = Extra_TransferPermute( ddSource, ddDestination, f, pPermute );
- ABC_FREE( pPermute );
- return bRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Remaps the function to depend on the topmost variables on the manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddRemapUp(
- DdManager * dd,
- DdNode * bF )
-{
- int * pPermute;
- DdNode * bSupp, * bTemp, * bRes;
- int Counter;
-
- pPermute = ABC_ALLOC( int, dd->size );
-
- // get support
- bSupp = Cudd_Support( dd, bF ); Cudd_Ref( bSupp );
-
- // create the variable map
- // to remap the DD into the upper part of the manager
- Counter = 0;
- for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
- pPermute[bTemp->index] = dd->invperm[Counter++];
-
- // transfer the BDD and remap it
- bRes = Cudd_bddPermute( dd, bF, pPermute ); Cudd_Ref( bRes );
-
- // remove support
- Cudd_RecursiveDeref( dd, bSupp );
-
- // return
- Cudd_Deref( bRes );
- ABC_FREE( pPermute );
- return bRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Moves the BDD by the given number of variables up or down.]
-
- Description []
-
- SideEffects []
-
- SeeAlso [Extra_bddShift]
-
-******************************************************************************/
-DdNode * Extra_bddMove(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- int nVars)
-{
- DdNode * res;
- DdNode * bVars;
- if ( nVars == 0 )
- return bF;
- if ( Cudd_IsConstant(bF) )
- return bF;
- assert( nVars <= dd->size );
- if ( nVars > 0 )
- bVars = dd->vars[nVars];
- else
- bVars = Cudd_Not(dd->vars[-nVars]);
-
- do {
- dd->reordered = 0;
- res = extraBddMove( dd, bF, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_bddMove */
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_StopManager( DdManager * dd )
-{
- int RetValue;
- // check for remaining references in the package
- RetValue = Cudd_CheckZeroRef( dd );
- if ( RetValue > 10 )
-// if ( RetValue )
- printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
-// Cudd_PrintInfo( dd, stdout );
- Cudd_Quit( dd );
-}
-
-/**Function********************************************************************
-
- Synopsis [Outputs the BDD in a readable format.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_bddPrint( DdManager * dd, DdNode * F )
-{
- DdGen * Gen;
- int * Cube;
- CUDD_VALUE_TYPE Value;
- int nVars = dd->size;
- int fFirstCube = 1;
- int i;
-
- if ( F == NULL )
- {
- printf("NULL");
- return;
- }
- if ( F == b0 )
- {
- printf("Constant 0");
- return;
- }
- if ( F == b1 )
- {
- printf("Constant 1");
- return;
- }
-
- Cudd_ForeachCube( dd, F, Gen, Cube, Value )
- {
- if ( fFirstCube )
- fFirstCube = 0;
- else
-// Output << " + ";
- printf( " + " );
-
- for ( i = 0; i < nVars; i++ )
- if ( Cube[i] == 0 )
- printf( "[%d]'", i );
-// printf( "%c'", (char)('a'+i) );
- else if ( Cube[i] == 1 )
- printf( "[%d]", i );
-// printf( "%c", (char)('a'+i) );
- }
-
-// printf("\n");
-}
-
-/**Function********************************************************************
-
- Synopsis [Outputs the BDD in a readable format.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_bddPrintSupport( DdManager * dd, DdNode * F )
-{
- DdNode * bSupp;
- bSupp = Cudd_Support( dd, F ); Cudd_Ref( bSupp );
- Extra_bddPrint( dd, bSupp );
- Cudd_RecursiveDeref( dd, bSupp );
-}
-
-/**Function********************************************************************
-
- Synopsis [Returns the size of the support.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddSuppSize( DdManager * dd, DdNode * bSupp )
-{
- int Counter = 0;
- while ( bSupp != b1 )
- {
- assert( !Cudd_IsComplement(bSupp) );
- assert( cuddE(bSupp) == b0 );
-
- bSupp = cuddT(bSupp);
- Counter++;
- }
- return Counter;
-}
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if the support contains the given BDD variable.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddSuppContainVar( DdManager * dd, DdNode * bS, DdNode * bVar )
-{
- for( ; bS != b1; bS = cuddT(bS) )
- if ( bS->index == bVar->index )
- return 1;
- return 0;
-}
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if two supports represented as BDD cubes are overlapping.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddSuppOverlapping( DdManager * dd, DdNode * S1, DdNode * S2 )
-{
- while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
- {
- // if the top vars are the same, they intersect
- if ( S1->index == S2->index )
- return 1;
- // if the top vars are different, skip the one, which is higher
- if ( dd->perm[S1->index] < dd->perm[S2->index] )
- S1 = cuddT(S1);
- else
- S2 = cuddT(S2);
- }
- return 0;
-}
-
-/**Function********************************************************************
-
- Synopsis [Returns the number of different vars in two supports.]
-
- Description [Counts the number of variables that appear in one support and
- does not appear in other support. If the number exceeds DiffMax, returns DiffMax.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddSuppDifferentVars( DdManager * dd, DdNode * S1, DdNode * S2, int DiffMax )
-{
- int Result = 0;
- while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
- {
- // if the top vars are the same, this var is the same
- if ( S1->index == S2->index )
- {
- S1 = cuddT(S1);
- S2 = cuddT(S2);
- continue;
- }
- // the top var is different
- Result++;
-
- if ( Result >= DiffMax )
- return DiffMax;
-
- // if the top vars are different, skip the one, which is higher
- if ( dd->perm[S1->index] < dd->perm[S2->index] )
- S1 = cuddT(S1);
- else
- S2 = cuddT(S2);
- }
-
- // consider the remaining variables
- if ( S1->index != CUDD_CONST_INDEX )
- Result += Extra_bddSuppSize(dd,S1);
- else if ( S2->index != CUDD_CONST_INDEX )
- Result += Extra_bddSuppSize(dd,S2);
-
- if ( Result >= DiffMax )
- return DiffMax;
- return Result;
-}
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the support containment.]
-
- Description [This function returns 1 if one support is contained in another.
- In this case, bLarge (bSmall) is assigned to point to the larger (smaller) support.
- If the supports are identical, return 0 and does not assign the supports!]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddSuppCheckContainment( DdManager * dd, DdNode * bL, DdNode * bH, DdNode ** bLarge, DdNode ** bSmall )
-{
- DdNode * bSL = bL;
- DdNode * bSH = bH;
- int fLcontainsH = 1;
- int fHcontainsL = 1;
- int TopVar;
-
- if ( bSL == bSH )
- return 0;
-
- while ( bSL != b1 || bSH != b1 )
- {
- if ( bSL == b1 )
- { // Low component has no vars; High components has some vars
- fLcontainsH = 0;
- if ( fHcontainsL == 0 )
- return 0;
- else
- break;
- }
-
- if ( bSH == b1 )
- { // similarly
- fHcontainsL = 0;
- if ( fLcontainsH == 0 )
- return 0;
- else
- break;
- }
-
- // determine the topmost var of the supports by comparing their levels
- if ( dd->perm[bSL->index] < dd->perm[bSH->index] )
- TopVar = bSL->index;
- else
- TopVar = bSH->index;
-
- if ( TopVar == bSL->index && TopVar == bSH->index )
- { // they are on the same level
- // it does not tell us anything about their containment
- // skip this var
- bSL = cuddT(bSL);
- bSH = cuddT(bSH);
- }
- else if ( TopVar == bSL->index ) // and TopVar != bSH->index
- { // Low components is higher and contains more vars
- // it is not possible that High component contains Low
- fHcontainsL = 0;
- // skip this var
- bSL = cuddT(bSL);
- }
- else // if ( TopVar == bSH->index ) // and TopVar != bSL->index
- { // similarly
- fLcontainsH = 0;
- // skip this var
- bSH = cuddT(bSH);
- }
-
- // check the stopping condition
- if ( !fHcontainsL && !fLcontainsH )
- return 0;
- }
- // only one of them can be true at the same time
- assert( !fHcontainsL || !fLcontainsH );
- if ( fHcontainsL )
- {
- *bLarge = bH;
- *bSmall = bL;
- }
- else // fLcontainsH
- {
- *bLarge = bL;
- *bSmall = bH;
- }
- return 1;
-}
-
-
-/**Function********************************************************************
-
- Synopsis [Finds variables on which the DD depends and returns them as am array.]
-
- Description [Finds the variables on which the DD depends. Returns an array
- with entries set to 1 for those variables that belong to the support;
- NULL otherwise. The array is allocated by the user and should have at least
- as many entries as the maximum number of variables in BDD and ZDD parts of
- the manager.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-int *
-Extra_SupportArray(
- DdManager * dd, /* manager */
- DdNode * f, /* DD whose support is sought */
- int * support ) /* array allocated by the user */
-{
- int i, size;
-
- /* Initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- 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 Extra_SupportArray */
-
-/**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]
-
-******************************************************************************/
-int *
-Extra_VectorSupportArray(
- DdManager * dd, /* manager */
- DdNode ** F, /* array of DDs whose support is sought */
- int n, /* size of the array */
- int * support ) /* array allocated by the user */
-{
- int i, size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax( dd->size, dd->sizeZ );
- 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;
-}
-
-/**Function********************************************************************
-
- Synopsis [Find any cube belonging to the on-set of the function.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddFindOneCube( DdManager * dd, DdNode * bF )
-{
- char * s_Temp;
- DdNode * bCube, * bTemp;
- int v;
-
- // get the vector of variables in the cube
- s_Temp = ABC_ALLOC( char, dd->size );
- Cudd_bddPickOneCube( dd, bF, s_Temp );
-
- // start the cube
- bCube = b1; Cudd_Ref( bCube );
- for ( v = 0; v < dd->size; v++ )
- if ( s_Temp[v] == 0 )
- {
-// Cube &= !s_XVars[v];
- bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(dd->vars[v]) ); Cudd_Ref( bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- else if ( s_Temp[v] == 1 )
- {
-// Cube &= s_XVars[v];
- bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[v] ); Cudd_Ref( bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref(bCube);
- ABC_FREE( s_Temp );
- return bCube;
-}
-
-/**Function********************************************************************
-
- Synopsis [Returns one cube contained in the given BDD.]
-
- Description [This function returns the cube with the smallest
- bits-to-integer value.]
-
- SideEffects []
-
-******************************************************************************/
-DdNode * Extra_bddGetOneCube( DdManager * dd, DdNode * bFunc )
-{
- DdNode * bFuncR, * bFunc0, * bFunc1;
- DdNode * bRes0, * bRes1, * bRes;
-
- bFuncR = Cudd_Regular(bFunc);
- if ( cuddIsConstant(bFuncR) )
- return bFunc;
-
- // cofactor
- if ( Cudd_IsComplement(bFunc) )
- {
- bFunc0 = Cudd_Not( cuddE(bFuncR) );
- bFunc1 = Cudd_Not( cuddT(bFuncR) );
- }
- else
- {
- bFunc0 = cuddE(bFuncR);
- bFunc1 = cuddT(bFuncR);
- }
-
- // try to find the cube with the negative literal
- bRes0 = Extra_bddGetOneCube( dd, bFunc0 ); Cudd_Ref( bRes0 );
-
- if ( bRes0 != b0 )
- {
- bRes = Cudd_bddAnd( dd, bRes0, Cudd_Not(dd->vars[bFuncR->index]) ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bRes0 );
- }
- else
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- // try to find the cube with the positive literal
- bRes1 = Extra_bddGetOneCube( dd, bFunc1 ); Cudd_Ref( bRes1 );
- assert( bRes1 != b0 );
- bRes = Cudd_bddAnd( dd, bRes1, dd->vars[bFuncR->index] ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bRes1 );
- }
-
- Cudd_Deref( bRes );
- return bRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int iStop )
-{
- DdNode * bTemp, * bProd;
- int i;
- assert( iStart <= iStop );
- assert( iStart >= 0 && iStart <= dd->size );
- assert( iStop >= 0 && iStop <= dd->size );
- bProd = b1; Cudd_Ref( bProd );
- for ( i = iStart; i < iStop; i++ )
- {
- bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] ); Cudd_Ref( bProd );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bProd );
- return bProd;
-}
-
-/**Function********************************************************************
-
- Synopsis [Computes the cube of BDD variables corresponding to bits it the bit-code]
-
- Description [Returns a bdd composed of elementary bdds found in array BddVars[] such
- that the bdd vars encode the number Value of bit length CodeWidth (if fMsbFirst is 1,
- the most significant bit is encoded with the first bdd variable). If the variables
- BddVars are not specified, takes the first CodeWidth variables of the manager]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst )
-{
- int z;
- DdNode * bTemp, * bVar, * bVarBdd, * bResult;
-
- bResult = b1; Cudd_Ref( bResult );
- for ( z = 0; z < CodeWidth; z++ )
- {
- bVarBdd = (pbVars)? pbVars[z]: dd->vars[z];
- if ( fMsbFirst )
- bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (CodeWidth-1-z)))==0 );
- else
- bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (z)))==0 );
- bResult = Cudd_bddAnd( dd, bTemp = bResult, bVar ); Cudd_Ref( bResult );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bResult );
-
- return bResult;
-} /* end of Extra_bddBitsToCube */
-
-/**Function********************************************************************
-
- Synopsis [Finds the support as a negative polarity cube.]
-
- Description [Finds the variables on which a DD depends. Returns a BDD
- consisting of the product of the variables in the negative polarity
- if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_VectorSupport Cudd_Support]
-
-******************************************************************************/
-DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f )
-{
- 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 = ABC_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 ) );
- //////////////////////////////////////////////////////////////////
- var = Cudd_Not(var);
- //////////////////////////////////////////////////////////////////
- cuddRef( var );
- tmp = cuddBddAndRecur( dd, res, var );
- if ( tmp == NULL )
- {
- Cudd_RecursiveDeref( dd, res );
- Cudd_RecursiveDeref( dd, var );
- res = NULL;
- break;
- }
- cuddRef( tmp );
- Cudd_RecursiveDeref( dd, res );
- Cudd_RecursiveDeref( dd, var );
- res = tmp;
- }
- }
- }
- while ( dd->reordered == 1 );
-
- ABC_FREE( support );
- if ( res != NULL )
- cuddDeref( res );
- return ( res );
-
-} /* end of Extra_SupportNeg */
-
-/**Function********************************************************************
-
- Synopsis [Returns 1 if the BDD is the BDD of elementary variable.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddIsVar( DdNode * bFunc )
-{
- bFunc = Cudd_Regular( bFunc );
- if ( cuddIsConstant(bFunc) )
- return 0;
- return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
-}
-
-/**Function********************************************************************
-
- Synopsis [Creates AND composed of the first nVars of the manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars )
-{
- DdNode * bFunc, * bTemp;
- int i;
- bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
- for ( i = 0; i < nVars; i++ )
- {
- bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bFunc );
- return bFunc;
-}
-
-/**Function********************************************************************
-
- Synopsis [Creates OR composed of the first nVars of the manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddCreateOr( DdManager * dd, int nVars )
-{
- DdNode * bFunc, * bTemp;
- int i;
- bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
- for ( i = 0; i < nVars; i++ )
- {
- bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bFunc );
- return bFunc;
-}
-
-/**Function********************************************************************
-
- Synopsis [Creates EXOR composed of the first nVars of the manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddCreateExor( DdManager * dd, int nVars )
-{
- DdNode * bFunc, * bTemp;
- int i;
- bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
- for ( i = 0; i < nVars; i++ )
- {
- bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bFunc );
- return bFunc;
-}
-
-/**Function********************************************************************
-
- Synopsis [Computes the set of primes as a ZDD.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddPrimes( DdManager * dd, DdNode * F )
-{
- DdNode *res;
- do {
- dd->reordered = 0;
- res = extraZddPrimes(dd, F);
- if ( dd->reordered == 1 )
- printf("\nReordering in Extra_zddPrimes()\n");
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddPrimes */
-
-/**Function********************************************************************
-
- Synopsis [Permutes the variables of the array of BDDs.]
-
- 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.
- The DDs in the resulting array are already referenced.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
-
-******************************************************************************/
-void Extra_bddPermuteArray( DdManager * manager, DdNode ** bNodesIn, DdNode ** bNodesOut, int nNodes, int *permut )
-{
- DdHashTable *table;
- int i, k;
- do
- {
- manager->reordered = 0;
- table = cuddHashTableInit( manager, 1, 2 );
-
- /* permute the output functions one-by-one */
- for ( i = 0; i < nNodes; i++ )
- {
- bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
- if ( bNodesOut[i] == NULL )
- {
- /* deref the array of the already computed outputs */
- for ( k = 0; k < i; k++ )
- Cudd_RecursiveDeref( manager, bNodesOut[k] );
- break;
- }
- cuddRef( bNodesOut[i] );
- }
- /* Dispose of local cache. */
- cuddHashTableQuit( table );
- }
- while ( manager->reordered == 1 );
-} /* end of Extra_bddPermuteArray */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the positive polarty cube composed of the first vars in the array.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddComputeCube( DdManager * dd, DdNode ** bXVars, int nVars )
-{
- DdNode * bRes;
- DdNode * bTemp;
- int i;
-
- bRes = b1; Cudd_Ref( bRes );
- for ( i = 0; i < nVars; i++ )
- {
- bRes = Cudd_bddAnd( dd, bTemp = bRes, bXVars[i] ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bTemp );
- }
-
- Cudd_Deref( bRes );
- return bRes;
-}
-
-/**Function********************************************************************
-
- Synopsis [Changes the polarity of vars listed in the cube.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddChangePolarity(
- DdManager * dd, /* the DD manager */
- DdNode * bFunc,
- DdNode * bVars)
-{
- DdNode *res;
- do {
- dd->reordered = 0;
- res = extraBddChangePolarity( dd, bFunc, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_bddChangePolarity */
-
-
-/**Function*************************************************************
-
- Synopsis [Checks if the given variable belongs to the cube.]
-
- Description [Return -1 if the var does not appear in the cube.
- Otherwise, returns polarity (0 or 1) of the var in the cube.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Extra_bddVarIsInCube( DdNode * bCube, int iVar )
-{
- DdNode * bCube0, * bCube1;
- while ( Cudd_Regular(bCube)->index != CUDD_CONST_INDEX )
- {
- bCube0 = Cudd_NotCond( cuddE(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
- bCube1 = Cudd_NotCond( cuddT(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
- // make sure it is a cube
- assert( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) || // bCube0 == 0
- (Cudd_IsComplement(bCube1) && Cudd_Regular(bCube1)->index == CUDD_CONST_INDEX) ); // bCube1 == 0
- // quit if it is the last one
- if ( Cudd_Regular(bCube)->index == iVar )
- return (int)(Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX);
- // get the next cube
- if ( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) )
- bCube = bCube1;
- else
- bCube = bCube0;
- }
- return -1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the AND of two BDD with different orders.]
-
- Description [Derives the result of Boolean AND of bF and bG in ddF.
- The array pPermute gives the mapping of variables of ddG into that of ddF.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Extra_bddAndPermute( DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute )
-{
- DdHashTable * table;
- DdNode * bRes;
- do
- {
- ddF->reordered = 0;
- table = cuddHashTableInit( ddF, 2, 256 );
- if (table == NULL) return NULL;
- bRes = extraBddAndPermute( table, ddF, bF, ddG, bG, pPermute );
- if ( bRes ) cuddRef( bRes );
- cuddHashTableQuit( table );
- if ( bRes ) cuddDeref( bRes );
-//if ( ddF->reordered == 1 )
-//printf( "Reordering happened\n" );
- }
- while ( ddF->reordered == 1 );
-//printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d\n",
-// Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes),
-// Cudd_DagSize(bF) * Cudd_DagSize(bG) );
- return ( bRes );
-}
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraBddMove(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- DdNode * bDist)
-{
- DdNode * bRes;
-
- if ( Cudd_IsConstant(bF) )
- return bF;
-
- if ( (bRes = cuddCacheLookup2(dd, extraBddMove, bF, bDist)) )
- return bRes;
- else
- {
- DdNode * bRes0, * bRes1;
- DdNode * bF0, * bF1;
- DdNode * bFR = Cudd_Regular(bF);
- int VarNew;
-
- if ( Cudd_IsComplement(bDist) )
- VarNew = bFR->index - Cudd_Not(bDist)->index;
- else
- VarNew = bFR->index + bDist->index;
- assert( VarNew < dd->size );
-
- // cofactor the functions
- if ( bFR != bF ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- bRes0 = extraBddMove( dd, bF0, bDist );
- if ( bRes0 == NULL )
- return NULL;
- cuddRef( bRes0 );
-
- bRes1 = extraBddMove( dd, bF1, bDist );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bRes1 );
-
- /* only bRes0 and bRes1 are referenced at this point */
- bRes = cuddBddIteRecur( dd, dd->vars[VarNew], bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bRes1 );
- return NULL;
- }
- cuddRef( bRes );
- Cudd_RecursiveDeref( dd, bRes0 );
- Cudd_RecursiveDeref( dd, bRes1 );
-
- /* insert the result into cache */
- cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
- cuddDeref( bRes );
- return bRes;
- }
-} /* end of extraBddMove */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds three cofactors of the cover w.r.t. to the topmost variable.]
-
- Description [Finds three cofactors of the cover w.r.t. to the topmost variable.
- Does not check the cover for being a constant. Assumes that ZDD variables encoding
- positive and negative polarities are adjacent in the variable order. Is different
- from cuddZddGetCofactors3() in that it does not compute the cofactors w.r.t. the
- given variable but takes the cofactors with respent to the topmost variable.
- This function is more efficient when used in recursive procedures because it does
- not require referencing of the resulting cofactors (compare cuddZddProduct()
- and extraZddPrimeProduct()).]
-
- SideEffects [None]
-
- SeeAlso [cuddZddGetCofactors3]
-
-******************************************************************************/
-void
-extraDecomposeCover(
- DdManager* dd, /* the manager */
- DdNode* zC, /* the cover */
- DdNode** zC0, /* the pointer to the negative var cofactor */
- DdNode** zC1, /* the pointer to the positive var cofactor */
- DdNode** zC2 ) /* the pointer to the cofactor without var */
-{
- if ( (zC->index & 1) == 0 )
- { /* the top variable is present in positive polarity and maybe in negative */
-
- DdNode *Temp = cuddE( zC );
- *zC1 = cuddT( zC );
- if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
- { /* Temp is not a terminal node
- * top var is present in negative polarity */
- *zC2 = cuddE( Temp );
- *zC0 = cuddT( Temp );
- }
- else
- { /* top var is not present in negative polarity */
- *zC2 = Temp;
- *zC0 = dd->zero;
- }
- }
- else
- { /* the top variable is present only in negative */
- *zC1 = dd->zero;
- *zC2 = cuddE( zC );
- *zC0 = cuddT( zC );
- }
-} /* extraDecomposeCover */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the total number of cubes in the ISOPs of the functions.]
-
- Description [Returns -1 if the number of cubes exceeds the limit.]
-
- SideEffects [None]
-
- SeeAlso [Extra_TransferPermute]
-
-******************************************************************************/
-static DdNode * extraBddCountCubes( DdManager * dd, DdNode * L, DdNode * U, st__table *table, int * pnCubes, int Limit )
-{
- 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;
- int Count0 = 0, Count1 = 0, Count2 = 0;
-
- statLine(dd);
- if (L == zero)
- {
- *pnCubes = 0;
- return(zero);
- }
- if (U == one)
- {
- *pnCubes = 1;
- return(one);
- }
-
- /* Check cache */
- r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
- if (r)
- {
- int nCubes = 0;
- if ( st__lookup( table, (char *)r, (char **)&nCubes ) )
- *pnCubes = nCubes;
- else assert( 0 );
- 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 = extraBddCountCubes(dd, Lsub0, Usub0, table, &Count0, Limit);
- if (Isub0 == NULL) {
- Cudd_RecursiveDeref(dd, Lsub0);
- Cudd_RecursiveDeref(dd, Lsub1);
- return(NULL);
- }
- Cudd_Ref(Isub0);
- Isub1 = extraBddCountCubes(dd, Lsub1, Usub1, table, &Count1, Limit);
- 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 = extraBddCountCubes(dd, Ld, Ud, table, &Count2, Limit);
- 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);
- *pnCubes = Count0 + Count1 + Count2;
- if ( st__add_direct( table, (char *)r, (char *)(ABC_PTRINT_T)*pnCubes ) == st__OUT_OF_MEM )
- {
- Cudd_RecursiveDeref( dd, r );
- return NULL;
- }
- if ( *pnCubes > Limit )
- {
- Cudd_RecursiveDeref( dd, r );
- return NULL;
- }
- //printf( "%d ", *pnCubes );
- Cudd_Deref(r);
- return r;
-}
-int Extra_bddCountCubes( DdManager * dd, DdNode ** pFuncs, int nFuncs, int fMode, int nLimit, int * pGuide )
-{
- DdNode * pF0, * pF1;
- int i, Count, Count0, Count1, CounterAll = 0;
- st__table *table = st__init_table( st__ptrcmp, st__ptrhash );
- unsigned int saveLimit = dd->maxLive;
- dd->maxLive = dd->keys - dd->dead + 1000000; // limit on intermediate BDD nodes
- for ( i = 0; i < nFuncs; i++ )
- {
- if ( !pFuncs[i] )
- continue;
- pF1 = pF0 = NULL;
- Count0 = Count1 = nLimit;
- if ( fMode == -1 || fMode == 1 ) // both or pos
- pF1 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count1, nLimit );
- pFuncs[i] = Cudd_Not( pFuncs[i] );
- if ( fMode == -1 || fMode == 0 ) // both or neg
- pF0 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count0, Count1 );
- pFuncs[i] = Cudd_Not( pFuncs[i] );
- if ( !pF1 && !pF0 )
- break;
- if ( !pF0 ) pGuide[i] = 1, Count = Count1; // use pos
- else if ( !pF1 ) pGuide[i] = 0, Count = Count0; // use neg
- else if ( Count1 <= Count0 ) pGuide[i] = 1, Count = Count1; // use pos
- else pGuide[i] = 0, Count = Count0; // use neg
- CounterAll += Count;
- //printf( "Output %5d has %5d cubes (%d) (%5d and %5d)\n", nOuts++, Count, pGuide[i], Count1, Count0 );
- }
- dd->maxLive = saveLimit;
- st__free_table( table );
- return i == nFuncs ? CounterAll : -1;
-} /* end of Extra_bddCountCubes */
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static 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 [Extra_TransferPermute]
-
-******************************************************************************/
-DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
-{
- 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 = extraTransferPermuteRecur( ddS, ddD, f, table, Permute );
- 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, ( const 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 extraTransferPermute */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Extra_TransferPermute.]
-
- Description [Performs the recursive step of Extra_TransferPermute.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [extraTransferPermute]
-
-******************************************************************************/
-static DdNode *
-extraTransferPermuteRecur(
- DdManager * ddS,
- DdManager * ddD,
- DdNode * f,
- st__table * table,
- int * Permute )
-{
- 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 ) );
-
- if ( ddS->TimeStop && Abc_Clock() > ddS->TimeStop )
- return NULL;
- if ( ddD->TimeStop && Abc_Clock() > ddD->TimeStop )
- return NULL;
-
- /* Recursive step. */
- if ( Permute )
- index = Permute[f->index];
- else
- index = f->index;
-
- ft = cuddT( f );
- fe = cuddE( f );
-
- t = extraTransferPermuteRecur( ddS, ddD, ft, table, Permute );
- if ( t == NULL )
- {
- return ( NULL );
- }
- cuddRef( t );
-
- e = extraTransferPermuteRecur( ddS, ddD, fe, table, Permute );
- if ( e == NULL )
- {
- Cudd_RecursiveDeref( ddD, t );
- return ( NULL );
- }
- cuddRef( e );
-
- zero = Cudd_Not(ddD->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 extraTransferPermuteRecur */
-
-/**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 [Composed three subcovers into one ZDD.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-extraComposeCover(
- DdManager* dd, /* the manager */
- DdNode* zC0, /* the pointer to the negative var cofactor */
- DdNode* zC1, /* the pointer to the positive var cofactor */
- DdNode* zC2, /* the pointer to the cofactor without var */
- int TopVar) /* the index of the positive ZDD var */
-{
- DdNode * zRes, * zTemp;
- /* compose with-neg-var and without-var using the neg ZDD var */
- zTemp = cuddZddGetNode( dd, 2*TopVar + 1, zC0, zC2 );
- if ( zTemp == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zC0);
- Cudd_RecursiveDerefZdd(dd, zC1);
- Cudd_RecursiveDerefZdd(dd, zC2);
- return NULL;
- }
- cuddRef( zTemp );
- cuddDeref( zC0 );
- cuddDeref( zC2 );
-
- /* compose with-pos-var and previous result using the pos ZDD var */
- zRes = cuddZddGetNode( dd, 2*TopVar, zC1, zTemp );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd(dd, zC1);
- Cudd_RecursiveDerefZdd(dd, zTemp);
- return NULL;
- }
- cuddDeref( zC1 );
- cuddDeref( zTemp );
- return zRes;
-} /* extraComposeCover */
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of prime computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode* extraZddPrimes( DdManager *dd, DdNode* F )
-{
- DdNode *zRes;
-
- if ( F == Cudd_Not( dd->one ) )
- return dd->zero;
- if ( F == dd->one )
- return dd->one;
-
- /* check cache */
- zRes = cuddCacheLookup1Zdd(dd, extraZddPrimes, F);
- if (zRes)
- return(zRes);
- {
- /* temporary variables */
- DdNode *bF01, *zP0, *zP1;
- /* three components of the prime set */
- DdNode *zResE, *zResP, *zResN;
- int fIsComp = Cudd_IsComplement( F );
-
- /* find cofactors of F */
- DdNode * bF0 = Cudd_NotCond( Cudd_E( F ), fIsComp );
- DdNode * bF1 = Cudd_NotCond( Cudd_T( F ), fIsComp );
-
- /* find the intersection of cofactors */
- bF01 = cuddBddAndRecur( dd, bF0, bF1 );
- if ( bF01 == NULL ) return NULL;
- cuddRef( bF01 );
-
- /* solve the problems for cofactors */
- zP0 = extraZddPrimes( dd, bF0 );
- if ( zP0 == NULL )
- {
- Cudd_RecursiveDeref( dd, bF01 );
- return NULL;
- }
- cuddRef( zP0 );
-
- zP1 = extraZddPrimes( dd, bF1 );
- if ( zP1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bF01 );
- Cudd_RecursiveDerefZdd( dd, zP0 );
- return NULL;
- }
- cuddRef( zP1 );
-
- /* check for local unateness */
- if ( bF01 == bF0 ) /* unate increasing */
- {
- /* intersection is useless */
- cuddDeref( bF01 );
- /* the primes of intersection are the primes of F0 */
- zResE = zP0;
- /* there are no primes with negative var */
- zResN = dd->zero;
- cuddRef( zResN );
- /* primes with positive var are primes of F1 that are not primes of F01 */
- zResP = cuddZddDiff( dd, zP1, zP0 );
- if ( zResP == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zResE );
- Cudd_RecursiveDerefZdd( dd, zResN );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- return NULL;
- }
- cuddRef( zResP );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- }
- else if ( bF01 == bF1 ) /* unate decreasing */
- {
- /* intersection is useless */
- cuddDeref( bF01 );
- /* the primes of intersection are the primes of F1 */
- zResE = zP1;
- /* there are no primes with positive var */
- zResP = dd->zero;
- cuddRef( zResP );
- /* primes with negative var are primes of F0 that are not primes of F01 */
- zResN = cuddZddDiff( dd, zP0, zP1 );
- if ( zResN == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zResE );
- Cudd_RecursiveDerefZdd( dd, zResP );
- Cudd_RecursiveDerefZdd( dd, zP0 );
- return NULL;
- }
- cuddRef( zResN );
- Cudd_RecursiveDerefZdd( dd, zP0 );
- }
- else /* not unate */
- {
- /* primes without the top var are primes of F10 */
- zResE = extraZddPrimes( dd, bF01 );
- if ( zResE == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, bF01 );
- Cudd_RecursiveDerefZdd( dd, zP0 );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- return NULL;
- }
- cuddRef( zResE );
- Cudd_RecursiveDeref( dd, bF01 );
-
- /* primes with the negative top var are those of P0 that are not in F10 */
- zResN = cuddZddDiff( dd, zP0, zResE );
- if ( zResN == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zResE );
- Cudd_RecursiveDerefZdd( dd, zP0 );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- return NULL;
- }
- cuddRef( zResN );
- Cudd_RecursiveDerefZdd( dd, zP0 );
-
- /* primes with the positive top var are those of P1 that are not in F10 */
- zResP = cuddZddDiff( dd, zP1, zResE );
- if ( zResP == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zResE );
- Cudd_RecursiveDerefZdd( dd, zResN );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- return NULL;
- }
- cuddRef( zResP );
- Cudd_RecursiveDerefZdd( dd, zP1 );
- }
-
- zRes = extraComposeCover( dd, zResN, zResP, zResE, Cudd_Regular(F)->index );
- if ( zRes == NULL ) return NULL;
-
- /* insert the result into cache */
- cuddCacheInsert1(dd, extraZddPrimes, F, zRes);
- return zRes;
- }
-} /* end of extraZddPrimes */
-
-/**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 )
- {
- 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 [Performs the reordering-sensitive step of Extra_bddChangePolarity().]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraBddChangePolarity(
- DdManager * dd, /* the DD manager */
- DdNode * bFunc,
- DdNode * bVars)
-{
- DdNode * bRes;
-
- if ( bVars == b1 )
- return bFunc;
- if ( Cudd_IsConstant(bFunc) )
- return bFunc;
-
- if ( (bRes = cuddCacheLookup2(dd, extraBddChangePolarity, bFunc, bVars)) )
- return bRes;
- else
- {
- DdNode * bFR = Cudd_Regular(bFunc);
- int LevelF = dd->perm[bFR->index];
- int LevelV = dd->perm[bVars->index];
-
- if ( LevelV < LevelF )
- bRes = extraBddChangePolarity( dd, bFunc, cuddT(bVars) );
- else // if ( LevelF <= LevelV )
- {
- DdNode * bRes0, * bRes1;
- DdNode * bF0, * bF1;
- DdNode * bVarsNext;
-
- // cofactor the functions
- if ( bFR != bFunc ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- if ( LevelF == LevelV )
- bVarsNext = cuddT(bVars);
- else
- bVarsNext = bVars;
-
- bRes0 = extraBddChangePolarity( dd, bF0, bVarsNext );
- if ( bRes0 == NULL )
- return NULL;
- cuddRef( bRes0 );
-
- bRes1 = extraBddChangePolarity( dd, bF1, bVarsNext );
- if ( bRes1 == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes0 );
- return NULL;
- }
- cuddRef( bRes1 );
-
- if ( LevelF == LevelV )
- { // swap the cofactors
- DdNode * bTemp;
- bTemp = bRes0;
- bRes0 = bRes1;
- bRes1 = bTemp;
- }
-
- /* only aRes0 and aRes1 are referenced at this point */
-
- /* consider the case when Res0 and Res1 are the same node */
- if ( bRes0 == bRes1 )
- bRes = bRes1;
- /* consider the case when Res1 is complemented */
- else if ( Cudd_IsComplement(bRes1) )
- {
- bRes = cuddUniqueInter(dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- bRes = Cudd_Not(bRes);
- }
- else
- {
- bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref(dd,bRes0);
- Cudd_RecursiveDeref(dd,bRes1);
- return NULL;
- }
- }
- cuddDeref( bRes0 );
- cuddDeref( bRes1 );
- }
-
- /* insert the result into cache */
- cuddCacheInsert2(dd, extraBddChangePolarity, bFunc, bVars, bRes);
- return bRes;
- }
-} /* end of extraBddChangePolarity */
-
-
-
-static int Counter = 0;
-
-/**Function*************************************************************
-
- Synopsis [Computes the AND of two BDD with different orders.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute )
-{
- DdNode * bF0, * bF1, * bG0, * bG1, * bRes0, * bRes1, * bRes, * bVar;
- int LevF, LevG, Lev;
-
- // if F == 0, return 0
- if ( bF == Cudd_Not(ddF->one) )
- return Cudd_Not(ddF->one);
- // if G == 0, return 0
- if ( bG == Cudd_Not(ddG->one) )
- return Cudd_Not(ddF->one);
- // if G == 1, return F
- if ( bG == ddG->one )
- return bF;
- // cannot use F == 1, because the var order of G has to be changed
-
- // check cache
- if ( //(Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1) &&
- (bRes = cuddHashTableLookup2(table, bF, bG)) )
- return bRes;
- Counter++;
-
- if ( ddF->TimeStop && Abc_Clock() > ddF->TimeStop )
- return NULL;
- if ( ddG->TimeStop && Abc_Clock() > ddG->TimeStop )
- return NULL;
-
- // find the topmost variable in F and G using var order of F
- LevF = cuddI( ddF, Cudd_Regular(bF)->index );
- LevG = cuddI( ddF, pPermute ? pPermute[Cudd_Regular(bG)->index] : Cudd_Regular(bG)->index );
- Lev = Abc_MinInt( LevF, LevG );
- assert( Lev < ddF->size );
- bVar = ddF->vars[ddF->invperm[Lev]];
-
- // cofactor
- bF0 = (Lev < LevF) ? bF : Cudd_NotCond( cuddE(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
- bF1 = (Lev < LevF) ? bF : Cudd_NotCond( cuddT(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
- bG0 = (Lev < LevG) ? bG : Cudd_NotCond( cuddE(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
- bG1 = (Lev < LevG) ? bG : Cudd_NotCond( cuddT(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
-
- // call for cofactors
- bRes0 = extraBddAndPermute( table, ddF, bF0, ddG, bG0, pPermute );
- if ( bRes0 == NULL )
- return NULL;
- cuddRef( bRes0 );
- // call for cofactors
- bRes1 = extraBddAndPermute( table, ddF, bF1, ddG, bG1, pPermute );
- if ( bRes1 == NULL )
- {
- Cudd_IterDerefBdd( ddF, bRes0 );
- return NULL;
- }
- cuddRef( bRes1 );
-
- // compose the result
- bRes = cuddBddIteRecur( ddF, bVar, bRes1, bRes0 );
- if ( bRes == NULL )
- {
- Cudd_IterDerefBdd( ddF, bRes0 );
- Cudd_IterDerefBdd( ddF, bRes1 );
- return NULL;
- }
- cuddRef( bRes );
- Cudd_IterDerefBdd( ddF, bRes0 );
- Cudd_IterDerefBdd( ddF, bRes1 );
-
- // cache the result
-// if ( Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1 )
- {
- ptrint fanout = (ptrint)Cudd_Regular(bF)->ref * Cudd_Regular(bG)->ref;
- cuddSatDec(fanout);
- cuddHashTableInsert2( table, bF, bG, bRes, fanout );
- }
- cuddDeref( bRes );
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Testbench.]
-
- Description [This procedure takes BDD manager ddF and two BDDs
- in this manager (bF and bG). It creates a new manager ddG,
- transfers bG into it and then reorders it, resulting in bG2.
- Then it tries to compute the product of bF and bG2 in ddF.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_TestAndPerm( DdManager * ddF, DdNode * bF, DdNode * bG )
-{
- DdManager * ddG;
- DdNode * bG2, * bRes1, * bRes2;
- abctime clk;
- // disable variable ordering in ddF
- Cudd_AutodynDisable( ddF );
-
- // create new BDD manager
- ddG = Cudd_Init( ddF->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
- // transfer BDD into it
- Cudd_ShuffleHeap( ddG, ddF->invperm );
- bG2 = Extra_TransferLevelByLevel( ddF, ddG, bG ); Cudd_Ref( bG2 );
- // reorder the new manager
- Cudd_ReduceHeap( ddG, CUDD_REORDER_SYMM_SIFT, 1 );
-
- // compute the result
-clk = Abc_Clock();
- bRes1 = Cudd_bddAnd( ddF, bF, bG ); Cudd_Ref( bRes1 );
-Abc_PrintTime( 1, "Runtime of Cudd_bddAnd ", Abc_Clock() - clk );
-
- // compute the result
-Counter = 0;
-clk = Abc_Clock();
- bRes2 = Extra_bddAndPermute( ddF, bF, ddG, bG2, NULL ); Cudd_Ref( bRes2 );
-Abc_PrintTime( 1, "Runtime of new procedure", Abc_Clock() - clk );
-printf( "Recursive calls = %d\n", Counter );
-printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d ",
- Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes2),
- Cudd_DagSize(bF) * Cudd_DagSize(bG) );
-
- if ( bRes1 == bRes2 )
- printf( "Result verified.\n\n" );
- else
- printf( "Result is incorrect.\n\n" );
-
- Cudd_RecursiveDeref( ddF, bRes1 );
- Cudd_RecursiveDeref( ddF, bRes2 );
- // quit the new manager
- Cudd_RecursiveDeref( ddG, bG2 );
- Extra_StopManager( ddG );
-
- // re-enable variable ordering in ddF
- Cudd_AutodynEnable( ddF, CUDD_REORDER_SYMM_SIFT );
-}
-
-/**Function*************************************************************
-
- Synopsis [Writes ZDD into a PLA file.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName )
-{
- DdGen *gen;
- char * pCube;
- int * pPath, i;
- FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\" for writing.\n", pFileName );
- return;
- }
- fprintf( pFile, "# PLA file dumped by Extra_zddDumpPla() in ABC\n" );
- fprintf( pFile, ".i %d\n", nVars );
- fprintf( pFile, ".o 1\n" );
- pCube = ABC_CALLOC( char, dd->sizeZ );
- Cudd_zddForeachPath( dd, F, gen, pPath )
- {
- for ( i = 0; i < nVars; i++ )
- pCube[i] = '-';
- for ( i = 0; i < nVars; i++ )
- if ( pPath[2*i] == 1 || pPath[2*i+1] == 1 )
- pCube[i] = '0' + (pPath[2*i] == 1);
- fprintf( pFile, "%s 1\n", pCube );
- }
- fprintf( pFile, ".e\n\n" );
- fclose( pFile );
- ABC_FREE( pCube );
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddSymm.c b/src/misc/extra/extraBddSymm.c
deleted file mode 100644
index 9dd2c8e5..00000000
--- a/src/misc/extra/extraBddSymm.c
+++ /dev/null
@@ -1,1474 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddSymm.c]
-
- PackageName [extra]
-
- Synopsis [Efficient methods to compute the information about
- symmetric variables using the algorithm presented in the paper:
- A. Mishchenko. Fast Computation of Symmetries in Boolean Functions.
- Transactions on CAD, Nov. 2003.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddSymm.c,v 1.0 2003/09/01 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-#define DD_GET_SYMM_VARS_TAG 0x0a /* former DD_BDD_XOR_EXIST_ABSTRACT_TAG */
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticEnd***************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical symmetry information for the function.]
-
- Description [Returns the symmetry information in the form of Extra_SymmInfo_t structure.]
-
- SideEffects [If the ZDD variables are not derived from BDD variables with
- multiplicity 2, this function may derive them in a wrong way.]
-
- SeeAlso []
-
-******************************************************************************/
-Extra_SymmInfo_t * Extra_SymmPairsCompute(
- DdManager * dd, /* the manager */
- DdNode * bFunc) /* the function whose symmetries are computed */
-{
- DdNode * bSupp;
- DdNode * zRes;
- Extra_SymmInfo_t * p;
-
- bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
- zRes = Extra_zddSymmPairsCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
-
- p = Extra_SymmPairsCreateFromZdd( dd, zRes, bSupp );
-
- Cudd_RecursiveDeref( dd, bSupp );
- Cudd_RecursiveDerefZdd( dd, zRes );
-
- return p;
-
-} /* end of Extra_SymmPairsCompute */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical symmetry information as a ZDD.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddSymmPairsCompute(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- DdNode * bVars)
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraZddSymmPairsCompute( dd, bF, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddSymmPairsCompute */
-
-/**Function********************************************************************
-
- Synopsis [Returns a singleton-set ZDD containing all variables that are symmetric with the given one.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddGetSymmetricVars(
- DdManager * dd, /* the DD manager */
- DdNode * bF, /* the first function - originally, the positive cofactor */
- DdNode * bG, /* the second fucntion - originally, the negative cofactor */
- DdNode * bVars) /* the set of variables, on which F and G depend */
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraZddGetSymmetricVars( dd, bF, bG, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddGetSymmetricVars */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a set of variables into a set of singleton subsets.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddGetSingletons(
- DdManager * dd, /* the DD manager */
- DdNode * bVars) /* the set of variables */
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraZddGetSingletons( dd, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddGetSingletons */
-
-/**Function********************************************************************
-
- Synopsis [Filters the set of variables using the support of the function.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_bddReduceVarSet(
- DdManager * dd, /* the DD manager */
- DdNode * bVars, /* the set of variables to be reduced */
- DdNode * bF) /* the function whose support is used for reduction */
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraBddReduceVarSet( dd, bVars, bF );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_bddReduceVarSet */
-
-
-/**Function********************************************************************
-
- Synopsis [Allocates symmetry information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_SymmInfo_t * Extra_SymmPairsAllocate( int nVars )
-{
- int i;
- Extra_SymmInfo_t * p;
-
- // allocate and clean the storage for symmetry info
- p = ABC_ALLOC( Extra_SymmInfo_t, 1 );
- memset( p, 0, sizeof(Extra_SymmInfo_t) );
- p->nVars = nVars;
- p->pVars = ABC_ALLOC( int, nVars );
- p->pSymms = ABC_ALLOC( char *, nVars );
- p->pSymms[0] = ABC_ALLOC( char , nVars * nVars );
- memset( p->pSymms[0], 0, nVars * nVars * sizeof(char) );
-
- for ( i = 1; i < nVars; i++ )
- p->pSymms[i] = p->pSymms[i-1] + nVars;
-
- return p;
-} /* end of Extra_SymmPairsAllocate */
-
-/**Function********************************************************************
-
- Synopsis [Deallocates symmetry information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_SymmPairsDissolve( Extra_SymmInfo_t * p )
-{
- ABC_FREE( p->pVars );
- ABC_FREE( p->pSymms[0] );
- ABC_FREE( p->pSymms );
- ABC_FREE( p );
-} /* end of Extra_SymmPairsDissolve */
-
-/**Function********************************************************************
-
- Synopsis [Allocates symmetry information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_SymmPairsPrint( Extra_SymmInfo_t * p )
-{
- int i, k;
- printf( "\n" );
- for ( i = 0; i < p->nVars; i++ )
- {
- for ( k = 0; k <= i; k++ )
- printf( " " );
- for ( k = i+1; k < p->nVars; k++ )
- if ( p->pSymms[i][k] )
- printf( "1" );
- else
- printf( "." );
- printf( "\n" );
- }
-} /* end of Extra_SymmPairsPrint */
-
-
-/**Function********************************************************************
-
- Synopsis [Creates the symmetry information structure from ZDD.]
-
- Description [ZDD representation of symmetries is the set of cubes, each
- of which has two variables in the positive polarity. These variables correspond
- to the symmetric variable pair.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp )
-{
- int i;
- int nSuppSize;
- Extra_SymmInfo_t * p;
- int * pMapVars2Nums;
- DdNode * bTemp;
- DdNode * zSet, * zCube, * zTemp;
- int iVar1, iVar2;
-
- nSuppSize = Extra_bddSuppSize( dd, bSupp );
-
- // allocate and clean the storage for symmetry info
- p = Extra_SymmPairsAllocate( nSuppSize );
-
- // allocate the storage for the temporary map
- pMapVars2Nums = ABC_ALLOC( int, dd->size );
- memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
-
- // assign the variables
- p->nVarsMax = dd->size;
-// p->nNodes = Cudd_DagSize( zPairs );
- p->nNodes = 0;
- for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
- {
- p->pVars[i] = bTemp->index;
- pMapVars2Nums[bTemp->index] = i;
- }
-
- // write the symmetry info into the structure
- zSet = zPairs; Cudd_Ref( zSet );
- while ( zSet != z0 )
- {
- // get the next cube
- zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
-
- // add these two variables to the data structure
- assert( cuddT( cuddT(zCube) ) == z1 );
- iVar1 = zCube->index/2;
- iVar2 = cuddT(zCube)->index/2;
- if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] )
- p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1;
- else
- p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1;
- // count the symmetric pairs
- p->nSymms ++;
-
- // update the cuver and deref the cube
- zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zCube );
-
- } // for each cube
- Cudd_RecursiveDerefZdd( dd, zSet );
-
- ABC_FREE( pMapVars2Nums );
- return p;
-
-} /* end of Extra_SymmPairsCreateFromZdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Checks the possibility of two variables being symmetric.]
-
- Description [Returns 0 if vars are not symmetric. Return 1 if vars can be symmetric.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddCheckVarsSymmetric(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- int iVar1,
- int iVar2)
-{
- DdNode * bVars;
- int Res;
-
-// return 1;
-
- assert( iVar1 != iVar2 );
- assert( iVar1 < dd->size );
- assert( iVar2 < dd->size );
-
- bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] ); Cudd_Ref( bVars );
-
- Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 );
-
- Cudd_RecursiveDeref( dd, bVars );
-
- return Res;
-} /* end of Extra_bddCheckVarsSymmetric */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical symmetry information for the function.]
-
- Description [Uses the naive way of comparing cofactors.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_SymmInfo_t * Extra_SymmPairsComputeNaive( DdManager * dd, DdNode * bFunc )
-{
- DdNode * bSupp, * bTemp;
- int nSuppSize;
- Extra_SymmInfo_t * p;
- int i, k;
-
- // compute the support
- bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
- nSuppSize = Extra_bddSuppSize( dd, bSupp );
-//printf( "Support = %d. ", nSuppSize );
-//Extra_bddPrint( dd, bSupp );
-//printf( "%d ", nSuppSize );
-
- // allocate the storage for symmetry info
- p = Extra_SymmPairsAllocate( nSuppSize );
-
- // assign the variables
- p->nVarsMax = dd->size;
- for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
- p->pVars[i] = bTemp->index;
-
- // go through the candidate pairs and check using Idea1
- for ( i = 0; i < nSuppSize; i++ )
- for ( k = i+1; k < nSuppSize; k++ )
- {
- p->pSymms[k][i] = p->pSymms[i][k] = Extra_bddCheckVarsSymmetricNaive( dd, bFunc, p->pVars[i], p->pVars[k] );
- if ( p->pSymms[i][k] )
- p->nSymms++;
- }
-
- Cudd_RecursiveDeref( dd, bSupp );
- return p;
-
-} /* end of Extra_SymmPairsComputeNaive */
-
-/**Function********************************************************************
-
- Synopsis [Checks if the two variables are symmetric.]
-
- Description [Returns 0 if vars are not symmetric. Return 1 if vars are symmetric.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddCheckVarsSymmetricNaive(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- int iVar1,
- int iVar2)
-{
- DdNode * bCube1, * bCube2;
- DdNode * bCof01, * bCof10;
- int Res;
-
- assert( iVar1 != iVar2 );
- assert( iVar1 < dd->size );
- assert( iVar2 < dd->size );
-
- bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] ); Cudd_Ref( bCube1 );
- bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] ); Cudd_Ref( bCube2 );
-
- bCof01 = Cudd_Cofactor( dd, bF, bCube1 ); Cudd_Ref( bCof01 );
- bCof10 = Cudd_Cofactor( dd, bF, bCube2 ); Cudd_Ref( bCof10 );
-
- Res = (int)( bCof10 == bCof01 );
-
- Cudd_RecursiveDeref( dd, bCof01 );
- Cudd_RecursiveDeref( dd, bCof10 );
- Cudd_RecursiveDeref( dd, bCube1 );
- Cudd_RecursiveDeref( dd, bCube2 );
-
- return Res;
-} /* end of Extra_bddCheckVarsSymmetricNaive */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds ZDD representing the set of fixed-size variable tuples.]
-
- Description [Creates ZDD of all combinations of variables in Support that
- is represented by a BDD.]
-
- SideEffects [New ZDD variables are created if indices of the variables
- present in the combination are larger than the currently
- allocated number of ZDD variables.]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode* Extra_zddTuplesFromBdd(
- DdManager * dd, /* the DD manager */
- int K, /* the number of variables in tuples */
- DdNode * bVarsN) /* the set of all variables represented as a BDD */
-{
- DdNode *zRes;
- int autoDynZ;
-
- autoDynZ = dd->autoDynZ;
- dd->autoDynZ = 0;
-
- do {
- /* transform the numeric arguments (K) into a DdNode* argument;
- * this allows us to use the standard internal CUDD cache */
- DdNode *bVarSet = bVarsN, *bVarsK = bVarsN;
- int nVars = 0, i;
-
- /* determine the number of variables in VarSet */
- while ( bVarSet != b1 )
- {
- nVars++;
- /* make sure that the VarSet is a cube */
- if ( cuddE( bVarSet ) != b0 )
- return NULL;
- bVarSet = cuddT( bVarSet );
- }
- /* make sure that the number of variables in VarSet is less or equal
- that the number of variables that should be present in the tuples
- */
- if ( K > nVars )
- return NULL;
-
- /* the second argument in the recursive call stannds for <n>;
- * reate the first argument, which stands for <k>
- * as when we are talking about the tuple of <k> out of <n> */
- for ( i = 0; i < nVars-K; i++ )
- bVarsK = cuddT( bVarsK );
-
- dd->reordered = 0;
- zRes = extraZddTuplesFromBdd(dd, bVarsK, bVarsN );
-
- } while (dd->reordered == 1);
- dd->autoDynZ = autoDynZ;
- return zRes;
-
-} /* end of Extra_zddTuplesFromBdd */
-
-/**Function********************************************************************
-
- Synopsis [Selects one subset from the set of subsets represented by a ZDD.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode* Extra_zddSelectOneSubset(
- DdManager * dd, /* the DD manager */
- DdNode * zS) /* the ZDD */
-{
- DdNode *res;
- do {
- dd->reordered = 0;
- res = extraZddSelectOneSubset(dd, zS);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddSelectOneSubset */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_SymmPairsCompute.]
-
- Description [Returns the set of symmetric variable pairs represented as a set
- of two-literal ZDD cubes. Both variables always appear in the positive polarity
- in the cubes. This function works without building new BDD nodes. Some relatively
- small number of ZDD nodes may be built to ensure proper bookkeeping of the
- symmetry information.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-extraZddSymmPairsCompute(
- DdManager * dd, /* the manager */
- DdNode * bFunc, /* the function whose symmetries are computed */
- DdNode * bVars ) /* the set of variables on which this function depends */
-{
- DdNode * zRes;
- DdNode * bFR = Cudd_Regular(bFunc);
-
- if ( cuddIsConstant(bFR) )
- {
- int nVars, i;
-
- // determine how many vars are in the bVars
- nVars = Extra_bddSuppSize( dd, bVars );
- if ( nVars < 2 )
- return z0;
- else
- {
- DdNode * bVarsK;
-
- // create the BDD bVarsK corresponding to K = 2;
- bVarsK = bVars;
- for ( i = 0; i < nVars-2; i++ )
- bVarsK = cuddT( bVarsK );
- return extraZddTuplesFromBdd( dd, bVarsK, bVars );
- }
- }
- assert( bVars != b1 );
-
- if ( (zRes = cuddCacheLookup2Zdd(dd, extraZddSymmPairsCompute, bFunc, bVars)) )
- return zRes;
- else
- {
- DdNode * zRes0, * zRes1;
- DdNode * zTemp, * zPlus, * zSymmVars;
- DdNode * bF0, * bF1;
- DdNode * bVarsNew;
- int nVarsExtra;
- int LevelF;
-
- // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
- // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
- // count how many extra vars are there in bVars
- nVarsExtra = 0;
- LevelF = dd->perm[bFR->index];
- for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
- nVarsExtra++;
- // the indexes (level) of variables should be synchronized now
- assert( bFR->index == bVarsNew->index );
-
- // cofactor the function
- if ( bFR != bFunc ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- // solve subproblems
- zRes0 = extraZddSymmPairsCompute( dd, bF0, cuddT(bVarsNew) );
- if ( zRes0 == NULL )
- return NULL;
- cuddRef( zRes0 );
-
- // if there is no symmetries in the negative cofactor
- // there is no need to test the positive cofactor
- if ( zRes0 == z0 )
- zRes = zRes0; // zRes takes reference
- else
- {
- zRes1 = extraZddSymmPairsCompute( dd, bF1, cuddT(bVarsNew) );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- return NULL;
- }
- cuddRef( zRes1 );
-
- // only those variables are pair-wise symmetric
- // that are pair-wise symmetric in both cofactors
- // therefore, intersect the solutions
- zRes = cuddZddIntersect( dd, zRes0, zRes1 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- }
-
- // consider the current top-most variable and find all the vars
- // that are pairwise symmetric with it
- // these variables are returned as a set of ZDD singletons
- zSymmVars = extraZddGetSymmetricVars( dd, bF1, bF0, cuddT(bVarsNew) );
- if ( zSymmVars == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zSymmVars );
-
- // attach the topmost variable to the set, to get the variable pairs
- // use the positive polarity ZDD variable for the purpose
-
- // there is no need to do so, if zSymmVars is empty
- if ( zSymmVars == z0 )
- Cudd_RecursiveDerefZdd( dd, zSymmVars );
- else
- {
- zPlus = cuddZddGetNode( dd, 2*bFR->index, zSymmVars, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- Cudd_RecursiveDerefZdd( dd, zSymmVars );
- return NULL;
- }
- cuddRef( zPlus );
- cuddDeref( zSymmVars );
-
- // add these variable pairs to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
-
- // only zRes is referenced at this point
-
- // if we skipped some variables, these variables cannot be symmetric with
- // any variables that are currently in the support of bF, but they can be
- // symmetric with the variables that are in bVars but not in the support of bF
- if ( nVarsExtra )
- {
- // it is possible to improve this step:
- // (1) there is no need to enter here, if nVarsExtra < 2
-
- // create the set of topmost nVarsExtra in bVars
- DdNode * bVarsExtra;
- int nVars;
-
- // remove from bVars all the variable that are in the support of bFunc
- bVarsExtra = extraBddReduceVarSet( dd, bVars, bFunc );
- if ( bVarsExtra == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( bVarsExtra );
-
- // determine how many vars are in the bVarsExtra
- nVars = Extra_bddSuppSize( dd, bVarsExtra );
- if ( nVars < 2 )
- {
- Cudd_RecursiveDeref( dd, bVarsExtra );
- }
- else
- {
- int i;
- DdNode * bVarsK;
-
- // create the BDD bVarsK corresponding to K = 2;
- bVarsK = bVarsExtra;
- for ( i = 0; i < nVars-2; i++ )
- bVarsK = cuddT( bVarsK );
-
- // create the 2 variable tuples
- zPlus = extraZddTuplesFromBdd( dd, bVarsK, bVarsExtra );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDeref( dd, bVarsExtra );
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
- Cudd_RecursiveDeref( dd, bVarsExtra );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
- }
- cuddDeref( zRes );
-
-
- /* insert the result into cache */
- cuddCacheInsert2(dd, extraZddSymmPairsCompute, bFunc, bVars, zRes);
- return zRes;
- }
-} /* end of extraZddSymmPairsCompute */
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_zddGetSymmetricVars.]
-
- Description [Returns the set of ZDD singletons, containing those positive
- ZDD variables that correspond to BDD variables x, for which it is true
- that bF(x=0) == bG(x=1).]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraZddGetSymmetricVars(
- DdManager * dd, /* the DD manager */
- DdNode * bF, /* the first function - originally, the positive cofactor */
- DdNode * bG, /* the second function - originally, the negative cofactor */
- DdNode * bVars) /* the set of variables, on which F and G depend */
-{
- DdNode * zRes;
- DdNode * bFR = Cudd_Regular(bF);
- DdNode * bGR = Cudd_Regular(bG);
-
- if ( cuddIsConstant(bFR) && cuddIsConstant(bGR) )
- {
- if ( bF == bG )
- return extraZddGetSingletons( dd, bVars );
- else
- return z0;
- }
- assert( bVars != b1 );
-
- if ( (zRes = cuddCacheLookupZdd(dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars)) )
- return zRes;
- else
- {
- DdNode * zRes0, * zRes1;
- DdNode * zPlus, * zTemp;
- DdNode * bF0, * bF1;
- DdNode * bG0, * bG1;
- DdNode * bVarsNew;
-
- int LevelF = cuddI(dd,bFR->index);
- int LevelG = cuddI(dd,bGR->index);
- int LevelFG;
-
- if ( LevelF < LevelG )
- LevelFG = LevelF;
- else
- LevelFG = LevelG;
-
- // at least one of the arguments is not a constant
- assert( LevelFG < dd->size );
-
- // every variable in bF and bG should be also in bVars, therefore LevelFG cannot be above LevelV
- // if LevelFG is below LevelV, scroll through the vars in bVars to the same level as LevelFG
- for ( bVarsNew = bVars; LevelFG > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) );
- assert( LevelFG == dd->perm[bVarsNew->index] );
-
- // cofactor the functions
- if ( LevelF == LevelFG )
- {
- if ( bFR != bF ) // bF is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
- }
- else
- bF0 = bF1 = bF;
-
- if ( LevelG == LevelFG )
- {
- if ( bGR != bG ) // bG is complemented
- {
- bG0 = Cudd_Not( cuddE(bGR) );
- bG1 = Cudd_Not( cuddT(bGR) );
- }
- else
- {
- bG0 = cuddE(bGR);
- bG1 = cuddT(bGR);
- }
- }
- else
- bG0 = bG1 = bG;
-
- // solve subproblems
- zRes0 = extraZddGetSymmetricVars( dd, bF0, bG0, cuddT(bVarsNew) );
- if ( zRes0 == NULL )
- return NULL;
- cuddRef( zRes0 );
-
- // if there is not symmetries in the negative cofactor
- // there is no need to test the positive cofactor
- if ( zRes0 == z0 )
- zRes = zRes0; // zRes takes reference
- else
- {
- zRes1 = extraZddGetSymmetricVars( dd, bF1, bG1, cuddT(bVarsNew) );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- return NULL;
- }
- cuddRef( zRes1 );
-
- // only those variables should belong to the resulting set
- // for which the property is true for both cofactors
- zRes = cuddZddIntersect( dd, zRes0, zRes1 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- }
-
- // add one more singleton if the property is true for this variable
- if ( bF0 == bG1 )
- {
- zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these variable pairs to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
-
- if ( bF == bG && bVars != bVarsNew )
- {
- // if the functions are equal, so are their cofactors
- // add those variables from V that are above F and G
-
- DdNode * bVarsExtra;
-
- assert( LevelFG > dd->perm[bVars->index] );
-
- // create the BDD of the extra variables
- bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsNew );
- if ( bVarsExtra == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( bVarsExtra );
-
- zPlus = extraZddGetSingletons( dd, bVarsExtra );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDeref( dd, bVarsExtra );
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
- Cudd_RecursiveDeref( dd, bVarsExtra );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
- cuddDeref( zRes );
-
- cuddCacheInsert( dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars, zRes );
- return zRes;
- }
-} /* end of extraZddGetSymmetricVars */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_zddGetSingletons.]
-
- Description [Returns the set of ZDD singletons, containing those positive
- polarity ZDD variables that correspond to the BDD variables in bVars.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraZddGetSingletons(
- DdManager * dd, /* the DD manager */
- DdNode * bVars) /* the set of variables */
-{
- DdNode * zRes;
-
- if ( bVars == b1 )
-// if ( bVars == b0 ) // bug fixed by Jin Zhang, Jan 23, 2004
- return z1;
-
- if ( (zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletons, bVars)) )
- return zRes;
- else
- {
- DdNode * zTemp, * zPlus;
-
- // solve subproblem
- zRes = extraZddGetSingletons( dd, cuddT(bVars) );
- if ( zRes == NULL )
- return NULL;
- cuddRef( zRes );
-
- zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- cuddDeref( zRes );
-
- cuddCacheInsert1( dd, extraZddGetSingletons, bVars, zRes );
- return zRes;
- }
-} /* end of extraZddGetSingletons */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_bddReduceVarSet.]
-
- Description [Returns the set of all variables in the given set that are not in the
- support of the given function.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraBddReduceVarSet(
- DdManager * dd, /* the DD manager */
- DdNode * bVars, /* the set of variables to be reduced */
- DdNode * bF) /* the function whose support is used for reduction */
-{
- DdNode * bRes;
- DdNode * bFR = Cudd_Regular(bF);
-
- if ( cuddIsConstant(bFR) || bVars == b1 )
- return bVars;
-
- if ( (bRes = cuddCacheLookup2(dd, extraBddReduceVarSet, bVars, bF)) )
- return bRes;
- else
- {
- DdNode * bF0, * bF1;
- DdNode * bVarsThis, * bVarsLower, * bTemp;
- int LevelF;
-
- // if LevelF is below LevelV, scroll through the vars in bVars
- LevelF = dd->perm[bFR->index];
- for ( bVarsThis = bVars; LevelF > cuddI(dd,bVarsThis->index); bVarsThis = cuddT(bVarsThis) );
- // scroll also through the current var, because it should be not be added
- if ( LevelF == cuddI(dd,bVarsThis->index) )
- bVarsLower = cuddT(bVarsThis);
- else
- bVarsLower = bVarsThis;
-
- // cofactor the function
- if ( bFR != bF ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- // solve subproblems
- bRes = extraBddReduceVarSet( dd, bVarsLower, bF0 );
- if ( bRes == NULL )
- return NULL;
- cuddRef( bRes );
-
- bRes = extraBddReduceVarSet( dd, bTemp = bRes, bF1 );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp );
- return NULL;
- }
- cuddRef( bRes );
- Cudd_RecursiveDeref( dd, bTemp );
-
- // the current var should not be added
- // add the skipped vars
- if ( bVarsThis != bVars )
- {
- DdNode * bVarsExtra;
-
- // extract the skipped variables
- bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsThis );
- if ( bVarsExtra == NULL )
- {
- Cudd_RecursiveDeref( dd, bRes );
- return NULL;
- }
- cuddRef( bVarsExtra );
-
- // add these variables
- bRes = cuddBddAndRecur( dd, bTemp = bRes, bVarsExtra );
- if ( bRes == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bVarsExtra );
- return NULL;
- }
- cuddRef( bRes );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bVarsExtra );
- }
- cuddDeref( bRes );
-
- cuddCacheInsert2( dd, extraBddReduceVarSet, bVars, bF, bRes );
- return bRes;
- }
-} /* end of extraBddReduceVarSet */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Extra_bddCheckVarsSymmetric().]
-
- Description [Returns b0 if the variables are not symmetric. Returns b1 if the
- variables can be symmetric. The variables are represented in the form of a
- two-variable cube. In case the cube contains one variable (below Var1 level),
- the cube's pointer is complemented if the variable Var1 occurred on the
- current path; otherwise, the cube's pointer is regular. Uses additional
- complemented bit (Hash_Not) to mark the result if in the BDD rooted that this
- node there is a branch passing though the node labeled with Var2.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraBddCheckVarsSymmetric(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- DdNode * bVars)
-{
- DdNode * bRes;
-
- if ( bF == b0 )
- return b1;
-
- assert( bVars != b1 );
-
- if ( (bRes = cuddCacheLookup2(dd, extraBddCheckVarsSymmetric, bF, bVars)) )
- return bRes;
- else
- {
- DdNode * bRes0, * bRes1;
- DdNode * bF0, * bF1;
- DdNode * bFR = Cudd_Regular(bF);
- int LevelF = cuddI(dd,bFR->index);
-
- DdNode * bVarsR = Cudd_Regular(bVars);
- int fVar1Pres;
- int iLev1;
- int iLev2;
-
- if ( bVarsR != bVars ) // cube's pointer is complemented
- {
- assert( cuddT(bVarsR) == b1 );
- fVar1Pres = 1; // the first var is present on the path
- iLev1 = -1; // we are already below the first var level
- iLev2 = dd->perm[bVarsR->index]; // the level of the second var
- }
- else // cube's pointer is NOT complemented
- {
- fVar1Pres = 0; // the first var is absent on the path
- if ( cuddT(bVars) == b1 )
- {
- iLev1 = -1; // we are already below the first var level
- iLev2 = dd->perm[bVars->index]; // the level of the second var
- }
- else
- {
- assert( cuddT(cuddT(bVars)) == b1 );
- iLev1 = dd->perm[bVars->index]; // the level of the first var
- iLev2 = dd->perm[cuddT(bVars)->index]; // the level of the second var
- }
- }
-
- // cofactor the function
- // the cofactors are needed only if we are above the second level
- if ( LevelF < iLev2 )
- {
- if ( bFR != bF ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
- }
- else
- bF0 = bF1 = NULL;
-
- // consider five cases:
- // (1) F is above iLev1
- // (2) F is on the level iLev1
- // (3) F is between iLev1 and iLev2
- // (4) F is on the level iLev2
- // (5) F is below iLev2
-
- // (1) F is above iLev1
- if ( LevelF < iLev1 )
- {
- // the returned result cannot have the hash attribute
- // because we still did not reach the level of Var1;
- // the attribute never travels above the level of Var1
- bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
-// assert( !Hash_IsComplement( bRes0 ) );
- assert( bRes0 != z0 );
- if ( bRes0 == b0 )
- bRes = b0;
- else
- bRes = extraBddCheckVarsSymmetric( dd, bF1, bVars );
-// assert( !Hash_IsComplement( bRes ) );
- assert( bRes != z0 );
- }
- // (2) F is on the level iLev1
- else if ( LevelF == iLev1 )
- {
- bRes0 = extraBddCheckVarsSymmetric( dd, bF0, Cudd_Not( cuddT(bVars) ) );
- if ( bRes0 == b0 )
- bRes = b0;
- else
- {
- bRes1 = extraBddCheckVarsSymmetric( dd, bF1, Cudd_Not( cuddT(bVars) ) );
- if ( bRes1 == b0 )
- bRes = b0;
- else
- {
-// if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
- if ( bRes0 == z0 || bRes1 == z0 )
- bRes = b1;
- else
- bRes = b0;
- }
- }
- }
- // (3) F is between iLev1 and iLev2
- else if ( LevelF < iLev2 )
- {
- bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
- if ( bRes0 == b0 )
- bRes = b0;
- else
- {
- bRes1 = extraBddCheckVarsSymmetric( dd, bF1, bVars );
- if ( bRes1 == b0 )
- bRes = b0;
- else
- {
-// if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
-// bRes = Hash_Not( b1 );
- if ( bRes0 == z0 || bRes1 == z0 )
- bRes = z0;
- else
- bRes = b1;
- }
- }
- }
- // (4) F is on the level iLev2
- else if ( LevelF == iLev2 )
- {
- // this is the only place where the hash attribute (Hash_Not) can be added
- // to the result; it can be added only if the path came through the node
- // lebeled with Var1; therefore, the hash attribute cannot be returned
- // to the caller function
- if ( fVar1Pres )
-// bRes = Hash_Not( b1 );
- bRes = z0;
- else
- bRes = b0;
- }
- // (5) F is below iLev2
- else // if ( LevelF > iLev2 )
- {
- // it is possible that the path goes through the node labeled by Var1
- // and still everything is okay; we do not label with Hash_Not here
- // because the path does not go through node labeled by Var2
- bRes = b1;
- }
-
- cuddCacheInsert2(dd, extraBddCheckVarsSymmetric, bF, bVars, bRes);
- return bRes;
- }
-} /* end of extraBddCheckVarsSymmetric */
-
-/**Function********************************************************************
-
- Synopsis [Performs the reordering-sensitive step of Extra_zddTupleFromBdd().]
-
- Description [Generates in a bottom-up fashion ZDD for all combinations
- composed of k variables out of variables belonging to Support.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode* extraZddTuplesFromBdd(
- DdManager * dd, /* the DD manager */
- DdNode * bVarsK, /* the number of variables in tuples */
- DdNode * bVarsN) /* the set of all variables */
-{
- DdNode *zRes, *zRes0, *zRes1;
- statLine(dd);
-
- /* terminal cases */
-/* if ( k < 0 || k > n )
- * return dd->zero;
- * if ( n == 0 )
- * return dd->one;
- */
- if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
- return z0;
- if ( bVarsN == b1 )
- return z1;
-
- /* check cache */
- zRes = cuddCacheLookup2Zdd(dd, extraZddTuplesFromBdd, bVarsK, bVarsN);
- if (zRes)
- return(zRes);
-
- /* ZDD in which this variable is 0 */
-/* zRes0 = extraZddTuplesFromBdd( dd, k, n-1 ); */
- zRes0 = extraZddTuplesFromBdd( dd, bVarsK, cuddT(bVarsN) );
- if ( zRes0 == NULL )
- return NULL;
- cuddRef( zRes0 );
-
- /* ZDD in which this variable is 1 */
-/* zRes1 = extraZddTuplesFromBdd( dd, k-1, n-1 ); */
- if ( bVarsK == b1 )
- {
- zRes1 = z0;
- cuddRef( zRes1 );
- }
- else
- {
- zRes1 = extraZddTuplesFromBdd( dd, cuddT(bVarsK), cuddT(bVarsN) );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- return NULL;
- }
- cuddRef( zRes1 );
- }
-
- /* compose Res0 and Res1 with the given ZDD variable */
- zRes = cuddZddGetNode( dd, 2*bVarsN->index, zRes1, zRes0 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- return NULL;
- }
- cuddDeref( zRes0 );
- cuddDeref( zRes1 );
-
- /* insert the result into cache */
- cuddCacheInsert2(dd, extraZddTuplesFromBdd, bVarsK, bVarsN, zRes);
- return zRes;
-
-} /* end of extraZddTuplesFromBdd */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Extra_zddSelectOneSubset.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraZddSelectOneSubset(
- DdManager * dd,
- DdNode * zS )
-// selects one subset from the ZDD zS
-// returns z0 if and only if zS is an empty set of cubes
-{
- DdNode * zRes;
-
- if ( zS == z0 ) return z0;
- if ( zS == z1 ) return z1;
-
- // check cache
- if ( (zRes = cuddCacheLookup1Zdd( dd, extraZddSelectOneSubset, zS )) )
- return zRes;
- else
- {
- DdNode * zS0, * zS1, * zTemp;
-
- zS0 = cuddE(zS);
- zS1 = cuddT(zS);
-
- if ( zS0 != z0 )
- {
- zRes = extraZddSelectOneSubset( dd, zS0 );
- if ( zRes == NULL )
- return NULL;
- }
- else // if ( zS0 == z0 )
- {
- assert( zS1 != z0 );
- zRes = extraZddSelectOneSubset( dd, zS1 );
- if ( zRes == NULL )
- return NULL;
- cuddRef( zRes );
-
- zRes = cuddZddGetNode( dd, zS->index, zTemp = zRes, z0 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- return NULL;
- }
- cuddDeref( zTemp );
- }
-
- // insert the result into cache
- cuddCacheInsert1( dd, extraZddSelectOneSubset, zS, zRes );
- return zRes;
- }
-} /* end of extraZddSelectOneSubset */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static Functions */
-/*---------------------------------------------------------------------------*/
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddTime.c b/src/misc/extra/extraBddTime.c
deleted file mode 100644
index dc9ff147..00000000
--- a/src/misc/extra/extraBddTime.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddTime.c]
-
- PackageName [extra]
-
- Synopsis [Procedures to control runtime in BDD operators.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddTime.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-#define CHECK_FACTOR 10
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static DdNode * cuddBddAndRecurTime( DdManager * manager, DdNode * f, DdNode * g, int * pRecCalls, int TimeOut );
-static DdNode * cuddBddAndAbstractRecurTime( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube, int * pRecCalls, int TimeOut );
-static DdNode * extraTransferPermuteTime( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute, int TimeOut );
-static DdNode * extraTransferPermuteRecurTime( DdManager * ddS, DdManager * ddD, DdNode * f, st__table * table, int * Permute, int TimeOut );
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/**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 *
-Extra_bddAndTime(
- DdManager * dd,
- DdNode * f,
- DdNode * g,
- int TimeOut)
-{
- DdNode *res;
- int Counter = 0;
-
- do {
- dd->reordered = 0;
- res = cuddBddAndRecurTime(dd,f,g, &Counter, TimeOut);
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_bddAndTime */
-
-/**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 *
-Extra_bddAndAbstractTime(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube,
- int TimeOut)
-{
- DdNode *res;
- int Counter = 0;
-
- do {
- manager->reordered = 0;
- res = cuddBddAndAbstractRecurTime(manager, f, g, cube, &Counter, TimeOut);
- } while (manager->reordered == 1);
- return(res);
-
-} /* end of Extra_bddAndAbstractTime */
-
-/**Function********************************************************************
-
- Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]
-
- Description [Convert a {A,B}DD from a manager to another one. The orders of the
- variables in the two managers may be different. Returns a
- pointer to the {A,B}DD in the destination manager if successful; NULL
- otherwise. The i-th entry in the array Permute tells what is the index
- of the i-th variable from the old manager in the new manager.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_TransferPermuteTime( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute, int TimeOut )
-{
- DdNode * bRes;
- do
- {
- ddDestination->reordered = 0;
- bRes = extraTransferPermuteTime( ddSource, ddDestination, f, Permute, TimeOut );
- }
- while ( ddDestination->reordered == 1 );
- return ( bRes );
-
-} /* end of Extra_TransferPermuteTime */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**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 *
-cuddBddAndRecurTime(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- int * pRecCalls,
- int TimeOut)
-{
- 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);
- }
-
-// if ( TimeOut && ((*pRecCalls)++ % CHECK_FACTOR) == 0 && TimeOut < Abc_Clock() )
- if ( TimeOut && Abc_Clock() > TimeOut )
- return NULL;
-
- /* 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 = cuddBddAndRecurTime(manager, fv, gv, pRecCalls, TimeOut);
- if (t == NULL) return(NULL);
- cuddRef(t);
-
- e = cuddBddAndRecurTime(manager, fnv, gnv, pRecCalls, TimeOut);
- 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 [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 *
-cuddBddAndAbstractRecurTime(
- DdManager * manager,
- DdNode * f,
- DdNode * g,
- DdNode * cube,
- int * pRecCalls,
- int TimeOut)
-{
- 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(cuddBddAndRecurTime(manager, f, g, pRecCalls, TimeOut));
- }
- 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(cuddBddAndRecurTime(manager, f, g, pRecCalls, TimeOut));
- }
- 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 ( TimeOut && ((*pRecCalls)++ % CHECK_FACTOR) == 0 && TimeOut < Abc_Clock() )
- if ( TimeOut && Abc_Clock() > TimeOut )
- return NULL;
-
- 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 = cuddBddAndAbstractRecurTime(manager, ft, gt, Cube, pRecCalls, TimeOut);
- 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 = cuddBddAndAbstractRecurTime(manager, fe, ge, Cube, pRecCalls, TimeOut);
- }
- if (e == NULL) {
- Cudd_IterDerefBdd(manager, t);
- return(NULL);
- }
- if (t == e) {
- r = t;
- cuddDeref(t);
- } else {
- cuddRef(e);
- r = cuddBddAndRecurTime(manager, Cudd_Not(t), Cudd_Not(e), pRecCalls, TimeOut);
- 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 = cuddBddAndAbstractRecurTime(manager, ft, gt, cube, pRecCalls, TimeOut);
- if (t == NULL) return(NULL);
- cuddRef(t);
- e = cuddBddAndAbstractRecurTime(manager, fe, ge, cube, pRecCalls, TimeOut);
- 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 */
-/*---------------------------------------------------------------------------*/
-
-/**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 [Extra_TransferPermute]
-
-******************************************************************************/
-DdNode * extraTransferPermuteTime( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute, int TimeOut )
-{
- 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 = extraTransferPermuteRecurTime( ddS, ddD, f, table, Permute, TimeOut );
- 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, ( const 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 extraTransferPermuteTime */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Extra_TransferPermute.]
-
- Description [Performs the recursive step of Extra_TransferPermute.
- Returns a pointer to the result if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [extraTransferPermuteTime]
-
-******************************************************************************/
-static DdNode *
-extraTransferPermuteRecurTime(
- DdManager * ddS,
- DdManager * ddD,
- DdNode * f,
- st__table * table,
- int * Permute,
- int TimeOut )
-{
- 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 ) );
-
- if ( TimeOut && Abc_Clock() > TimeOut )
- return NULL;
-
- /* Recursive step. */
- if ( Permute )
- index = Permute[f->index];
- else
- index = f->index;
-
- ft = cuddT( f );
- fe = cuddE( f );
-
- t = extraTransferPermuteRecurTime( ddS, ddD, ft, table, Permute, TimeOut );
- if ( t == NULL )
- {
- return ( NULL );
- }
- cuddRef( t );
-
- e = extraTransferPermuteRecurTime( ddS, ddD, fe, table, Permute, TimeOut );
- if ( e == NULL )
- {
- Cudd_RecursiveDeref( ddD, t );
- return ( NULL );
- }
- cuddRef( e );
-
- zero = Cudd_Not(ddD->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 extraTransferPermuteRecurTime */
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-ABC_NAMESPACE_IMPL_END
-
diff --git a/src/misc/extra/extraBddUnate.c b/src/misc/extra/extraBddUnate.c
deleted file mode 100644
index 9ebdd4e5..00000000
--- a/src/misc/extra/extraBddUnate.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/**CFile****************************************************************
-
- FileName [extraBddUnate.c]
-
- PackageName [extra]
-
- Synopsis [Efficient methods to compute the information about
- unate variables using an algorithm that is conceptually similar to
- the algorithm for two-variable symmetry computation presented in:
- A. Mishchenko. Fast Computation of Symmetries in Boolean Functions.
- Transactions on CAD, Nov. 2003.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 2.0. Started - September 1, 2003.]
-
- Revision [$Id: extraBddUnate.c,v 1.0 2003/09/01 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "extraBdd.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-/**AutomaticEnd***************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical symmetry information for the function.]
-
- Description [Returns the symmetry information in the form of Extra_UnateInfo_t structure.]
-
- SideEffects [If the ZDD variables are not derived from BDD variables with
- multiplicity 2, this function may derive them in a wrong way.]
-
- SeeAlso []
-
-******************************************************************************/
-Extra_UnateInfo_t * Extra_UnateComputeFast(
- DdManager * dd, /* the manager */
- DdNode * bFunc) /* the function whose symmetries are computed */
-{
- DdNode * bSupp;
- DdNode * zRes;
- Extra_UnateInfo_t * p;
-
- bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
- zRes = Extra_zddUnateInfoCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
-
- p = Extra_UnateInfoCreateFromZdd( dd, zRes, bSupp );
-
- Cudd_RecursiveDeref( dd, bSupp );
- Cudd_RecursiveDerefZdd( dd, zRes );
-
- return p;
-
-} /* end of Extra_UnateInfoCompute */
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical symmetry information as a ZDD.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddUnateInfoCompute(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- DdNode * bVars)
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraZddUnateInfoCompute( dd, bF, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddUnateInfoCompute */
-
-
-/**Function********************************************************************
-
- Synopsis [Converts a set of variables into a set of singleton subsets.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * Extra_zddGetSingletonsBoth(
- DdManager * dd, /* the DD manager */
- DdNode * bVars) /* the set of variables */
-{
- DdNode * res;
- do {
- dd->reordered = 0;
- res = extraZddGetSingletonsBoth( dd, bVars );
- } while (dd->reordered == 1);
- return(res);
-
-} /* end of Extra_zddGetSingletonsBoth */
-
-/**Function********************************************************************
-
- Synopsis [Allocates unateness information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_UnateInfo_t * Extra_UnateInfoAllocate( int nVars )
-{
- Extra_UnateInfo_t * p;
- // allocate and clean the storage for unateness info
- p = ABC_ALLOC( Extra_UnateInfo_t, 1 );
- memset( p, 0, sizeof(Extra_UnateInfo_t) );
- p->nVars = nVars;
- p->pVars = ABC_ALLOC( Extra_UnateVar_t, nVars );
- memset( p->pVars, 0, nVars * sizeof(Extra_UnateVar_t) );
- return p;
-} /* end of Extra_UnateInfoAllocate */
-
-/**Function********************************************************************
-
- Synopsis [Deallocates symmetry information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_UnateInfoDissolve( Extra_UnateInfo_t * p )
-{
- ABC_FREE( p->pVars );
- ABC_FREE( p );
-} /* end of Extra_UnateInfoDissolve */
-
-/**Function********************************************************************
-
- Synopsis [Allocates symmetry information structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-void Extra_UnateInfoPrint( Extra_UnateInfo_t * p )
-{
- char * pBuffer;
- int i;
- pBuffer = ABC_ALLOC( char, p->nVarsMax+1 );
- memset( pBuffer, ' ', p->nVarsMax );
- pBuffer[p->nVarsMax] = 0;
- for ( i = 0; i < p->nVars; i++ )
- if ( p->pVars[i].Neg )
- pBuffer[ p->pVars[i].iVar ] = 'n';
- else if ( p->pVars[i].Pos )
- pBuffer[ p->pVars[i].iVar ] = 'p';
- else
- pBuffer[ p->pVars[i].iVar ] = '.';
- printf( "%s\n", pBuffer );
- ABC_FREE( pBuffer );
-} /* end of Extra_UnateInfoPrint */
-
-
-/**Function********************************************************************
-
- Synopsis [Creates the symmetry information structure from ZDD.]
-
- Description [ZDD representation of symmetries is the set of cubes, each
- of which has two variables in the positive polarity. These variables correspond
- to the symmetric variable pair.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp )
-{
- Extra_UnateInfo_t * p;
- DdNode * bTemp, * zSet, * zCube, * zTemp;
- int * pMapVars2Nums;
- int i, nSuppSize;
-
- nSuppSize = Extra_bddSuppSize( dd, bSupp );
-
- // allocate and clean the storage for symmetry info
- p = Extra_UnateInfoAllocate( nSuppSize );
-
- // allocate the storage for the temporary map
- pMapVars2Nums = ABC_ALLOC( int, dd->size );
- memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
-
- // assign the variables
- p->nVarsMax = dd->size;
- for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
- {
- p->pVars[i].iVar = bTemp->index;
- pMapVars2Nums[bTemp->index] = i;
- }
-
- // write the symmetry info into the structure
- zSet = zPairs; Cudd_Ref( zSet );
-// Cudd_zddPrintCover( dd, zPairs ); printf( "\n" );
- while ( zSet != z0 )
- {
- // get the next cube
- zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
-
- // add this var to the data structure
- assert( cuddT(zCube) == z1 && cuddE(zCube) == z0 );
- if ( zCube->index & 1 ) // neg
- p->pVars[ pMapVars2Nums[zCube->index/2] ].Neg = 1;
- else
- p->pVars[ pMapVars2Nums[zCube->index/2] ].Pos = 1;
- // count the unate vars
- p->nUnate++;
-
- // update the cuver and deref the cube
- zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zCube );
-
- } // for each cube
- Cudd_RecursiveDerefZdd( dd, zSet );
- ABC_FREE( pMapVars2Nums );
- return p;
-
-} /* end of Extra_UnateInfoCreateFromZdd */
-
-
-
-/**Function********************************************************************
-
- Synopsis [Computes the classical unateness information for the function.]
-
- Description [Uses the naive way of comparing cofactors.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-Extra_UnateInfo_t * Extra_UnateComputeSlow( DdManager * dd, DdNode * bFunc )
-{
- int nSuppSize;
- DdNode * bSupp, * bTemp;
- Extra_UnateInfo_t * p;
- int i, Res;
-
- // compute the support
- bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
- nSuppSize = Extra_bddSuppSize( dd, bSupp );
-//printf( "Support = %d. ", nSuppSize );
-//Extra_bddPrint( dd, bSupp );
-//printf( "%d ", nSuppSize );
-
- // allocate the storage for symmetry info
- p = Extra_UnateInfoAllocate( nSuppSize );
-
- // assign the variables
- p->nVarsMax = dd->size;
- for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
- {
- Res = Extra_bddCheckUnateNaive( dd, bFunc, bTemp->index );
- p->pVars[i].iVar = bTemp->index;
- if ( Res == -1 )
- p->pVars[i].Neg = 1;
- else if ( Res == 1 )
- p->pVars[i].Pos = 1;
- p->nUnate += (Res != 0);
- }
- Cudd_RecursiveDeref( dd, bSupp );
- return p;
-
-} /* end of Extra_UnateComputeSlow */
-
-/**Function********************************************************************
-
- Synopsis [Checks if the two variables are symmetric.]
-
- Description [Returns 0 if vars are not unate. Return -1/+1 if the var is neg/pos unate.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-int Extra_bddCheckUnateNaive(
- DdManager * dd, /* the DD manager */
- DdNode * bF,
- int iVar)
-{
- DdNode * bCof0, * bCof1;
- int Res;
-
- assert( iVar < dd->size );
-
- bCof0 = Cudd_Cofactor( dd, bF, Cudd_Not(Cudd_bddIthVar(dd,iVar)) ); Cudd_Ref( bCof0 );
- bCof1 = Cudd_Cofactor( dd, bF, Cudd_bddIthVar(dd,iVar) ); Cudd_Ref( bCof1 );
-
- if ( Cudd_bddLeq( dd, bCof0, bCof1 ) )
- Res = 1;
- else if ( Cudd_bddLeq( dd, bCof1, bCof0 ) )
- Res =-1;
- else
- Res = 0;
-
- Cudd_RecursiveDeref( dd, bCof0 );
- Cudd_RecursiveDeref( dd, bCof1 );
- return Res;
-} /* end of Extra_bddCheckUnateNaive */
-
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_UnateInfoCompute.]
-
- Description [Returns the set of symmetric variable pairs represented as a set
- of two-literal ZDD cubes. Both variables always appear in the positive polarity
- in the cubes. This function works without building new BDD nodes. Some relatively
- small number of ZDD nodes may be built to ensure proper bookkeeping of the
- symmetry information.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode *
-extraZddUnateInfoCompute(
- DdManager * dd, /* the manager */
- DdNode * bFunc, /* the function whose symmetries are computed */
- DdNode * bVars ) /* the set of variables on which this function depends */
-{
- DdNode * zRes;
- DdNode * bFR = Cudd_Regular(bFunc);
-
- if ( cuddIsConstant(bFR) )
- {
- if ( cuddIsConstant(bVars) )
- return z0;
- return extraZddGetSingletonsBoth( dd, bVars );
- }
- assert( bVars != b1 );
-
- if ( (zRes = cuddCacheLookup2Zdd(dd, extraZddUnateInfoCompute, bFunc, bVars)) )
- return zRes;
- else
- {
- DdNode * zRes0, * zRes1;
- DdNode * zTemp, * zPlus;
- DdNode * bF0, * bF1;
- DdNode * bVarsNew;
- int nVarsExtra;
- int LevelF;
- int AddVar;
-
- // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
- // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
- // count how many extra vars are there in bVars
- nVarsExtra = 0;
- LevelF = dd->perm[bFR->index];
- for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
- nVarsExtra++;
- // the indexes (level) of variables should be synchronized now
- assert( bFR->index == bVarsNew->index );
-
- // cofactor the function
- if ( bFR != bFunc ) // bFunc is complemented
- {
- bF0 = Cudd_Not( cuddE(bFR) );
- bF1 = Cudd_Not( cuddT(bFR) );
- }
- else
- {
- bF0 = cuddE(bFR);
- bF1 = cuddT(bFR);
- }
-
- // solve subproblems
- zRes0 = extraZddUnateInfoCompute( dd, bF0, cuddT(bVarsNew) );
- if ( zRes0 == NULL )
- return NULL;
- cuddRef( zRes0 );
-
- // if there is no symmetries in the negative cofactor
- // there is no need to test the positive cofactor
- if ( zRes0 == z0 )
- zRes = zRes0; // zRes takes reference
- else
- {
- zRes1 = extraZddUnateInfoCompute( dd, bF1, cuddT(bVarsNew) );
- if ( zRes1 == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- return NULL;
- }
- cuddRef( zRes1 );
-
- // only those variables are pair-wise symmetric
- // that are pair-wise symmetric in both cofactors
- // therefore, intersect the solutions
- zRes = cuddZddIntersect( dd, zRes0, zRes1 );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zRes0 );
- Cudd_RecursiveDerefZdd( dd, zRes1 );
- }
-
- // consider the current top-most variable
- AddVar = -1;
- if ( Cudd_bddLeq( dd, bF0, bF1 ) ) // pos
- AddVar = 0;
- else if ( Cudd_bddLeq( dd, bF1, bF0 ) ) // neg
- AddVar = 1;
- if ( AddVar >= 0 )
- {
- // create the singleton
- zPlus = cuddZddGetNode( dd, 2*bFR->index + AddVar, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
- // only zRes is referenced at this point
-
- // if we skipped some variables, these variables cannot be symmetric with
- // any variables that are currently in the support of bF, but they can be
- // symmetric with the variables that are in bVars but not in the support of bF
- for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
- {
- // create the negative singleton
- zPlus = cuddZddGetNode( dd, 2*bVarsNew->index+1, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
-
-
- // create the positive singleton
- zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- }
- cuddDeref( zRes );
-
- /* insert the result into cache */
- cuddCacheInsert2(dd, extraZddUnateInfoCompute, bFunc, bVars, zRes);
- return zRes;
- }
-} /* end of extraZddUnateInfoCompute */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a recursive step of Extra_zddGetSingletons.]
-
- Description [Returns the set of ZDD singletons, containing those pos/neg
- polarity ZDD variables that correspond to the BDD variables in bVars.]
-
- SideEffects []
-
- SeeAlso []
-
-******************************************************************************/
-DdNode * extraZddGetSingletonsBoth(
- DdManager * dd, /* the DD manager */
- DdNode * bVars) /* the set of variables */
-{
- DdNode * zRes;
-
- if ( bVars == b1 )
- return z1;
-
- if ( (zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletonsBoth, bVars)) )
- return zRes;
- else
- {
- DdNode * zTemp, * zPlus;
-
- // solve subproblem
- zRes = extraZddGetSingletonsBoth( dd, cuddT(bVars) );
- if ( zRes == NULL )
- return NULL;
- cuddRef( zRes );
-
-
- // create the negative singleton
- zPlus = cuddZddGetNode( dd, 2*bVars->index+1, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
-
-
- // create the positive singleton
- zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
- if ( zPlus == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zRes );
- return NULL;
- }
- cuddRef( zPlus );
-
- // add these to the result
- zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
- if ( zRes == NULL )
- {
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
- return NULL;
- }
- cuddRef( zRes );
- Cudd_RecursiveDerefZdd( dd, zTemp );
- Cudd_RecursiveDerefZdd( dd, zPlus );
-
- cuddDeref( zRes );
- cuddCacheInsert1( dd, extraZddGetSingletonsBoth, bVars, zRes );
- return zRes;
- }
-} /* end of extraZddGetSingletonsBoth */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static Functions */
-/*---------------------------------------------------------------------------*/
-ABC_NAMESPACE_IMPL_END
-