summaryrefslogtreecommitdiffstats
path: root/src/bdd/dsd/dsdProc.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2007-09-30 08:01:00 -0700
commite54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (patch)
treede3ffe87c3e17950351e3b7d97fa18318bd5ea9a /src/bdd/dsd/dsdProc.c
parent7d7e60f2dc84393cd4c5db22d2eaf7b1fb1a79b2 (diff)
downloadabc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.gz
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.bz2
abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.zip
Version abc70930
Diffstat (limited to 'src/bdd/dsd/dsdProc.c')
-rw-r--r--src/bdd/dsd/dsdProc.c1617
1 files changed, 0 insertions, 1617 deletions
diff --git a/src/bdd/dsd/dsdProc.c b/src/bdd/dsd/dsdProc.c
deleted file mode 100644
index 543ad387..00000000
--- a/src/bdd/dsd/dsdProc.c
+++ /dev/null
@@ -1,1617 +0,0 @@
-/**CFile****************************************************************
-
- FileName [dsdProc.c]
-
- PackageName [DSD: Disjoint-support decomposition package.]
-
- Synopsis [The core procedures of the package.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 8.0. Started - September 22, 2003.]
-
- Revision [$Id: dsdProc.c,v 1.0 2002/22/09 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "dsdInt.h"
-
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-// the most important procedures
-void dsdKernelDecompose( Dsd_Manager_t * pDsdMan, DdNode ** pbFuncs, int nFuncs );
-static Dsd_Node_t * dsdKernelDecompose_rec( Dsd_Manager_t * pDsdMan, DdNode * F );
-
-// additional procedures
-static Dsd_Node_t * dsdKernelFindContainingComponent( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pWhere, DdNode * Var, int * fPolarity );
-static int dsdKernelFindCommonComponents( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pL, Dsd_Node_t * pH, Dsd_Node_t *** pCommon, Dsd_Node_t ** pLastDiffL, Dsd_Node_t ** pLastDiffH );
-static void dsdKernelComputeSumOfComponents( Dsd_Manager_t * pDsdMan, Dsd_Node_t ** pCommon, int nCommon, DdNode ** pCompF, DdNode ** pCompS, int fExor );
-static int dsdKernelCheckContainment( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pL, Dsd_Node_t * pH, Dsd_Node_t ** pLarge, Dsd_Node_t ** pSmall );
-
-// list copying
-static void dsdKernelCopyListPlusOne( Dsd_Node_t * p, Dsd_Node_t * First, Dsd_Node_t ** ppList, int nListSize );
-static void dsdKernelCopyListPlusOneMinusOne( Dsd_Node_t * p, Dsd_Node_t * First, Dsd_Node_t ** ppList, int nListSize, int Skipped );
-
-// debugging procedures
-static int dsdKernelVerifyDecomposition( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pDE );
-
-////////////////////////////////////////////////////////////////////////
-/// STATIC VARIABLES ///
-////////////////////////////////////////////////////////////////////////
-
-// the counter of marks
-static int s_Mark;
-
-// debugging flag
-static int s_Show = 0;
-// temporary var used for debugging
-static int Depth = 0;
-
-static int s_Loops1;
-static int s_Loops2;
-static int s_Loops3;
-static int s_Pivot;
-static int s_PivotNo;
-static int s_Common;
-static int s_CommonNo;
-
-static int s_Case4Calls;
-static int s_Case4CallsSpecial;
-
-static int s_Case5;
-static int s_Loops2Useless;
-
-
-static int s_DecNodesTotal;
-static int s_DecNodesUsed;
-
-// statistical variables
-static int s_nDecBlocks;
-static int s_nLiterals;
-static int s_nExorGates;
-static int s_nReusedBlocks;
-static int s_nCascades;
-static float s_nArea;
-static float s_MaxDelay;
-static long s_Time;
-static int s_nInvertors;
-static int s_nPrimeBlocks;
-
-static int HashSuccess = 0;
-static int HashFailure = 0;
-
-static int s_CacheEntries;
-
-
-////////////////////////////////////////////////////////////////////////
-/// DECOMPOSITION FUNCTIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Performs DSD for the array of functions represented by BDDs.]
-
- Description [This function takes the DSD manager, which should be
- previously allocated by the call to Dsd_ManagerStart(). The resulting
- DSD tree is stored in the DSD manager (pDsdMan->pRoots, pDsdMan->nRoots).
- Access to the tree is through the APIs of the manager. The resulting
- tree is a shared DSD DAG for the functions given in the array. For one
- function the resulting DAG is always a tree. The root node pointers can
- be complemented, as discussed in the literature referred to in "dsd.h".
- This procedure can be called repeatedly for different functions. There is
- no need to remove the decomposition tree after it is returned, because
- the next call to the DSD manager will "recycle" the tree. The user should
- not modify or dereference any data associated with the nodes of the
- DSD trees (the user can only change the contents of a temporary
- mark associated with each node by the calling to Dsd_NodeSetMark()).
- All the decomposition trees and intermediate nodes will be removed when
- the DSD manager is deallocated at the end by calling Dsd_ManagerStop().]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Dsd_Decompose( Dsd_Manager_t * pDsdMan, DdNode ** pbFuncs, int nFuncs )
-{
- DdManager * dd = pDsdMan->dd;
- int i;
- long clk;
- Dsd_Node_t * pTemp;
- int SumMaxGateSize = 0;
- int nDecOutputs = 0;
- int nCBFOutputs = 0;
-/*
-s_Loops1 = 0;
-s_Loops2 = 0;
-s_Loops3 = 0;
-s_Case4Calls = 0;
-s_Case4CallsSpecial = 0;
-s_Case5 = 0;
-s_Loops2Useless = 0;
-*/
- // resize the number of roots in the manager
- if ( pDsdMan->nRootsAlloc < nFuncs )
- {
- if ( pDsdMan->nRootsAlloc > 0 )
- free( pDsdMan->pRoots );
- pDsdMan->nRootsAlloc = nFuncs;
- pDsdMan->pRoots = (Dsd_Node_t **) malloc( pDsdMan->nRootsAlloc * sizeof(Dsd_Node_t *) );
- }
-
- if ( pDsdMan->fVerbose )
- printf( "\nDecomposability statistics for individual outputs:\n" );
-
- // set the counter of decomposition nodes
- s_nDecBlocks = 0;
-
- // perform decomposition for all outputs
- clk = clock();
- pDsdMan->nRoots = 0;
- s_nCascades = 0;
- for ( i = 0; i < nFuncs; i++ )
- {
- int nLiteralsPrev;
- int nDecBlocksPrev;
- int nExorGatesPrev;
- int nReusedBlocksPres;
- int nCascades;
- int MaxBlock;
- int nPrimeBlocks;
- long clk;
-
- clk = clock();
- nLiteralsPrev = s_nLiterals;
- nDecBlocksPrev = s_nDecBlocks;
- nExorGatesPrev = s_nExorGates;
- nReusedBlocksPres = s_nReusedBlocks;
- nPrimeBlocks = s_nPrimeBlocks;
-
- pDsdMan->pRoots[ pDsdMan->nRoots++ ] = dsdKernelDecompose_rec( pDsdMan, pbFuncs[i] );
-
- Dsd_TreeNodeGetInfoOne( pDsdMan->pRoots[i], &nCascades, &MaxBlock );
- s_nCascades = ddMax( s_nCascades, nCascades );
- pTemp = Dsd_Regular(pDsdMan->pRoots[i]);
- if ( pTemp->Type != DSD_NODE_PRIME || pTemp->nDecs != Extra_bddSuppSize(dd,pTemp->S) )
- nDecOutputs++;
- if ( MaxBlock < 3 )
- nCBFOutputs++;
- SumMaxGateSize += MaxBlock;
-
- if ( pDsdMan->fVerbose )
- {
- printf("#%02d: ", i );
- printf("Ins=%2d. ", Cudd_SupportSize(dd,pbFuncs[i]) );
- printf("Gts=%3d. ", Dsd_TreeCountNonTerminalNodesOne( pDsdMan->pRoots[i] ) );
- printf("Pri=%3d. ", Dsd_TreeCountPrimeNodesOne( pDsdMan->pRoots[i] ) );
- printf("Max=%3d. ", MaxBlock );
- printf("Reuse=%2d. ", s_nReusedBlocks-nReusedBlocksPres );
- printf("Csc=%2d. ", nCascades );
- printf("T= %.2f s. ", (float)(clock()-clk)/(float)(CLOCKS_PER_SEC) ) ;
- printf("Bdd=%2d. ", Cudd_DagSize(pbFuncs[i]) );
- printf("\n");
- fflush( stdout );
- }
- }
- assert( pDsdMan->nRoots == nFuncs );
-
- if ( pDsdMan->fVerbose )
- {
- printf( "\n" );
- printf( "The cumulative decomposability statistics:\n" );
- printf( " Total outputs = %5d\n", nFuncs );
- printf( " Decomposable outputs = %5d\n", nDecOutputs );
- printf( " Completely decomposable outputs = %5d\n", nCBFOutputs );
- printf( " The sum of max gate sizes = %5d\n", SumMaxGateSize );
- printf( " Shared BDD size = %5d\n", Cudd_SharingSize( pbFuncs, nFuncs ) );
- printf( " Decomposition entries = %5d\n", st_count( pDsdMan->Table ) );
- printf( " Pure decomposition time = %.2f sec\n", (float)(clock() - clk)/(float)(CLOCKS_PER_SEC) );
- }
-/*
- printf( "s_Loops1 = %d.\n", s_Loops1 );
- printf( "s_Loops2 = %d.\n", s_Loops2 );
- printf( "s_Loops3 = %d.\n", s_Loops3 );
- printf( "s_Case4Calls = %d.\n", s_Case4Calls );
- printf( "s_Case4CallsSpecial = %d.\n", s_Case4CallsSpecial );
- printf( "s_Case5 = %d.\n", s_Case5 );
- printf( "s_Loops2Useless = %d.\n", s_Loops2Useless );
-*/
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs decomposition for one function.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Dsd_Node_t * Dsd_DecomposeOne( Dsd_Manager_t * pDsdMan, DdNode * bFunc )
-{
- return dsdKernelDecompose_rec( pDsdMan, bFunc );
-}
-
-/**Function*************************************************************
-
- Synopsis [The main function of this module. Recursive implementation of DSD.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Dsd_Node_t * dsdKernelDecompose_rec( Dsd_Manager_t * pDsdMan, DdNode * bFunc0 )
-{
- DdManager * dd = pDsdMan->dd;
- DdNode * bLow;
- DdNode * bLowR;
- DdNode * bHigh;
-
- int VarInt;
- DdNode * bVarCur;
- Dsd_Node_t * pVarCurDE;
- // works only if var indices start from 0!!!
- DdNode * bSuppNew = NULL, * bTemp;
-
- int fContained;
- int nSuppLH;
- int nSuppL;
- int nSuppH;
-
-
-
- // various decomposition nodes
- Dsd_Node_t * pThis, * pL, * pH, * pLR, * pHR;
-
- Dsd_Node_t * pSmallR, * pLargeR;
- Dsd_Node_t * pTableEntry;
-
-
- // treat the complemented case
- DdNode * bF = Cudd_Regular(bFunc0);
- int fCompF = (int)(bF != bFunc0);
-
- // check cache
- if ( st_lookup( pDsdMan->Table, (char*)bF, (char**)&pTableEntry ) )
- { // the entry is present
- HashSuccess++;
- return Dsd_NotCond( pTableEntry, fCompF );
- }
- HashFailure++;
- Depth++;
-
- // proceed to consider "four cases"
- //////////////////////////////////////////////////////////////////////
- // TERMINAL CASES - CASES 1 and 2
- //////////////////////////////////////////////////////////////////////
- bLow = cuddE(bF);
- bLowR = Cudd_Regular(bLow);
- bHigh = cuddT(bF);
- VarInt = bF->index;
- bVarCur = dd->vars[VarInt];
- pVarCurDE = pDsdMan->pInputs[VarInt];
- // works only if var indices start from 0!!!
- bSuppNew = NULL;
-
- if ( bLowR->index == CUDD_CONST_INDEX || bHigh->index == CUDD_CONST_INDEX )
- { // one of the cofactors in the constant
- if ( bHigh == b1 ) // bHigh cannot be equal to b0, because then it will be complemented
- if ( bLow == b0 ) // bLow cannot be equal to b1, because then the node will have bLow == bHigh
- /////////////////////////////////////////////////////////////////
- // bLow == 0, bHigh == 1, F = x'&0 + x&1 = x
- /////////////////////////////////////////////////////////////////
- { // create the elementary variable node
- assert(0); // should be already in the hash table
- pThis = Dsd_TreeNodeCreate( DSD_NODE_BUF, 1, s_nDecBlocks++ );
- pThis->pDecs[0] = NULL;
- }
- else // if ( bLow != constant )
- /////////////////////////////////////////////////////////////////
- // bLow != const, bHigh == 1, F = x'&bLow + x&1 = bLow + x --- DSD_NODE_OR(x,bLow)
- /////////////////////////////////////////////////////////////////
- {
- pL = dsdKernelDecompose_rec( pDsdMan, bLow );
- pLR = Dsd_Regular( pL );
- bSuppNew = Cudd_bddAnd( dd, bVarCur, pLR->S ); Cudd_Ref(bSuppNew);
- if ( pLR->Type == DSD_NODE_OR && pL == pLR ) // OR and no complement
- { // add to the components
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, pL->nDecs+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, pVarCurDE, pL->pDecs, pL->nDecs );
- }
- else // all other cases
- { // create a new 2-input OR-gate
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, 2, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pL, 1 );
- }
- }
- else // if ( bHigh != const ) // meaning that bLow should be a constant
- {
- pH = dsdKernelDecompose_rec( pDsdMan, bHigh );
- pHR = Dsd_Regular( pH );
- bSuppNew = Cudd_bddAnd( dd, bVarCur, pHR->S ); Cudd_Ref(bSuppNew);
- if ( bLow == b0 )
- /////////////////////////////////////////////////////////////////
- // Low == 0, High != 1, F = x'&0+x&High = (x'+High')'--- NOR(x',High')
- /////////////////////////////////////////////////////////////////
- if ( pHR->Type == DSD_NODE_OR && pH != pHR ) // DSD_NODE_OR and complement
- { // add to the components
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, pHR->nDecs+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, Dsd_Not(pVarCurDE), pHR->pDecs, pHR->nDecs );
- pThis = Dsd_Not(pThis);
- }
- else // all other cases
- { // create a new 2-input NOR gate
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, 2, s_nDecBlocks++ );
- pH = Dsd_Not(pH);
- dsdKernelCopyListPlusOne( pThis, Dsd_Not(pVarCurDE), &pH, 1 );
- pThis = Dsd_Not(pThis);
- }
- else // if ( bLow == b1 )
- /////////////////////////////////////////////////////////////////
- // Low == 1, High != 1, F = x'&1 + x&High = x' + High --- DSD_NODE_OR(x',High)
- /////////////////////////////////////////////////////////////////
- if ( pHR->Type == DSD_NODE_OR && pH == pHR ) // OR and no complement
- { // add to the components
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, pH->nDecs+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, Dsd_Not(pVarCurDE), pH->pDecs, pH->nDecs );
- }
- else // all other cases
- { // create a new 2-input OR-gate
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, 2, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, Dsd_Not(pVarCurDE), &pH, 1 );
- }
- }
- goto EXIT;
- }
- // else if ( bLow != const && bHigh != const )
-
- // the case of equal cofactors (up to complementation)
- if ( bLowR == bHigh )
- /////////////////////////////////////////////////////////////////
- // Low == G, High == G', F = x'&G + x&G' = (x(+)G) --- EXOR(x,Low)
- /////////////////////////////////////////////////////////////////
- {
- pL = dsdKernelDecompose_rec( pDsdMan, bLow );
- pLR = Dsd_Regular( pL );
- bSuppNew = Cudd_bddAnd( dd, bVarCur, pLR->S ); Cudd_Ref(bSuppNew);
- if ( pLR->Type == DSD_NODE_EXOR ) // complemented or not - does not matter!
- { // add to the components
- pThis = Dsd_TreeNodeCreate( DSD_NODE_EXOR, pLR->nDecs+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, pVarCurDE, pLR->pDecs, pLR->nDecs );
- if ( pL != pLR )
- pThis = Dsd_Not( pThis );
- }
- else // all other cases
- { // create a new 2-input EXOR-gate
- pThis = Dsd_TreeNodeCreate( DSD_NODE_EXOR, 2, s_nDecBlocks++ );
- if ( pL != pLR ) // complemented
- {
- dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pLR, 1 );
- pThis = Dsd_Not( pThis );
- }
- else // non-complemented
- dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pL, 1 );
- }
- goto EXIT;
- }
-
- //////////////////////////////////////////////////////////////////////
- // solve subproblems
- //////////////////////////////////////////////////////////////////////
- pL = dsdKernelDecompose_rec( pDsdMan, bLow );
- pH = dsdKernelDecompose_rec( pDsdMan, bHigh );
- pLR = Dsd_Regular( pL );
- pHR = Dsd_Regular( pH );
-
- assert( pLR->Type == DSD_NODE_BUF || pLR->Type == DSD_NODE_OR || pLR->Type == DSD_NODE_EXOR || pLR->Type == DSD_NODE_PRIME );
- assert( pHR->Type == DSD_NODE_BUF || pHR->Type == DSD_NODE_OR || pHR->Type == DSD_NODE_EXOR || pHR->Type == DSD_NODE_PRIME );
-
-/*
-if ( Depth == 1 )
-{
-// PRK(bLow,pDecTreeTotal->nInputs);
-// PRK(bHigh,pDecTreeTotal->nInputs);
-if ( s_Show )
-{
- PRD( pL );
- PRD( pH );
-}
-}
-*/
- // compute the new support
- bTemp = Cudd_bddAnd( dd, pLR->S, pHR->S ); Cudd_Ref( bTemp );
- nSuppL = Extra_bddSuppSize( dd, pLR->S );
- nSuppH = Extra_bddSuppSize( dd, pHR->S );
- nSuppLH = Extra_bddSuppSize( dd, bTemp );
- bSuppNew = Cudd_bddAnd( dd, bTemp, bVarCur ); Cudd_Ref( bSuppNew );
- Cudd_RecursiveDeref( dd, bTemp );
-
-
- // several possibilities are possible
- // (1) support of one component contains another
- // (2) none of the supports is contained in another
- fContained = dsdKernelCheckContainment( pDsdMan, pLR, pHR, &pLargeR, &pSmallR );
-
- //////////////////////////////////////////////////////////////////////
- // CASE 3.b One of the cofactors in a constant (OR and EXOR)
- //////////////////////////////////////////////////////////////////////
- // the support of the larger component should contain the support of the smaller
- // it is possible to have PRIME function in this role
- // for example: F = ITE( a+b, c(+)d, e+f ), F0 = ITE( b, c(+)d, e+f ), F1 = c(+)d
- if ( fContained )
- {
- Dsd_Node_t * pSmall, * pLarge;
- int c, iCompLarge; // the number of the component is Large is equal to the whole of Small
- int fLowIsLarge;
-
- DdNode * bFTemp; // the changed input function
- Dsd_Node_t * pDETemp, * pDENew;
-
- Dsd_Node_t * pComp = NULL;
- int nComp;
-
- if ( pSmallR == pLR )
- { // Low is Small => High is Large
- pSmall = pL;
- pLarge = pH;
- fLowIsLarge = 0;
- }
- else
- { // vice versa
- pSmall = pH;
- pLarge = pL;
- fLowIsLarge = 1;
- }
-
- // treat the situation when the larger is PRIME
- if ( pLargeR->Type == DSD_NODE_PRIME ) //&& pLargeR->nDecs != pSmallR->nDecs )
- {
- // QUESTION: Is it possible for pLargeR->nDecs > 3
- // and pSmall contained as one of input in pLarge?
- // Yes, for example F = a'c + a & MUX(b,c',d) = a'c + abc' + ab'd is non-decomposable
- // Consider the function H(a->xy) = F( xy, b, c, d )
- // H0 = H(x=0) = F(0,b,c,d) = c
- // H1 = F(x=1) = F(y,b,c,d) - non-decomposable
- //
- // QUESTION: Is it possible that pLarge is PRIME(3) and pSmall is OR(2),
- // which is not contained in PRIME as one input?
- // Yes, for example F = abcd + b'c'd' + a'c'd' = PRIME(ab, c, d)
- // F(a=0) = c'd' = NOT(OR(a,d)) F(a=1) = bcd + b'c'd' = PRIME(b,c,d)
- // To find decomposition, we have to prove that F(a=1)|b=0 = F(a=0)
-
- // Is it possible that (pLargeR->nDecs == pSmallR->nDecs) and yet this case holds?
- // Yes, consider the function such that F(a=0) = PRIME(a,b+c,d,e) and F(a=1) = OR(b,c,d,e)
- // They have the same number of inputs and it is possible that they will be the cofactors
- // as discribed in the previous example.
-
- // find the component, which when substituted for 0 or 1, produces the desired result
- int g, fFoundComp; // {0,1} depending on whether setting cofactor to 0 or 1 worked out
-
- DdNode * bLarge, * bSmall;
- if ( fLowIsLarge )
- {
- bLarge = bLow;
- bSmall = bHigh;
- }
- else
- {
- bLarge = bHigh;
- bSmall = bLow;
- }
-
- for ( g = 0; g < pLargeR->nDecs; g++ )
-// if ( g != c )
- {
- pDETemp = pLargeR->pDecs[g]; // cannot be complemented
- if ( Dsd_CheckRootFunctionIdentity( dd, bLarge, bSmall, pDETemp->G, b1 ) )
- {
- fFoundComp = 1;
- break;
- }
-
- s_Loops1++;
-
- if ( Dsd_CheckRootFunctionIdentity( dd, bLarge, bSmall, Cudd_Not(pDETemp->G), b1 ) )
- {
- fFoundComp = 0;
- break;
- }
-
- s_Loops1++;
- }
-
- if ( g != pLargeR->nDecs )
- { // decomposition is found
- if ( fFoundComp )
- if ( fLowIsLarge )
- bFTemp = Cudd_bddOr( dd, bVarCur, pLargeR->pDecs[g]->G );
- else
- bFTemp = Cudd_bddOr( dd, Cudd_Not(bVarCur), pLargeR->pDecs[g]->G );
- else
- if ( fLowIsLarge )
- bFTemp = Cudd_bddAnd( dd, Cudd_Not(bVarCur), pLargeR->pDecs[g]->G );
- else
- bFTemp = Cudd_bddAnd( dd, bVarCur, pLargeR->pDecs[g]->G );
- Cudd_Ref( bFTemp );
-
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFTemp );
- pDENew = Dsd_Regular( pDENew );
- Cudd_RecursiveDeref( dd, bFTemp );
-
- // get the new gate
- pThis = Dsd_TreeNodeCreate( DSD_NODE_PRIME, pLargeR->nDecs, s_nDecBlocks++ );
- dsdKernelCopyListPlusOneMinusOne( pThis, pDENew, pLargeR->pDecs, pLargeR->nDecs, g );
- goto EXIT;
- }
- }
-
- // try to find one component in the pLarger that is equal to the whole of pSmaller
- for ( c = 0; c < pLargeR->nDecs; c++ )
- if ( pLargeR->pDecs[c] == pSmall || pLargeR->pDecs[c] == Dsd_Not(pSmall) )
- {
- iCompLarge = c;
- break;
- }
-
- // assign the equal component
- if ( c != pLargeR->nDecs ) // the decomposition is possible!
- {
- pComp = pLargeR->pDecs[iCompLarge];
- nComp = 1;
- }
- else // the decomposition is still possible
- { // for example F = OR(ab,c,d), F(a=0) = OR(c,d), F(a=1) = OR(b,c,d)
- // supp(F0) is contained in supp(F1), Polarity(F(a=0)) == Polarity(F(a=1))
-
- // try to find a group of common components
- if ( pLargeR->Type == pSmallR->Type &&
- (pLargeR->Type == DSD_NODE_EXOR || pSmallR->Type == DSD_NODE_OR&& ((pLarge==pLargeR) == (pSmall==pSmallR))) )
- {
- Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
- int nCommon = dsdKernelFindCommonComponents( pDsdMan, pLargeR, pSmallR, &pCommon, &pLastDiffL, &pLastDiffH );
- // if all the components of pSmall are contained in pLarge,
- // then the decomposition exists
- if ( nCommon == pSmallR->nDecs )
- {
- pComp = pSmallR;
- nComp = pSmallR->nDecs;
- }
- }
- }
-
- if ( pComp ) // the decomposition is possible!
- {
-// Dsd_Node_t * pComp = pLargeR->pDecs[iCompLarge];
- Dsd_Node_t * pCompR = Dsd_Regular( pComp );
- int fComp1 = (int)( pLarge != pLargeR );
- int fComp2 = (int)( pComp != pCompR );
- int fComp3 = (int)( pSmall != pSmallR );
-
- DdNode * bFuncComp; // the function of the given component
- DdNode * bFuncNew; // the function of the input component
-
- if ( pLargeR->Type == DSD_NODE_OR ) // Figure 4 of Matsunaga's paper
- {
- // the decomposition exists only if the polarity assignment
- // along the paths is the same
- if ( (fComp1 ^ fComp2) == fComp3 )
- { // decomposition exists = consider 4 cases
- // consideration of cases leads to the following conclusion
- // fComp1 gives the polarity of the resulting DSD_NODE_OR gate
- // fComp2 gives the polarity of the common component feeding into the DSD_NODE_OR gate
- //
- // | fComp1 pL/ |pS
- // <> .........<=>....... <> |
- // | / |
- // [OR] [OR] | fComp3
- // / \ fComp2 / | \ |
- // <> <> .......<=>... /..|..<> |
- // / \ / | \|
- // [OR] [C] S1 S2 C
- // / \
- // <> \
- // / \
- // [OR] [x]
- // / \
- // S1 S2
- //
-
-
- // at this point we have the function F (bFTemp) and the common component C (bFuncComp)
- // to get the remainder, R, in the relationship F = R + C, supp(R) & supp(C) = 0
- // we compute the following R = Exist( F - C, supp(C) )
- bFTemp = (fComp1)? Cudd_Not( bF ): bF;
- bFuncComp = (fComp2)? Cudd_Not( pCompR->G ): pCompR->G;
- bFuncNew = Cudd_bddAndAbstract( dd, bFTemp, Cudd_Not(bFuncComp), pCompR->S ); Cudd_Ref( bFuncNew );
-
- // there is no need to copy the dec entry list first, because pComp is a component
- // which will not be destroyed by the recursive call to decomposition
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
- assert( Dsd_IsComplement(pDENew) ); // follows from the consideration of cases
- Cudd_RecursiveDeref( dd, bFuncNew );
-
- // get the new gate
- if ( nComp == 1 )
- {
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, 2, s_nDecBlocks++ );
- pThis->pDecs[0] = pDENew;
- pThis->pDecs[1] = pComp; // takes the complement
- }
- else
- { // pComp is not complemented
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, nComp+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, pDENew, pComp->pDecs, nComp );
- }
-
- if ( fComp1 )
- pThis = Dsd_Not( pThis );
- goto EXIT;
- }
- }
- else if ( pLargeR->Type == DSD_NODE_EXOR ) // Figure 5 of Matsunaga's paper (with correction)
- { // decomposition always exists = consider 4 cases
-
- // consideration of cases leads to the following conclusion
- // fComp3 gives the COMPLEMENT of the polarity of the resulting EXOR gate
- // (if fComp3 is 0, the EXOR gate is complemented, and vice versa)
- //
- // | fComp1 pL/ |pS
- // <> .........<=>....... /....| fComp3
- // | / |
- // [XOR] [XOR] |
- // / \ fComp2==0 / | \ |
- // / \ / | \ |
- // / \ / | \|
- // [OR] [C] S1 S2 C
- // / \
- // <> \
- // / \
- // [XOR] [x]
- // / \
- // S1 S2
- //
-
- assert( fComp2 == 0 );
- // find the functionality of the lower gates
- bFTemp = (fComp3)? bF: Cudd_Not( bF );
- bFuncNew = Cudd_bddXor( dd, bFTemp, pComp->G ); Cudd_Ref( bFuncNew );
-
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
- assert( !Dsd_IsComplement(pDENew) ); // follows from the consideration of cases
- Cudd_RecursiveDeref( dd, bFuncNew );
-
- // get the new gate
- if ( nComp == 1 )
- {
- pThis = Dsd_TreeNodeCreate( DSD_NODE_EXOR, 2, s_nDecBlocks++ );
- pThis->pDecs[0] = pDENew;
- pThis->pDecs[1] = pComp;
- }
- else
- { // pComp is not complemented
- pThis = Dsd_TreeNodeCreate( DSD_NODE_EXOR, nComp+1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, pDENew, pComp->pDecs, nComp );
- }
-
- if ( !fComp3 )
- pThis = Dsd_Not( pThis );
- goto EXIT;
- }
- }
- }
-
- // this case was added to fix the trivial bug found November 4, 2002 in Japan
- // by running the example provided by T. Sasao
- if ( nSuppLH == nSuppL + nSuppH ) // the supports of the components are disjoint
- {
- // create a new component of the type ITE( a, pH, pL )
- pThis = Dsd_TreeNodeCreate( DSD_NODE_PRIME, 3, s_nDecBlocks++ );
- if ( dd->perm[pLR->S->index] < dd->perm[pHR->S->index] ) // pLR is higher in the varible order
- {
- pThis->pDecs[1] = pLR;
- pThis->pDecs[2] = pHR;
- }
- else // pHR is higher in the varible order
- {
- pThis->pDecs[1] = pHR;
- pThis->pDecs[2] = pLR;
- }
- // add the first component
- pThis->pDecs[0] = pVarCurDE;
- goto EXIT;
- }
-
-
- //////////////////////////////////////////////////////////////////////
- // CASE 3.a Neither of the cofactors is a constant (OR, EXOR, PRIME)
- //////////////////////////////////////////////////////////////////////
- // the component types are identical
- // and if they are OR, they are either both complemented or both not complemented
- // and if they are PRIME, their dec numbers should be the same
- if ( pLR->Type == pHR->Type &&
- pLR->Type != DSD_NODE_BUF &&
- (pLR->Type != DSD_NODE_OR || ( pL == pLR && pH == pHR || pL != pLR && pH != pHR ) ) &&
- (pLR->Type != DSD_NODE_PRIME || pLR->nDecs == pHR->nDecs) )
- {
- // array to store common comps in pL and pH
- Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
- int nCommon = dsdKernelFindCommonComponents( pDsdMan, pLR, pHR, &pCommon, &pLastDiffL, &pLastDiffH );
- if ( nCommon )
- {
- if ( pLR->Type == DSD_NODE_OR ) // Figure 2 of Matsunaga's paper
- { // at this point we have the function F and the group of common components C
- // to get the remainder, R, in the relationship F = R + C, supp(R) & supp(C) = 0
- // we compute the following R = Exist( F - C, supp(C) )
-
- // compute the sum total of the common components and the union of their supports
- DdNode * bCommF, * bCommS, * bFTemp, * bFuncNew;
- Dsd_Node_t * pDENew;
-
- dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, &bCommS, 0 );
- Cudd_Ref( bCommF );
- Cudd_Ref( bCommS );
- bFTemp = ( pL != pLR )? Cudd_Not(bF): bF;
-
- bFuncNew = Cudd_bddAndAbstract( dd, bFTemp, Cudd_Not(bCommF), bCommS ); Cudd_Ref( bFuncNew );
- Cudd_RecursiveDeref( dd, bCommF );
- Cudd_RecursiveDeref( dd, bCommS );
-
- // get the new gate
-
- // copy the components first, then call the decomposition
- // because decomposition will distroy the list used for copying
- pThis = Dsd_TreeNodeCreate( DSD_NODE_OR, nCommon + 1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
-
- // call the decomposition recursively
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
-// assert( !Dsd_IsComplement(pDENew) ); // follows from the consideration of cases
- Cudd_RecursiveDeref( dd, bFuncNew );
-
- // add the first component
- pThis->pDecs[0] = pDENew;
-
- if ( pL != pLR )
- pThis = Dsd_Not( pThis );
- goto EXIT;
- }
- else
- if ( pLR->Type == DSD_NODE_EXOR ) // Figure 3 of Matsunaga's paper
- {
- // compute the sum total of the common components and the union of their supports
- DdNode * bCommF, * bFuncNew;
- Dsd_Node_t * pDENew;
- int fCompExor;
-
- dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, NULL, 1 );
- Cudd_Ref( bCommF );
-
- bFuncNew = Cudd_bddXor( dd, bF, bCommF ); Cudd_Ref( bFuncNew );
- Cudd_RecursiveDeref( dd, bCommF );
-
- // get the new gate
-
- // copy the components first, then call the decomposition
- // because decomposition will distroy the list used for copying
- pThis = Dsd_TreeNodeCreate( DSD_NODE_EXOR, nCommon + 1, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
-
- // call the decomposition recursively
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
- Cudd_RecursiveDeref( dd, bFuncNew );
-
- // remember the fact that it was complemented
- fCompExor = Dsd_IsComplement(pDENew);
- pDENew = Dsd_Regular(pDENew);
-
- // add the first component
- pThis->pDecs[0] = pDENew;
-
-
- if ( fCompExor )
- pThis = Dsd_Not( pThis );
- goto EXIT;
- }
- else
- if ( pLR->Type == DSD_NODE_PRIME && (nCommon == pLR->nDecs-1 || nCommon == pLR->nDecs) )
- {
- // for example the function F(a,b,c,d) = ITE(b,c,a(+)d) produces
- // two cofactors F(a=0) = PRIME(b,c,d) and F(a=1) = PRIME(b,c,d)
- // with exactly the same list of common components
-
- Dsd_Node_t * pDENew;
- DdNode * bFuncNew;
- int fCompComp = 0; // this flag can be {0,1,2}
- // if it is 0 there is no identity
- // if it is 1/2, the cofactored functions are equal in the direct/complemented polarity
-
- if ( nCommon == pLR->nDecs )
- { // all the components are the same
- // find the formal input, in which pLow and pHigh differ (if such input exists)
- int m;
- Dsd_Node_t * pTempL, * pTempH;
-
- s_Common++;
- for ( m = 0; m < pLR->nDecs; m++ )
- {
- pTempL = pLR->pDecs[m]; // cannot be complemented
- pTempH = pHR->pDecs[m]; // cannot be complemented
-
- if ( Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, pTempL->G, Cudd_Not(pTempH->G) ) &&
- Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, Cudd_Not(pTempL->G), pTempH->G ) )
- {
- pLastDiffL = pTempL;
- pLastDiffH = pTempH;
- assert( pLastDiffL == pLastDiffH );
- fCompComp = 2;
- break;
- }
-
- s_Loops2++;
- s_Loops2++;
-/*
- if ( s_Loops2 % 10000 == 0 )
- {
- int i;
- for ( i = 0; i < pLR->nDecs; i++ )
- printf( " %d(s=%d)", pLR->pDecs[i]->Type,
- Extra_bddSuppSize(dd, pLR->pDecs[i]->S) );
- printf( "\n" );
- }
-*/
-
- }
-// if ( pLR->nDecs == Extra_bddSuppSize(dd, pLR->S) )
-// s_Loops2Useless += pLR->nDecs * 2;
-
- if ( fCompComp )
- { // put the equal components into pCommon, so that they could be copied into the new dec entry
- nCommon = 0;
- for ( m = 0; m < pLR->nDecs; m++ )
- if ( pLR->pDecs[m] != pLastDiffL )
- pCommon[nCommon++] = pLR->pDecs[m];
- assert( nCommon = pLR->nDecs-1 );
- }
- }
- else
- { // the differing components are known - check that they have compatible PRIME function
-
- s_CommonNo++;
-
- // find the numbers of different components
- assert( pLastDiffL );
- assert( pLastDiffH );
- // also, they cannot be complemented, because the decomposition type is PRIME
-
- if ( Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, Cudd_Not(pLastDiffL->G), Cudd_Not(pLastDiffH->G) ) &&
- Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, pLastDiffL->G, pLastDiffH->G ) )
- fCompComp = 1;
- else if ( Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, pLastDiffL->G, Cudd_Not(pLastDiffH->G) ) &&
- Dsd_CheckRootFunctionIdentity( dd, bLow, bHigh, Cudd_Not(pLastDiffL->G), pLastDiffH->G ) )
- fCompComp = 2;
-
- s_Loops3 += 4;
- }
-
- if ( fCompComp )
- {
- if ( fCompComp == 1 ) // it is true that bLow(G=0) == bHigh(H=0) && bLow(G=1) == bHigh(H=1)
- bFuncNew = Cudd_bddIte( dd, bVarCur, pLastDiffH->G, pLastDiffL->G );
- else // it is true that bLow(G=0) == bHigh(H=1) && bLow(G=1) == bHigh(H=0)
- bFuncNew = Cudd_bddIte( dd, bVarCur, Cudd_Not(pLastDiffH->G), pLastDiffL->G );
- Cudd_Ref( bFuncNew );
-
- // get the new gate
-
- // copy the components first, then call the decomposition
- // because decomposition will distroy the list used for copying
- pThis = Dsd_TreeNodeCreate( DSD_NODE_PRIME, pLR->nDecs, s_nDecBlocks++ );
- dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
-
- // create a new component
- pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
- Cudd_RecursiveDeref( dd, bFuncNew );
- // the BDD of the argument function in PRIME decomposition, should be regular
- pDENew = Dsd_Regular(pDENew);
-
- // add the first component
- pThis->pDecs[0] = pDENew;
- goto EXIT;
- }
- } // end of PRIME type
- } // end of existing common components
- } // end of CASE 3.a
-
-// if ( Depth != 1)
-// {
-
-//CASE4:
- //////////////////////////////////////////////////////////////////////
- // CASE 4
- //////////////////////////////////////////////////////////////////////
- {
- // estimate the number of entries in the list
- int nEntriesMax = pDsdMan->nInputs - dd->perm[VarInt];
-
- // create the new decomposition entry
- int nEntries = 0;
-
- DdNode * SuppL, * SuppH, * SuppL_init, * SuppH_init;
- Dsd_Node_t *pHigher, *pLower, * pTemp, * pDENew;
-
-
- int levTopSuppL;
- int levTopSuppH;
- int levTop;
-
- pThis = Dsd_TreeNodeCreate( DSD_NODE_PRIME, nEntriesMax, s_nDecBlocks++ );
- pThis->pDecs[ nEntries++ ] = pVarCurDE;
- // other entries will be added to this list one-by-one during analysis
-
- // count how many times does it happen that the decomposition entries are
- s_Case4Calls++;
-
- // consider the simplest case: when the supports are equal
- // and at least one of the components
- // is the PRIME without decompositions, or
- // when both of them are without decomposition
- if ( (((pLR->Type == DSD_NODE_PRIME && nSuppL == pLR->nDecs) || (pHR->Type == DSD_NODE_PRIME && nSuppH == pHR->nDecs)) && pLR->S == pHR->S) ||
- ((pLR->Type == DSD_NODE_PRIME && nSuppL == pLR->nDecs) && (pHR->Type == DSD_NODE_PRIME && nSuppH == pHR->nDecs)) )
- {
-
- s_Case4CallsSpecial++;
- // walk through both supports and create the decomposition list composed of simple entries
- SuppL = pLR->S;
- SuppH = pHR->S;
- do
- {
- // determine levels
- levTopSuppL = cuddI(dd,SuppL->index);
- levTopSuppH = cuddI(dd,SuppH->index);
-
- // skip the topmost variable in both supports
- if ( levTopSuppL <= levTopSuppH )
- {
- levTop = levTopSuppL;
- SuppL = cuddT(SuppL);
- }
- else
- levTop = levTopSuppH;
-
- if ( levTopSuppH <= levTopSuppL )
- SuppH = cuddT(SuppH);
-
- // set the new decomposition entry
- pThis->pDecs[ nEntries++ ] = pDsdMan->pInputs[ dd->invperm[levTop] ];
- }
- while ( SuppL != b1 || SuppH != b1 );
- }
- else
- {
-
- // compare two different decomposition lists
- SuppL_init = pLR->S;
- SuppH_init = pHR->S;
- // start references (because these supports will change)
- SuppL = pLR->S; Cudd_Ref( SuppL );
- SuppH = pHR->S; Cudd_Ref( SuppH );
- while ( SuppL != b1 || SuppH != b1 )
- {
- // determine the top level in cofactors and
- // whether they have the same top level
- int TopLevL = cuddI(dd,SuppL->index);
- int TopLevH = cuddI(dd,SuppH->index);
- int TopLevel = TopLevH;
- int fEqualLevel = 0;
-
- DdNode * bVarTop;
- DdNode * bSuppSubract;
-
-
- if ( TopLevL < TopLevH )
- {
- pHigher = pLR;
- pLower = pHR;
- TopLevel = TopLevL;
- }
- else if ( TopLevL > TopLevH )
- {
- pHigher = pHR;
- pLower = pLR;
- }
- else
- fEqualLevel = 1;
- assert( TopLevel != CUDD_CONST_INDEX );
-
-
- // find the currently top variable in the decomposition lists
- bVarTop = dd->vars[dd->invperm[TopLevel]];
-
- if ( !fEqualLevel )
- {
- // find the lower support
- DdNode * bSuppLower = (TopLevL < TopLevH)? SuppH_init: SuppL_init;
-
- // find the first component in pHigher
- // whose support does not overlap with supp(Lower)
- // and remember the previous component
- int fPolarity;
- Dsd_Node_t * pPrev = NULL; // the pointer to the component proceeding pCur
- Dsd_Node_t * pCur = pHigher; // the first component not contained in supp(Lower)
- while ( Extra_bddSuppOverlapping( dd, pCur->S, bSuppLower ) )
- { // get the next component
- pPrev = pCur;
- pCur = dsdKernelFindContainingComponent( pDsdMan, pCur, bVarTop, &fPolarity );
- };
-
- // look for the possibility to subtract more than one component
- if ( pPrev == NULL || pPrev->Type == DSD_NODE_PRIME )
- { // if there is no previous component, or if the previous component is PRIME
- // there is no way to subtract more than one component
-
- // add the new decomposition entry (it is already regular)
- pThis->pDecs[ nEntries++ ] = pCur;
- // assign the support to be subtracted from both components
- bSuppSubract = pCur->S;
- }
- else // all other types
- {
- // go through the decomposition list of pPrev and find components
- // whose support does not overlap with supp(Lower)
-
- static Dsd_Node_t * pNonOverlap[MAXINPUTS];
- int i, nNonOverlap = 0;
- for ( i = 0; i < pPrev->nDecs; i++ )
- {
- pTemp = Dsd_Regular( pPrev->pDecs[i] );
- if ( !Extra_bddSuppOverlapping( dd, pTemp->S, bSuppLower ) )
- pNonOverlap[ nNonOverlap++ ] = pPrev->pDecs[i];
- }
- assert( nNonOverlap > 0 );
-
- if ( nNonOverlap == 1 )
- { // one one component was found, which is the original one
- assert( Dsd_Regular(pNonOverlap[0]) == pCur);
- // add the new decomposition entry
- pThis->pDecs[ nEntries++ ] = pCur;
- // assign the support to be subtracted from both components
- bSuppSubract = pCur->S;
- }
- else // more than one components was found
- {
- // find the OR (EXOR) of the non-overlapping components
- DdNode * bCommF;
- dsdKernelComputeSumOfComponents( pDsdMan, pNonOverlap, nNonOverlap, &bCommF, NULL, (int)(pPrev->Type==DSD_NODE_EXOR) );
- Cudd_Ref( bCommF );
-
- // create a new gated
- pDENew = dsdKernelDecompose_rec( pDsdMan, bCommF );
- Cudd_RecursiveDeref(dd, bCommF);
- // make it regular... it must be regular already
- assert( !Dsd_IsComplement(pDENew) );
-
- // add the new decomposition entry
- pThis->pDecs[ nEntries++ ] = pDENew;
- // assign the support to be subtracted from both components
- bSuppSubract = pDENew->S;
- }
- }
-
- // subtract its support from the support of upper component
- if ( TopLevL < TopLevH )
- {
- SuppL = Cudd_bddExistAbstract( dd, bTemp = SuppL, bSuppSubract ); Cudd_Ref( SuppL );
- Cudd_RecursiveDeref(dd, bTemp);
- }
- else
- {
- SuppH = Cudd_bddExistAbstract( dd, bTemp = SuppH, bSuppSubract ); Cudd_Ref( SuppH );
- Cudd_RecursiveDeref(dd, bTemp);
- }
- } // end of if ( !fEqualLevel )
- else // if ( fEqualLevel ) -- they have the same top level var
- {
- static Dsd_Node_t * pMarkedLeft[MAXINPUTS]; // the pointers to the marked blocks
- static char pMarkedPols[MAXINPUTS]; // polarities of the marked blocks
- int nMarkedLeft = 0;
-
- int fPolarity = 0;
- Dsd_Node_t * pTempL = pLR;
-
- int fPolarityCurH = 0;
- Dsd_Node_t * pPrevH = NULL, * pCurH = pHR;
-
- int fPolarityCurL = 0;
- Dsd_Node_t * pPrevL = NULL, * pCurL = pLR; // = pMarkedLeft[0];
- int index = 1;
-
- // set the new mark
- s_Mark++;
-
- // go over the dec list of pL, mark all components that contain the given variable
- assert( Extra_bddSuppContainVar( dd, pLR->S, bVarTop ) );
- assert( Extra_bddSuppContainVar( dd, pHR->S, bVarTop ) );
- do {
- pTempL->Mark = s_Mark;
- pMarkedLeft[ nMarkedLeft ] = pTempL;
- pMarkedPols[ nMarkedLeft ] = fPolarity;
- nMarkedLeft++;
- } while ( pTempL = dsdKernelFindContainingComponent( pDsdMan, pTempL, bVarTop, &fPolarity ) );
-
- // go over the dec list of pH, and find the component that is marked and the previos one
- // (such component always exists, because they have common variables)
- while ( pCurH->Mark != s_Mark )
- {
- pPrevH = pCurH;
- pCurH = dsdKernelFindContainingComponent( pDsdMan, pCurH, bVarTop, &fPolarityCurH );
- assert( pCurH );
- }
-
- // go through the first list once again and find
- // the component proceeding the one marked found in the second list
- while ( pCurL != pCurH )
- {
- pPrevL = pCurL;
- pCurL = pMarkedLeft[index];
- fPolarityCurL = pMarkedPols[index];
- index++;
- }
-
- // look for the possibility to subtract more than one component
- if ( !pPrevL || !pPrevH || pPrevL->Type != pPrevH->Type || pPrevL->Type == DSD_NODE_PRIME || fPolarityCurL != fPolarityCurH )
- { // there is no way to extract more than one
- pThis->pDecs[ nEntries++ ] = pCurH;
- // assign the support to be subtracted from both components
- bSuppSubract = pCurH->S;
- }
- else
- {
- // find the equal components in two decomposition lists
- Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
- int nCommon = dsdKernelFindCommonComponents( pDsdMan, pPrevL, pPrevH, &pCommon, &pLastDiffL, &pLastDiffH );
-
- if ( nCommon == 0 || nCommon == 1 )
- { // one one component was found, which is the original one
- // assert( Dsd_Regular(pCommon[0]) == pCurL);
- // add the new decomposition entry
- pThis->pDecs[ nEntries++ ] = pCurL;
- // assign the support to be subtracted from both components
- bSuppSubract = pCurL->S;
- }
- else // more than one components was found
- {
- // find the OR (EXOR) of the non-overlapping components
- DdNode * bCommF;
- dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, NULL, (int)(pPrevL->Type==DSD_NODE_EXOR) );
- Cudd_Ref( bCommF );
-
- pDENew = dsdKernelDecompose_rec( pDsdMan, bCommF );
- assert( !Dsd_IsComplement(pDENew) ); // cannot be complemented because of construction
- Cudd_RecursiveDeref( dd, bCommF );
-
- // add the new decomposition entry
- pThis->pDecs[ nEntries++ ] = pDENew;
-
- // assign the support to be subtracted from both components
- bSuppSubract = pDENew->S;
- }
- }
-
- SuppL = Cudd_bddExistAbstract( dd, bTemp = SuppL, bSuppSubract ), Cudd_Ref( SuppL );
- Cudd_RecursiveDeref(dd, bTemp);
-
- SuppH = Cudd_bddExistAbstract( dd, bTemp = SuppH, bSuppSubract ), Cudd_Ref( SuppH );
- Cudd_RecursiveDeref(dd, bTemp);
-
- } // end of if ( fEqualLevel )
-
- } // end of decomposition list comparison
- Cudd_RecursiveDeref( dd, SuppL );
- Cudd_RecursiveDeref( dd, SuppH );
-
- }
-
- // check that the estimation of the number of entries was okay
- assert( nEntries <= nEntriesMax );
-
-// if ( nEntries != Extra_bddSuppSize(dd, bSuppNew) )
-// s_Case5++;
-
- // update the number of entries in the new decomposition list
- pThis->nDecs = nEntries;
- }
-//}
-EXIT:
-
- {
- // if the component created is complemented, it represents a function without complement
- // therefore, as it is, without complement, it should recieve the complemented function
- Dsd_Node_t * pThisR = Dsd_Regular( pThis );
- assert( pThisR->G == NULL );
- assert( pThisR->S == NULL );
-
- if ( pThisR == pThis ) // set regular function
- pThisR->G = bF;
- else // set complemented function
- pThisR->G = Cudd_Not(bF);
- Cudd_Ref(bF); // reference the function in the component
-
- assert( bSuppNew );
- pThisR->S = bSuppNew; // takes the reference from the new support
- if ( st_insert( pDsdMan->Table, (char*)bF, (char*)pThis ) )
- {
- assert( 0 );
- }
- s_CacheEntries++;
-
-
-/*
- if ( dsdKernelVerifyDecomposition(dd, pThis) == 0 )
- {
- // write the function, for which verification does not work
- cout << endl << "Internal verification failed!"" );
-
- // create the variable mask
- static int s_pVarMask[MAXINPUTS];
- int nInputCounter = 0;
-
- Cudd_SupportArray( dd, bF, s_pVarMask );
- int k;
- for ( k = 0; k < dd->size; k++ )
- if ( s_pVarMask[k] )
- nInputCounter++;
-
- cout << endl << "The problem function is "" );
-
- DdNode * zNewFunc = Cudd_zddIsopCover( dd, bF, bF ); Cudd_Ref( zNewFunc );
- cuddWriteFunctionSop( stdout, dd, zNewFunc, -1, dd->size, "1", s_pVarMask );
- Cudd_RecursiveDerefZdd( dd, zNewFunc );
- }
-*/
-
- }
-
- Depth--;
- return Dsd_NotCond( pThis, fCompF );
-}
-
-
-////////////////////////////////////////////////////////////////////////
-/// OTHER FUNCTIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Finds the corresponding decomposition entry.]
-
- Description [This function returns the non-complemented pointer to the
- DecEntry of that component which contains the given variable in its
- support, or NULL if no such component exists]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Dsd_Node_t * dsdKernelFindContainingComponent( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pWhere, DdNode * Var, int * fPolarity )
-
-{
- Dsd_Node_t * pTemp;
- int i;
-
-// assert( !Dsd_IsComplement( pWhere ) );
-// assert( Extra_bddSuppContainVar( pDsdMan->dd, pWhere->S, Var ) );
-
- if ( pWhere->nDecs == 1 )
- return NULL;
-
- for( i = 0; i < pWhere->nDecs; i++ )
- {
- pTemp = Dsd_Regular( pWhere->pDecs[i] );
- if ( Extra_bddSuppContainVar( pDsdMan->dd, pTemp->S, Var ) )
- {
- *fPolarity = (int)( pTemp != pWhere->pDecs[i] );
- return pTemp;
- }
- }
- assert( 0 );
- return NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis [Find the common decomposition components.]
-
- Description [This function determines the common components. It counts
- the number of common components in the decomposition lists of pL and pH
- and returns their number and the lists of common components. It assumes
- that pL and pH are regular pointers. It retuns also the pointers to the
- last different components encountered in pL and pH.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int dsdKernelFindCommonComponents( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pL, Dsd_Node_t * pH, Dsd_Node_t *** pCommon, Dsd_Node_t ** pLastDiffL, Dsd_Node_t ** pLastDiffH )
-{
- static Dsd_Node_t * Common[MAXINPUTS];
- int nCommon = 0;
-
- // pointers to the current decomposition entries
- Dsd_Node_t * pLcur;
- Dsd_Node_t * pHcur;
-
- // the pointers to their supports
- DdNode * bSLcur;
- DdNode * bSHcur;
-
- // the top variable in the supports
- int TopVar;
-
- // the indices running through the components
- int iCurL = 0;
- int iCurH = 0;
- while ( iCurL < pL->nDecs && iCurH < pH->nDecs )
- { // both did not run out
-
- pLcur = Dsd_Regular(pL->pDecs[iCurL]);
- pHcur = Dsd_Regular(pH->pDecs[iCurH]);
-
- bSLcur = pLcur->S;
- bSHcur = pHcur->S;
-
- // find out what component is higher in the BDD
- if ( pDsdMan->dd->perm[bSLcur->index] < pDsdMan->dd->perm[bSHcur->index] )
- TopVar = bSLcur->index;
- else
- TopVar = bSHcur->index;
-
- if ( TopVar == bSLcur->index && TopVar == bSHcur->index )
- {
- // the components may be equal - should match exactly!
- if ( pL->pDecs[iCurL] == pH->pDecs[iCurH] )
- Common[nCommon++] = pL->pDecs[iCurL];
- else
- {
- *pLastDiffL = pL->pDecs[iCurL];
- *pLastDiffH = pH->pDecs[iCurH];
- }
-
- // skip both
- iCurL++;
- iCurH++;
- }
- else if ( TopVar == bSLcur->index )
- { // the components cannot be equal
- // skip the top-most one
- *pLastDiffL = pL->pDecs[iCurL++];
- }
- else // if ( TopVar == bSHcur->index )
- { // the components cannot be equal
- // skip the top-most one
- *pLastDiffH = pH->pDecs[iCurH++];
- }
- }
-
- // if one of the lists still has components, write the first one down
- if ( iCurL < pL->nDecs )
- *pLastDiffL = pL->pDecs[iCurL];
-
- if ( iCurH < pH->nDecs )
- *pLastDiffH = pH->pDecs[iCurH];
-
- // return the pointer to the array
- *pCommon = Common;
- // return the number of common components
- return nCommon;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the sum (OR or EXOR) of the functions of the components.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void dsdKernelComputeSumOfComponents( Dsd_Manager_t * pDsdMan, Dsd_Node_t ** pCommon, int nCommon, DdNode ** pCompF, DdNode ** pCompS, int fExor )
-{
- DdManager * dd = pDsdMan->dd;
- DdNode * bF, * bS, * bFadd, * bTemp;
- Dsd_Node_t * pDE, * pDER;
- int i;
-
- // start the function
- bF = b0; Cudd_Ref( bF );
- // start the support
- if ( pCompS )
- bS = b1, Cudd_Ref( bS );
-
- assert( nCommon > 0 );
- for ( i = 0; i < nCommon; i++ )
- {
- pDE = pCommon[i];
- pDER = Dsd_Regular( pDE );
- bFadd = (pDE != pDER)? Cudd_Not(pDER->G): pDER->G;
- // add to the function
- if ( fExor )
- bF = Cudd_bddXor( dd, bTemp = bF, bFadd );
- else
- bF = Cudd_bddOr( dd, bTemp = bF, bFadd );
- Cudd_Ref( bF );
- Cudd_RecursiveDeref( dd, bTemp );
- if ( pCompS )
- {
- // add to the support
- bS = Cudd_bddAnd( dd, bTemp = bS, pDER->S ); Cudd_Ref( bS );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- }
- // return the function
- Cudd_Deref( bF );
- *pCompF = bF;
-
- // return the support
- if ( pCompS )
- Cudd_Deref( bS ), *pCompS = bS;
-}
-
-/**Function*************************************************************
-
- Synopsis [Checks support containment of the decomposition components.]
-
- Description [This function returns 1 if support of one component is contained
- in that of another. In this case, pLarge (pSmall) is assigned to point to the
- larger (smaller) support. If the supports are identical return 0, and does not
- assign the components.]
-]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int dsdKernelCheckContainment( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pL, Dsd_Node_t * pH, Dsd_Node_t ** pLarge, Dsd_Node_t ** pSmall )
-{
- DdManager * dd = pDsdMan->dd;
- DdNode * bSuppLarge, * bSuppSmall;
- int RetValue;
-
- RetValue = Extra_bddSuppCheckContainment( dd, pL->S, pH->S, &bSuppLarge, &bSuppSmall );
-
- if ( RetValue == 0 )
- return 0;
-
- if ( pH->S == bSuppLarge )
- {
- *pLarge = pH;
- *pSmall = pL;
- }
- else // if ( pL->S == bSuppLarge )
- {
- *pLarge = pL;
- *pSmall = pH;
- }
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Copies the list of components plus one.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void dsdKernelCopyListPlusOne( Dsd_Node_t * p, Dsd_Node_t * First, Dsd_Node_t ** ppList, int nListSize )
-{
- int i;
- assert( nListSize+1 == p->nDecs );
- p->pDecs[0] = First;
- for( i = 0; i < nListSize; i++ )
- p->pDecs[i+1] = ppList[i];
-}
-
-/**Function*************************************************************
-
- Synopsis [Copies the list of components plus one, and skips one.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void dsdKernelCopyListPlusOneMinusOne( Dsd_Node_t * p, Dsd_Node_t * First, Dsd_Node_t ** ppList, int nListSize, int iSkipped )
-{
- int i, Counter;
- assert( nListSize == p->nDecs );
- p->pDecs[0] = First;
- for( i = 0, Counter = 1; i < nListSize; i++ )
- if ( i != iSkipped )
- p->pDecs[Counter++] = ppList[i];
-}
-
-/**Function*************************************************************
-
- Synopsis [Debugging procedure to compute the functionality of the decomposed structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int dsdKernelVerifyDecomposition( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pDE )
-{
- DdManager * dd = pDsdMan->dd;
- Dsd_Node_t * pR = Dsd_Regular(pDE);
- int fCompP = (int)( pDE != pR );
- int RetValue;
-
- DdNode * bRes;
- if ( pR->Type == DSD_NODE_CONST1 )
- bRes = b1;
- else if ( pR->Type == DSD_NODE_BUF )
- bRes = pR->G;
- else if ( pR->Type == DSD_NODE_OR || pR->Type == DSD_NODE_EXOR )
- dsdKernelComputeSumOfComponents( pDsdMan, pR->pDecs, pR->nDecs, &bRes, NULL, (int)(pR->Type == DSD_NODE_EXOR) );
- else if ( pR->Type == DSD_NODE_PRIME )
- {
- int i;
- static DdNode * bGVars[MAXINPUTS];
- // transform the function of this block, so that it depended on inputs
- // corresponding to the formal inputs
- DdNode * bNewFunc = Dsd_TreeGetPrimeFunctionOld( dd, pR, 1 ); Cudd_Ref( bNewFunc );
-
- // compose this function with the inputs
- // create the elementary permutation
- for ( i = 0; i < dd->size; i++ )
- bGVars[i] = dd->vars[i];
-
- // assign functions to be composed
- for ( i = 0; i < pR->nDecs; i++ )
- bGVars[dd->invperm[i]] = pR->pDecs[i]->G;
-
- // perform the composition
- bRes = Cudd_bddVectorCompose( dd, bNewFunc, bGVars ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bNewFunc );
-
- /////////////////////////////////////////////////////////
- RetValue = (int)( bRes == pR->G );//|| bRes == Cudd_Not(pR->G) );
- /////////////////////////////////////////////////////////
- Cudd_Deref( bRes );
- }
- else
- {
- assert(0);
- }
-
- Cudd_Ref( bRes );
- RetValue = (int)( bRes == pR->G );//|| bRes == Cudd_Not(pR->G) );
- Cudd_RecursiveDeref( dd, bRes );
- return RetValue;
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////