diff options
Diffstat (limited to 'src')
263 files changed, 34538 insertions, 25549 deletions
diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index ddedb4e2..f667d4e3 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -33,6 +33,7 @@ #include <time.h> #include "vec.h" +#include "utilCex.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// diff --git a/src/aig/aig/aigCuts.c b/src/aig/aig/aigCuts.c index 6de19484..1bcf69ce 100644 --- a/src/aig/aig/aigCuts.c +++ b/src/aig/aig/aigCuts.c @@ -56,9 +56,7 @@ Aig_ManCut_t * Aig_ManCutStart( Aig_Man_t * pMan, int nCutsMax, int nLeafMax, in p->fTruth = fTruth; p->fVerbose = fVerbose; p->pAig = pMan; - // allocate room for cuts and equivalent nodes - p->pCuts = ABC_ALLOC( Aig_Cut_t *, Aig_ManObjNumMax(pMan) ); - memset( p->pCuts, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(pMan) ); + p->pCuts = ABC_CALLOC( Aig_Cut_t *, Aig_ManObjNumMax(pMan) ); // allocate memory manager p->nTruthWords = Aig_TruthWordNum(nLeafMax); p->nCutSize = sizeof(Aig_Cut_t) + sizeof(int) * nLeafMax + fTruth * sizeof(unsigned) * p->nTruthWords; diff --git a/src/aig/aig/aigDoms.c b/src/aig/aig/aigDoms.c index c12c0caa..e909ac41 100644 --- a/src/aig/aig/aigDoms.c +++ b/src/aig/aig/aigDoms.c @@ -44,6 +44,7 @@ struct Aig_Sto_t_ Aig_MmFixed_t * pMem; // memory manager for dominators Vec_Ptr_t * vDoms; // dominators Vec_Int_t * vFans; // temporary fanouts + Vec_Int_t * vTimes; // the number of times each appears int nDomNodes; // nodes with dominators int nDomsTotal; // total dominators int nDomsFilter1; // filtered dominators @@ -71,13 +72,13 @@ struct Aig_Sto_t_ Aig_Sto_t * Aig_ManDomStart( Aig_Man_t * pAig, int Limit ) { Aig_Sto_t * pSto; - assert( Aig_ManRegNum(pAig) > 0 ); pSto = ABC_CALLOC( Aig_Sto_t, 1 ); pSto->pAig = pAig; pSto->Limit = Limit; pSto->pMem = Aig_MmFixedStart( sizeof(Aig_Dom_t) + sizeof(int) * Limit, 10000 ); pSto->vDoms = Vec_PtrStart( Aig_ManObjNumMax(pAig) ); pSto->vFans = Vec_IntAlloc( 100 ); + pSto->vTimes = Vec_IntStart( Aig_ManObjNumMax(pAig) ); return pSto; } @@ -233,6 +234,7 @@ void Aig_ManDomStop( Aig_Sto_t * pSto ) Aig_ObjDomVecRecycle( pSto, vDoms ); Vec_PtrFree( pSto->vDoms ); Vec_IntFree( pSto->vFans ); + Vec_IntFree( pSto->vTimes ); Aig_MmFixedStop( pSto->pMem, 0 ); ABC_FREE( pSto ); } @@ -547,11 +549,11 @@ void Aig_ObjDomCompute( Aig_Sto_t * pSto, Aig_Obj_t * pObj ) Vec_IntPush( pSto->vFans, iFanout>>1 ); if ( Vec_IntSize(pSto->vFans) == 0 ) return; - vDoms0 = Vec_PtrEntry( pSto->vDoms, Vec_IntEntry(pSto->vFans, 0) ); + vDoms0 = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, Vec_IntEntry(pSto->vFans, 0) ); vDoms2 = Aig_ObjDomVecDup( pSto, vDoms0, 0 ); Vec_IntForEachEntryStart( pSto->vFans, iFanout, i, 1 ) { - vDoms1 = Vec_PtrEntry( pSto->vDoms, iFanout ); + vDoms1 = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, iFanout ); vDoms2 = Aig_ObjDomMerge( pSto, vDomsT = vDoms2, vDoms1 ); Aig_ObjDomVecRecycle( pSto, vDomsT ); } @@ -616,7 +618,7 @@ void Aig_ManMarkFlopTfi( Aig_Man_t * p ) SeeAlso [] ***********************************************************************/ -Aig_Sto_t * Aig_ManComputeDoms( Aig_Man_t * pAig, int Limit ) +Aig_Sto_t * Aig_ManComputeDomsFlops( Aig_Man_t * pAig, int Limit ) { Aig_Sto_t * pSto; Vec_Ptr_t * vNodes; @@ -636,7 +638,6 @@ Aig_Sto_t * Aig_ManComputeDoms( Aig_Man_t * pAig, int Limit ) // compute combinational inputs Aig_ManForEachPi( pAig, pObj, i ) Aig_ObjDomCompute( pSto, pObj ); - // print statistics printf( "Nodes =%4d. Flops =%4d. Doms =%9d. Ave =%8.2f. ", pSto->nDomNodes, Aig_ManRegNum(pSto->pAig), pSto->nDomsTotal, @@ -649,6 +650,44 @@ Aig_Sto_t * Aig_ManComputeDoms( Aig_Man_t * pAig, int Limit ) /**Function************************************************************* + Synopsis [Computes multi-node dominators.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Sto_t * Aig_ManComputeDomsNodes( Aig_Man_t * pAig, int Limit ) +{ + Aig_Sto_t * pSto; + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i, clk = clock(); + pSto = Aig_ManDomStart( pAig, Limit ); + // initialize flop inputs + Aig_ManForEachPo( pAig, pObj, i ) + Aig_ObjAddTriv( pSto, pObj->Id, Vec_PtrAlloc(1) ); + // compute internal nodes + vNodes = Aig_ManDfsReverse( pAig ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + Aig_ObjDomCompute( pSto, pObj ); + Vec_PtrFree( vNodes ); + // compute combinational inputs + Aig_ManForEachPi( pAig, pObj, i ) + Aig_ObjDomCompute( pSto, pObj ); + // print statistics + printf( "Nodes =%6d. Doms =%9d. Ave =%8.2f. ", + pSto->nDomNodes, pSto->nDomsTotal, +// pSto->nDomsFilter1, pSto->nDomsFilter2, + 1.0 * pSto->nDomsTotal / pSto->nDomNodes ); + Abc_PrintTime( 1, "Time", clock() - clk ); + return pSto; +} + +/**Function************************************************************* + Synopsis [Collects dominators from the cut.] Description [] @@ -662,11 +701,11 @@ Vec_Ptr_t * Aig_ObjDomCollect( Aig_Sto_t * pSto, Vec_Int_t * vCut ) { Vec_Ptr_t * vDoms0, * vDoms1, * vDoms2; int i, ObjId; - vDoms0 = Vec_PtrEntry( pSto->vDoms, Vec_IntEntry(vCut, 0) ); + vDoms0 = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, Vec_IntEntry(vCut, 0) ); vDoms2 = Aig_ObjDomVecDup( pSto, vDoms0, 1 ); Vec_IntForEachEntryStart( vCut, ObjId, i, 1 ) { - vDoms1 = Vec_PtrEntry( pSto->vDoms, ObjId ); + vDoms1 = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, ObjId ); if ( vDoms1 == NULL ) continue; Aig_ObjDomUnion( pSto, vDoms2, vDoms1 ); @@ -941,7 +980,7 @@ void Aig_ManComputeDomsTest( Aig_Man_t * pAig, int Num ) // for ( i = 1; i < 9; i++ ) { printf( "ITERATION %d:\n", Num ); - pSto = Aig_ManComputeDoms( pAig, Num ); + pSto = Aig_ManComputeDomsFlops( pAig, Num ); Aig_ObjDomFindGood( pSto ); // Aig_ManDomPrint( pSto ); Aig_ManDomStop( pSto ); @@ -950,6 +989,99 @@ void Aig_ManComputeDomsTest( Aig_Man_t * pAig, int Num ) } + + + +/**Function************************************************************* + + Synopsis [Collects dominators from the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjDomCount( Aig_Sto_t * pSto, Aig_Obj_t * pObj ) +{ + Aig_Dom_t * pDom; + Aig_Obj_t * pFanout; + Vec_Int_t * vSingles; + Vec_Ptr_t * vDoms; + int i, k, Entry, iFanout, fPrint = 0; + vSingles = Vec_IntAlloc( 100 ); + // for each dominator of a fanout, count how many fanouts have it as a dominator + Aig_ObjForEachFanout( pSto->pAig, pObj, pFanout, iFanout, i ) + { + vDoms = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, Aig_ObjId(pFanout) ); + Vec_PtrForEachEntryStart( Aig_Dom_t *, vDoms, pDom, k, 1 ) + { +// printf( "Fanout %d Dominator %d\n", Aig_ObjId(pFanout), pDom->pNodes[0] ); + Vec_IntAddToEntry( pSto->vTimes, pDom->pNodes[0], 1 ); + Vec_IntPushUnique( vSingles, pDom->pNodes[0] ); + } + } + // clear storage + Vec_IntForEachEntry( vSingles, Entry, i ) + { + if ( Vec_IntEntry(pSto->vTimes, Entry) > 5 ) + { + if ( fPrint == 0 ) + { + printf( "%6d : Level =%4d. Fanout =%6d.\n", + Aig_ObjId(pObj), Aig_ObjLevel(pObj), Aig_ObjRefs(pObj) ); + } + fPrint = 1; + printf( "%d(%d) ", Entry, Vec_IntEntry(pSto->vTimes, Entry) ); + } + Vec_IntWriteEntry( pSto->vTimes, Entry, 0); + } + if ( fPrint ) + printf( "\n" ); + Vec_IntFree( vSingles ); +} + + +/**Function************************************************************* + + Synopsis [Computes multi-node dominators.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManComputeDomsForCofactoring( Aig_Man_t * pAig ) +{ + Vec_Ptr_t * vDoms; + Aig_Sto_t * pSto; + Aig_Obj_t * pObj; + int i; + Aig_ManFanoutStart( pAig ); + pSto = Aig_ManComputeDomsNodes( pAig, 1 ); + Aig_ManForEachObj( pAig, pObj, i ) + { + if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) ) + continue; + if ( Aig_ObjRefs(pObj) < 10 ) + continue; + vDoms = (Vec_Ptr_t *)Vec_PtrEntry( pSto->vDoms, Aig_ObjId(pObj) ); +// printf( "%6d : Level =%4d. Fanout =%6d.\n", +// Aig_ObjId(pObj), Aig_ObjLevel(pObj), Aig_ObjRefs(pObj) ); + + Aig_ObjDomCount( pSto, pObj ); + } + Aig_ManDomStop( pSto ); + Aig_ManFanoutStop( pAig ); +} + + + + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/bbr/bbrCex.c b/src/aig/bbr/bbrCex.c index 8f99ea3c..4a1a1d67 100644 --- a/src/aig/bbr/bbrCex.c +++ b/src/aig/bbr/bbrCex.c @@ -19,7 +19,6 @@ ***********************************************************************/ #include "bbr.h" -#include "ssw.h" ABC_NAMESPACE_IMPL_START @@ -60,7 +59,7 @@ Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, //printf( "\nDeriving counter-example.\n" ); // allocate room for the counter-example - pCex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(p), Saig_ManPiNum(p), Vec_PtrSize(vOnionRings)+1 ); + pCex = Abc_CexAlloc( Saig_ManRegNum(p), Saig_ManPiNum(p), Vec_PtrSize(vOnionRings)+1 ); pCex->iFrame = Vec_PtrSize(vOnionRings); pCex->iPo = iOutput; nPiOffset = Saig_ManRegNum(p) + Saig_ManPiNum(p) * Vec_PtrSize(vOnionRings); @@ -153,7 +152,7 @@ Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, // verify the counter example if ( Vec_PtrSize(vOnionRings) < 1000 ) { - RetValue = Ssw_SmlRunCounterExample( p, pCex ); + RetValue = Saig_ManVerifyCex( p, pCex ); if ( RetValue == 0 && !fSilent ) printf( "Aig_ManVerifyUsingBdds(): Counter-example verification has FAILED.\n" ); } diff --git a/src/aig/bbr/bbrReach.c b/src/aig/bbr/bbrReach.c index c2433d45..ef355992 100644 --- a/src/aig/bbr/bbrReach.c +++ b/src/aig/bbr/bbrReach.c @@ -19,7 +19,6 @@ ***********************************************************************/ #include "bbr.h" -#include "ssw.h" ABC_NAMESPACE_IMPL_START @@ -568,7 +567,7 @@ int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, Saig_ParBbr_t * pPars ) else Vec_IntPush( vInputMap, -1 ); // create new pattern - pCexNew = Ssw_SmlAllocCounterExample( Saig_ManRegNum(pInit), Saig_ManPiNum(pInit), pCexOld->iFrame+1 ); + pCexNew = Abc_CexAlloc( Saig_ManRegNum(pInit), Saig_ManPiNum(pInit), pCexOld->iFrame+1 ); pCexNew->iFrame = pCexOld->iFrame; pCexNew->iPo = pCexOld->iPo; // copy the bit-data diff --git a/src/aig/cec/cecCec.c b/src/aig/cec/cecCec.c index 0859a9ad..9fd8a03f 100644 --- a/src/aig/cec/cecCec.c +++ b/src/aig/cec/cecCec.c @@ -164,7 +164,7 @@ int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars ) { if ( p->pCexComb != NULL ) { - if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + if ( p->pCexComb && !Gia_ManVerifyCex( p, p->pCexComb, 1 ) ) Abc_Print( 1, "Counter-example simulation has failed.\n" ); Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); Abc_PrintTime( 1, "Time", clock() - clk ); @@ -220,7 +220,7 @@ int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars ) fflush( stdout ); RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose, &pPars->iOutFail ); p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL; - if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + if ( p->pCexComb && !Gia_ManVerifyCex( p, p->pCexComb, 1 ) ) Abc_Print( 1, "Counter-example simulation has failed.\n" ); Gia_ManStop( pNew ); return RetValue; diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index 5e71dbff..369c4a40 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -436,9 +436,12 @@ p->timeSat += clock() - clk; // update the manager pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDualOut ); - Gia_ManStop( pTemp ); if ( p->pAig == NULL ) + { + p->pAig = pTemp; break; + } + Gia_ManStop( pTemp ); if ( p->pPars->fVerbose ) { Abc_Print( 1, "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", diff --git a/src/aig/cec/cecSeq.c b/src/aig/cec/cecSeq.c index b91e8523..0e49cd7c 100644 --- a/src/aig/cec/cecSeq.c +++ b/src/aig/cec/cecSeq.c @@ -242,7 +242,7 @@ int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex Vec_PtrFree( vSimInfo ); if ( pPars->fVerbose ) ABC_PRT( "Time", clock() - clkTotal ); - if ( RetValue ) + if ( RetValue && pPars->fCheckMiter ) Abc_Print( 1, "Cec_ManSeqResimulateCounter(): An output of the miter is asserted!\n" ); return RetValue; } @@ -338,7 +338,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) } Gia_ManRandom( 1 ); // prepare starting pattern - pState = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), 0, 0 ); + pState = Abc_CexAlloc( Gia_ManRegNum(pAig), 0, 0 ); pState->iFrame = -1; pState->iPo = -1; // prepare SAT solving @@ -359,7 +359,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) Abc_Print( 1, "Cec_ManSeqSemiformal: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); break; } -// Gia_ManPrintCounterExample( pState ); +// Abc_CexPrint( pState ); // derive speculatively reduced model // pSrm = Gia_ManSpecReduceInit( pAig, pState, pPars->nFrames, pPars->fDualOut ); pSrm = Gia_ManSpecReduceInitFrames( pAig, pState, pPars->nFrames, &nFramesReal, pPars->fDualOut, pPars->nMinOutputs ); @@ -393,7 +393,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) // write equivalence classes Gia_WriteAiger( pAig, "gore.aig", 0, 0 ); // reduce the model - pReduce = Gia_ManSpecReduce( pAig, 0, 0, 0 ); + pReduce = Gia_ManSpecReduce( pAig, 0, 0, 1, 0, 0 ); if ( pReduce ) { pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); diff --git a/src/aig/fra/fra.h b/src/aig/fra/fra.h index aee38d08..a0073ca1 100644 --- a/src/aig/fra/fra.h +++ b/src/aig/fra/fra.h @@ -376,12 +376,6 @@ extern Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int extern Fra_Sml_t * Fra_SmlSimulateComb( Aig_Man_t * pAig, int nWords ); extern Abc_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ); extern Abc_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); -extern void Fra_SmlFreeCounterExample( Abc_Cex_t * p ); -extern Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); -extern int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); -extern int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Abc_Cex_t * p ); -extern Abc_Cex_t * Fra_SmlSimpleCounterExample( Aig_Man_t * pAig, int * pModel, int iFrame, int iPo ); - ABC_NAMESPACE_HEADER_END diff --git a/src/aig/fra/fraBmc.c b/src/aig/fra/fraBmc.c index ae9e4bc5..3907fcdd 100644 --- a/src/aig/fra/fraBmc.c +++ b/src/aig/fra/fraBmc.c @@ -417,7 +417,7 @@ void Fra_BmcPerformSimple( Aig_Man_t * pAig, int nFrames, int nBTLimit, int fRew clk = clock(); iOutput = Fra_FraigMiterAssertedOutput( pBmc->pAigFrames ); if ( iOutput >= 0 ) - pAig->pSeqModel = Fra_SmlTrivCounterExample( pAig, iOutput ); + pAig->pSeqModel = Abc_CexMakeTriv( Aig_ManRegNum(pAig), Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig), Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig), iOutput ); else { pBmc->pAigFraig = Fra_FraigEquivence( pBmc->pAigFrames, nBTLimit, 1 ); @@ -428,7 +428,7 @@ void Fra_BmcPerformSimple( Aig_Man_t * pAig, int nFrames, int nBTLimit, int fRew ABC_FREE( pBmc->pAigFraig->pData ); } else if ( iOutput >= 0 ) - pAig->pSeqModel = Fra_SmlTrivCounterExample( pAig, iOutput ); + pAig->pSeqModel = Abc_CexMakeTriv( Aig_ManRegNum(pAig), Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig), Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig), iOutput ); } if ( fVerbose ) { diff --git a/src/aig/fra/fraSec.c b/src/aig/fra/fraSec.c index 7608791f..4b893cb2 100644 --- a/src/aig/fra/fraSec.c +++ b/src/aig/fra/fraSec.c @@ -203,14 +203,14 @@ clk = clock(); if ( pTemp->pSeqModel ) { - if ( !Ssw_SmlRunCounterExample( pTemp, pTemp->pSeqModel ) ) + if ( !Saig_ManVerifyCex( pTemp, pTemp->pSeqModel ) ) printf( "Fra_FraigSec(): Counter-example verification has FAILED.\n" ); if ( Saig_ManPiNum(p) != Saig_ManPiNum(pTemp) ) printf( "The counter-example is invalid because of phase abstraction.\n" ); else { ABC_FREE( p->pSeqModel ); - p->pSeqModel = Ssw_SmlDupCounterExample( pTemp->pSeqModel, Aig_ManRegNum(p) ); + p->pSeqModel = Abc_CexDup( pTemp->pSeqModel, Aig_ManRegNum(p) ); ABC_FREE( pTemp->pSeqModel ); } } @@ -443,7 +443,7 @@ ABC_PRT( "Time", clock() - clk ); else { ABC_FREE( p->pSeqModel ); - p->pSeqModel = Ssw_SmlDupCounterExample( pNew->pSeqModel, Aig_ManRegNum(p) ); + p->pSeqModel = Abc_CexDup( pNew->pSeqModel, Aig_ManRegNum(p) ); ABC_FREE( pNew->pSeqModel ); } @@ -505,7 +505,7 @@ clk = clock(); RetValue = Inter_ManPerformInterpolation( pTemp, pPars, &Depth ); if ( pTemp->pSeqModel ) { - pCex = p->pSeqModel = Ssw_SmlDupCounterExample( pTemp->pSeqModel, Aig_ManRegNum(p) ); + pCex = p->pSeqModel = Abc_CexDup( pTemp->pSeqModel, Aig_ManRegNum(p) ); pCex->iPo = i; Aig_ManStop( pTemp ); break; @@ -548,7 +548,7 @@ clk = clock(); { Abc_Cex_t * pCex; pCex = pNew->pSeqModel = pNewOrpos->pSeqModel; pNewOrpos->pSeqModel = NULL; - pCex->iPo = Ssw_SmlFindOutputCounterExample( pNew, pNew->pSeqModel ); + pCex->iPo = Saig_ManFindFailedPoCex( pNew, pNew->pSeqModel ); } Aig_ManStop( pNewOrpos ); } @@ -598,7 +598,7 @@ ABC_PRT( "Time", clock() - clk ); printf( "Running property directed reachability...\n" ); RetValue = Pdr_ManSolve( pNewOrpos, pPars, &pCex ); if ( pCex ) - pCex->iPo = Ssw_SmlFindOutputCounterExample( pNew, pCex ); + pCex->iPo = Saig_ManFindFailedPoCex( pNew, pCex ); Aig_ManStop( pNewOrpos ); pNew->pSeqModel = pCex; } @@ -665,7 +665,7 @@ ABC_PRT( "Time", clock() - clkTotal ); else { ABC_FREE( p->pSeqModel ); - p->pSeqModel = Ssw_SmlDupCounterExample( pNew->pSeqModel, Aig_ManRegNum(p) ); + p->pSeqModel = Abc_CexDup( pNew->pSeqModel, Aig_ManRegNum(p) ); ABC_FREE( pNew->pSeqModel ); } } diff --git a/src/aig/fra/fraSim.c b/src/aig/fra/fraSim.c index 25c30989..37620a16 100644 --- a/src/aig/fra/fraSim.c +++ b/src/aig/fra/fraSim.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "fra.h" +#include "saig.h" ABC_NAMESPACE_IMPL_START @@ -879,45 +880,6 @@ Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nW /**Function************************************************************* - Synopsis [Allocates a counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Fra_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) -{ - Abc_Cex_t * pCex; - int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - pCex->nRegs = nRegs; - pCex->nPis = nRealPis; - pCex->nBits = nRegs + nRealPis * nFrames; - return pCex; -} - -/**Function************************************************************* - - Synopsis [Frees the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fra_SmlFreeCounterExample( Abc_Cex_t * pCex ) -{ - ABC_FREE( pCex ); -} - -/**Function************************************************************* - Synopsis [Creates sequential counter-example from the simulation info.] Description [] @@ -960,7 +922,7 @@ Abc_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ) assert( iBit < 32 * p->nWordsFrame ); // allocate the counter example - pCex = Fra_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 ); + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 ); pCex->iPo = iPo; pCex->iFrame = iFrame; @@ -981,10 +943,10 @@ Abc_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ) } } // verify the counter example - if ( !Fra_SmlRunCounterExample( p->pAig, pCex ) ) + if ( !Saig_ManVerifyCex( p->pAig, pCex ) ) { printf( "Fra_SmlGetCounterExample(): Counter-example is invalid.\n" ); - Fra_SmlFreeCounterExample( pCex ); + Abc_CexFree( pCex ); pCex = NULL; } return pCex; @@ -1026,7 +988,7 @@ Abc_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, in } assert( iPo >= 0 ); // allocate the counter example - pCex = Fra_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); + pCex = Abc_CexAlloc( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); pCex->iPo = iPo; pCex->iFrame = iFrame; @@ -1040,186 +1002,16 @@ Abc_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, in } // verify the counter example - if ( !Fra_SmlRunCounterExample( pAig, pCex ) ) + if ( !Saig_ManVerifyCex( pAig, pCex ) ) { printf( "Fra_SmlGetCounterExample(): Counter-example is invalid.\n" ); - Fra_SmlFreeCounterExample( pCex ); + Abc_CexFree( pCex ); pCex = NULL; } return pCex; } -/**Function************************************************************* - - Synopsis [Make the trivial counter-example for the trivially asserted output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) -{ - Abc_Cex_t * pCex; - int nTruePis, nTruePos, iPo, iFrame; - assert( Aig_ManRegNum(pAig) > 0 ); - nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); - nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig); - iPo = iFrameOut % nTruePos; - iFrame = iFrameOut / nTruePos; - // allocate the counter example - pCex = Fra_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); - pCex->iPo = iPo; - pCex->iFrame = iFrame; - return pCex; -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) -{ - Fra_Sml_t * pSml; - Aig_Obj_t * pObj; - int RetValue, i, k, iBit; - assert( Aig_ManRegNum(pAig) > 0 ); - assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); - // start a new sequential simulator - pSml = Fra_SmlStart( pAig, 0, p->iFrame+1, 1 ); - // assign simulation info for the registers - iBit = 0; - Aig_ManForEachLoSeq( pAig, pObj, i ) - Fra_SmlAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); - // assign simulation info for the primary inputs - for ( i = 0; i <= p->iFrame; i++ ) - Aig_ManForEachPiSeq( pAig, pObj, k ) - Fra_SmlAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); - assert( iBit == p->nBits ); - // run random simulation - Fra_SmlSimulateOne( pSml ); - // check if the given output has failed - RetValue = !Fra_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) ); - Fra_SmlStop( pSml ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Make the trivial counter-example for the trivially asserted output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Fra_SmlSimpleCounterExample( Aig_Man_t * pAig, int * pModel, int iFrame, int iPo ) -{ - Abc_Cex_t * pCex; - int iBit; - pCex = Fra_SmlAllocCounterExample( Aig_ManRegNum(pAig), Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig), iFrame + 1 ); - pCex->iPo = iPo; - pCex->iFrame = iFrame; - for ( iBit = Aig_ManRegNum(pAig); iBit < pCex->nBits; iBit++ ) - if ( pModel[iBit-Aig_ManRegNum(pAig)] ) - Aig_InfoSetBit( pCex->pData, iBit ); -/* - if ( !Fra_SmlRunCounterExample( pAig, pCex ) ) - { - printf( "Fra_SmlSimpleCounterExample(): Counter-example is invalid.\n" ); -// Fra_SmlFreeCounterExample( pCex ); -// pCex = NULL; - } -*/ - return pCex; -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Abc_Cex_t * p ) -{ - Fra_Sml_t * pSml; - Aig_Obj_t * pObj; - int RetValue, i, k, iBit; - unsigned * pSims; - assert( Aig_ManRegNum(pAig) > 0 ); - assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); - // start a new sequential simulator - pSml = Fra_SmlStart( pAig, 0, p->iFrame+1, 1 ); - // assign simulation info for the registers - iBit = 0; - Aig_ManForEachLoSeq( pAig, pObj, i ) -// Fra_SmlAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); - Fra_SmlAssignConst( pSml, pObj, 0, 0 ); - // assign simulation info for the primary inputs - iBit = p->nRegs; - for ( i = 0; i <= p->iFrame; i++ ) - Aig_ManForEachPiSeq( pAig, pObj, k ) - Fra_SmlAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); - assert( iBit == p->nBits ); - // run random simulation - Fra_SmlSimulateOne( pSml ); - // check if the given output has failed - RetValue = !Fra_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) ); - - // write the output file - for ( i = 0; i <= p->iFrame; i++ ) - { -/* - Aig_ManForEachLoSeq( pAig, pObj, k ) - { - pSims = Fra_ObjSim(pSml, pObj->Id); - fprintf( pFile, "%d", (int)(pSims[i] != 0) ); - } - fprintf( pFile, " " ); -*/ - Aig_ManForEachPiSeq( pAig, pObj, k ) - { - pSims = Fra_ObjSim(pSml, pObj->Id); - fprintf( pFile, "%d", (int)(pSims[i] != 0) ); - } -/* - fprintf( pFile, " " ); - Aig_ManForEachPoSeq( pAig, pObj, k ) - { - pSims = Fra_ObjSim(pSml, pObj->Id); - fprintf( pFile, "%d", (int)(pSims[i] != 0) ); - } - fprintf( pFile, " " ); - Aig_ManForEachLiSeq( pAig, pObj, k ) - { - pSims = Fra_ObjSim(pSml, pObj->Id); - fprintf( pFile, "%d", (int)(pSims[i] != 0) ); - } -*/ - fprintf( pFile, "\n" ); - } - - Fra_SmlStop( pSml ); - return RetValue; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/fsim/fsimSim.c b/src/aig/fsim/fsimSim.c index 2da7db15..56aeab2f 100644 --- a/src/aig/fsim/fsimSim.c +++ b/src/aig/fsim/fsimSim.c @@ -434,7 +434,7 @@ Abc_Cex_t * Fsim_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; - p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); + p = Abc_CexAlloc( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); p->iFrame = iFrame; p->iPo = iOut; // fill in the binary data diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index e3546686..4059153d 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -33,6 +33,7 @@ #include <time.h> #include "vec.h" +#include "utilCex.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -295,8 +296,8 @@ static inline Gia_Obj_t * Gia_ManCi( Gia_Man_t * p, int v ) { return Gia_ManO static inline Gia_Obj_t * Gia_ManCo( Gia_Man_t * p, int v ) { return Gia_ManObj( p, Vec_IntEntry(p->vCos,v) ); } static inline Gia_Obj_t * Gia_ManPi( Gia_Man_t * p, int v ) { assert( v < Gia_ManPiNum(p) ); return Gia_ManCi( p, v ); } static inline Gia_Obj_t * Gia_ManPo( Gia_Man_t * p, int v ) { assert( v < Gia_ManPoNum(p) ); return Gia_ManCo( p, v ); } -static inline Gia_Obj_t * Gia_ManRo( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCi( p, Gia_ManRegNum(p)+v ); } -static inline Gia_Obj_t * Gia_ManRi( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCo( p, Gia_ManRegNum(p)+v ); } +static inline Gia_Obj_t * Gia_ManRo( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCi( p, Gia_ManPiNum(p)+v ); } +static inline Gia_Obj_t * Gia_ManRi( Gia_Man_t * p, int v ) { assert( v < Gia_ManRegNum(p) ); return Gia_ManCo( p, Gia_ManPoNum(p)+v ); } static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; } static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; } @@ -658,7 +659,7 @@ extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose ); extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ); extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ); -extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ); +extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fReduce, int fSkipSome, int fVerbose ); extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut ); extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ); extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ); @@ -788,17 +789,13 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ); extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode ); extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ); extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); -extern Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); -extern Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ); -extern Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ); -extern Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ); -extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ); -extern void Gia_ManPrintCounterExample( Abc_Cex_t * p ); extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_ManHasChoices( Gia_Man_t * p ); extern int Gia_ManHasDangling( Gia_Man_t * p ); extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ); extern void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ); +extern int Gia_ManVerifyCex( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ); +extern int Gia_ManFindFailedPoCex( Gia_Man_t * pAig, Abc_Cex_t * p ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit ); @@ -808,8 +805,6 @@ extern void Tas_ManSatPrintStats( Tas_Man_t * p ); extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ); extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs ); - - ABC_NAMESPACE_HEADER_END diff --git a/src/aig/gia/giaAbs.c b/src/aig/gia/giaAbs.c index 38e010f1..d31e62f5 100644 --- a/src/aig/gia/giaAbs.c +++ b/src/aig/gia/giaAbs.c @@ -36,7 +36,7 @@ ABC_NAMESPACE_IMPL_START extern Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); extern Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); -extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ); +extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fTryFour, int fSensePath, int fVerbose ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -253,7 +253,7 @@ Gia_Man_t * Gia_ManCexAbstractionDerive( Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbose ) +int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fTryFour, int fSensePath, int fVerbose ) { Aig_Man_t * pNew; Vec_Int_t * vFlops; @@ -264,7 +264,7 @@ int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbos } pNew = Gia_ManToAig( pGia, 0 ); vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); - if ( !Saig_ManCexRefineStep( pNew, vFlops, pCex, fVerbose ) ) + if ( !Saig_ManCexRefineStep( pNew, vFlops, pCex, fTryFour, fSensePath, fVerbose ) ) { pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; Vec_IntFree( vFlops ); @@ -530,8 +530,8 @@ void Gia_ManCexAbstractionStartNew( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) { printf( "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 ); Abc_PrintTime( 1, "Time", clk ); - pGia->pCexSeq = Gia_ManDeriveCexFromArray( pGia, vCex, 0, nFrames-1 ); - if ( !Gia_ManVerifyCounterExample( pGia, pGia->pCexSeq, 0 ) ) + pGia->pCexSeq = Abc_CexCreate( Gia_ManRegNum(pGia), Gia_ManPiNum(pGia), Vec_IntArray(vCex), nFrames-1, 0, 0 ); + if ( !Gia_ManVerifyCex( pGia, pGia->pCexSeq, 0 ) ) Abc_Print( 1, "Generated counter-example is INVALID.\n" ); pPars->Status = 0; } diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 4ded9a78..71204548 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -416,7 +416,7 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p ) } Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); if ( p->pCexSeq ) - pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); + pNew->pCexSeq = Abc_CexDup( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } @@ -764,7 +764,7 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); if ( p->pCexSeq ) - pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); + pNew->pCexSeq = Abc_CexDup( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 581383ea..383d4e8d 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -748,7 +748,7 @@ int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ) SeeAlso [] ***********************************************************************/ -static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut ) +static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut, int fSpeculate, Vec_Int_t * vTrace, Vec_Int_t * vGuide ) { Gia_Obj_t * pRepr; unsigned iLitNew; @@ -760,8 +760,19 @@ static inline void Gia_ManSpecBuild( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t return; iLitNew = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); if ( pObj->Value != iLitNew && !Gia_ObjProved(p, Gia_ObjId(p,pObj)) ) - Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); - pObj->Value = iLitNew; + { + if ( vTrace ) + Vec_IntPush( vTrace, 1 ); + if ( vGuide == NULL || Vec_IntEntry( vGuide, Vec_IntSize(vTrace)-1 ) ) + Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, pObj->Value, iLitNew) ); + } + else + { + if ( vTrace ) + Vec_IntPush( vTrace, 0 ); + } + if ( fSpeculate ) + pObj->Value = iLitNew; } /**Function************************************************************* @@ -798,15 +809,15 @@ int Gia_ManHasNoEquivs( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut ) +void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXorLits, int fDualOut, int fSpeculate, Vec_Int_t * vTrace, Vec_Int_t * vGuide ) { if ( ~pObj->Value ) return; assert( Gia_ObjIsAnd(pObj) ); - Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut ); - Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits, fDualOut ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut, fSpeculate, vTrace, vGuide ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), vXorLits, fDualOut, fSpeculate, vTrace, vGuide ); pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); - Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut ); + Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut, fSpeculate, vTrace, vGuide ); } /**Function************************************************************* @@ -820,36 +831,86 @@ void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, V SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ) +Gia_Man_t * Gia_ManSpecReduceTrace( Gia_Man_t * p, Vec_Int_t * vTrace ) { + Vec_Int_t * vXorLits; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; - Vec_Int_t * vXorLits; int i, iLitNew; if ( !p->pReprs ) { printf( "Gia_ManSpecReduce(): Equivalence classes are not available.\n" ); return NULL; } - if ( fDualOut && (Gia_ManPoNum(p) & 1) ) + Vec_IntClear( vTrace ); + vXorLits = Vec_IntAlloc( 1000 ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachRo( p, pObj, i ) + Gia_ManSpecBuild( pNew, p, pObj, vXorLits, 0, 1, vTrace, NULL ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, 0, 1, vTrace, NULL ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntForEachEntry( vXorLits, iLitNew, i ) + Gia_ManAppendCo( pNew, iLitNew ); + if ( Vec_IntSize(vXorLits) == 0 ) { - printf( "Gia_ManSpecReduce(): Dual-output miter should have even number of POs.\n" ); - return NULL; + printf( "Speculatively reduced model has no primary outputs.\n" ); + Gia_ManAppendCo( pNew, 0 ); } -/* - if ( Gia_ManHasNoEquivs(p) ) + Gia_ManForEachRi( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Vec_IntFree( vXorLits ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fSpeculate, int fSkipSome, int fVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + Vec_Int_t * vXorLits; + int i, iLitNew; + Vec_Int_t * vTrace = NULL, * vGuide = NULL; + if ( !p->pReprs ) { - printf( "Gia_ManSpecReduce(): There are no equivalences to reduce.\n" ); + printf( "Gia_ManSpecReduce(): Equivalence classes are not available.\n" ); return NULL; } -*/ -/* - if ( !Gia_ManCheckTopoOrder( p ) ) + if ( fDualOut && (Gia_ManPoNum(p) & 1) ) { - printf( "Gia_ManSpecReduce(): AIG is not in a correct topological order.\n" ); + printf( "Gia_ManSpecReduce(): Dual-output miter should have even number of POs.\n" ); return NULL; } -*/ + if ( fSkipSome ) + { + vGuide = Vec_IntAlloc( 100 ); + pTemp = Gia_ManSpecReduceTrace( p, vGuide ); + Gia_ManStop( pTemp ); + assert( Vec_IntSize(vGuide) == Gia_ManEquivCountLitsAll(p) ); + vTrace = Vec_IntAlloc( 100 ); + } vXorLits = Vec_IntAlloc( 1000 ); Gia_ManSetPhase( p ); Gia_ManFillValue( p ); @@ -862,9 +923,9 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); Gia_ManForEachRo( p, pObj, i ) - Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut ); + Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut, fSpeculate, vTrace, vGuide ); Gia_ManForEachCo( p, pObj, i ) - Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut ); + Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut, fSpeculate, vTrace, vGuide ); if ( !fSynthesis ) { Gia_ManForEachPo( p, pObj, i ) @@ -884,6 +945,20 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); + + // update using trace + if ( fSkipSome ) + { + // count the number of non-zero entries + int iLit, nAddPos = 0; + Vec_IntForEachEntry( vGuide, iLit, i ) + if ( iLit ) + nAddPos++; + if ( nAddPos ) + assert( Gia_ManPoNum(pNew) == Gia_ManPoNum(p) + nAddPos ); + } + Vec_IntFreeP( &vTrace ); + Vec_IntFreeP( &vGuide ); return pNew; } @@ -1127,6 +1202,104 @@ void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ) /**Function************************************************************* + Synopsis [Marks proved equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivMark( Gia_Man_t * p, char * pFileName, int fSkipSome, int fVerbose ) +{ + Gia_Man_t * pMiter, * pTemp; + Gia_Obj_t * pObj; + int i, iLit, nAddPos, nLits = 0; + int nLitsAll, Counter = 0; + nLitsAll = Gia_ManEquivCountLitsAll( p ); + if ( nLitsAll == 0 ) + { + printf( "Gia_ManEquivMark(): Current AIG does not have equivalences.\n" ); + return; + } + // read AIGER file + pMiter = Gia_ReadAiger( pFileName, 0 ); + if ( pMiter == NULL ) + { + printf( "Gia_ManEquivMark(): Input file %s could not be read.\n", pFileName ); + return; + } + if ( fSkipSome ) + { + Vec_Int_t * vTrace = Vec_IntAlloc( 100 ); + pTemp = Gia_ManSpecReduceTrace( p, vTrace ); + Gia_ManStop( pTemp ); + assert( Vec_IntSize(vTrace) == nLitsAll ); + // count the number of non-zero entries + nAddPos = 0; + Vec_IntForEachEntry( vTrace, iLit, i ) + if ( iLit ) + nAddPos++; + // check the number + if ( Gia_ManPoNum(pMiter) != Gia_ManPoNum(p) + nAddPos ) + { + printf( "Gia_ManEquivMark(): The number of POs is not correct: MiterPONum(%d) != AIGPONum(%d) + AIGFilteredEquivNum(%d).\n", + Gia_ManPoNum(pMiter), Gia_ManPoNum(p), nAddPos ); + Gia_ManStop( pMiter ); + Vec_IntFreeP( &vTrace ); + return; + } + // mark corresponding POs as solved + nLits = iLit = Counter = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjRepr(p, i) == GIA_VOID ) + continue; + if ( Vec_IntEntry( vTrace, nLits++ ) == 0 ) + continue; + pObj = Gia_ManPo( pMiter, Gia_ManPoNum(p) + iLit++ ); + if ( Gia_ObjFaninLit0p(pMiter, pObj) == 0 ) // const 0 - proven + { + Gia_ObjSetProved(p, i); + Counter++; + } + } + assert( nLits == nLitsAll ); + assert( iLit == nAddPos ); + Vec_IntFreeP( &vTrace ); + } + else + { + if ( Gia_ManPoNum(pMiter) != Gia_ManPoNum(p) + nLitsAll ) + { + printf( "Gia_ManEquivMark(): The number of POs is not correct: MiterPONum(%d) != AIGPONum(%d) + AIGEquivNum(%d).\n", + Gia_ManPoNum(pMiter), Gia_ManPoNum(p), nLitsAll ); + Gia_ManStop( pMiter ); + return; + } + // mark corresponding POs as solved + nLits = 0; + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjRepr(p, i) == GIA_VOID ) + continue; + pObj = Gia_ManPo( pMiter, Gia_ManPoNum(p) + nLits++ ); + if ( Gia_ObjFaninLit0p(pMiter, pObj) == 0 ) // const 0 - proven + { + Gia_ObjSetProved(p, i); + Counter++; + } + } + assert( nLits == nLitsAll ); + } + if ( fVerbose ) + printf( "Set %d equivalences as proved.\n", Counter ); + Gia_ManStop( pMiter ); +} + +/**Function************************************************************* + Synopsis [Transforms equiv classes by setting a good representative.] Description [] @@ -1534,7 +1707,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f printf( "Gia_CommandSpecI: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); break; } - pSrm = Gia_ManSpecReduce( pGia, 0, 0, 0 ); + pSrm = Gia_ManSpecReduce( pGia, 0, 0, 1, 0, 0 ); // bmc2 -F 100 -C 25000 { Abc_Cex_t * pCex; @@ -1571,7 +1744,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f // write equivalence classes Gia_WriteAiger( pGia, "gore.aig", 0, 0 ); // reduce the model - pReduce = Gia_ManSpecReduce( pGia, 0, 0, 0 ); + pReduce = Gia_ManSpecReduce( pGia, 0, 0, 1, 0, 0 ); if ( pReduce ) { pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); diff --git a/src/aig/gia/giaEra2.c b/src/aig/gia/giaEra2.c index 64464832..dedbc032 100644 --- a/src/aig/gia/giaEra2.c +++ b/src/aig/gia/giaEra2.c @@ -1758,7 +1758,7 @@ int Gia_ManArePerform( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbos // verify if ( pAig->pCexSeq ) { - if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) + if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) ) printf( "Generated counter-example is INVALID. \n" ); else printf( "Generated counter-example verified correctly. \n" ); @@ -1922,7 +1922,7 @@ Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast ) Vec_PtrPush( vStates, pSta ); assert( Vec_PtrSize(vStates) >= 1 ); // start the counter-example - pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(p->pAig), Gia_ManPiNum(p->pAig), Vec_PtrSize(vStates) ); + pCex = Abc_CexAlloc( Gia_ManRegNum(p->pAig), Gia_ManPiNum(p->pAig), Vec_PtrSize(vStates) ); pCex->iFrame = Vec_PtrSize(vStates)-1; pCex->iPo = p->iOutFail; // compute states diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index 1de1a2d4..18e02d81 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -436,7 +436,7 @@ Abc_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; - p = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); + p = Abc_CexAlloc( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); p->iFrame = iFrame; p->iPo = iOut; // fill in the binary data @@ -513,7 +513,7 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) pPars->iOutFail = iOut; pAig->pCexSeq = Gia_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids ); Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d was asserted in frame %d. ", iOut, i ); - if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) + if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) ) { // Abc_Print( 1, "\n" ); Abc_Print( 1, "\nGenerated counter-example is INVALID. " ); diff --git a/src/aig/gia/giaSim2.c b/src/aig/gia/giaSim2.c index 4131f942..e1a5aa07 100644 --- a/src/aig/gia/giaSim2.c +++ b/src/aig/gia/giaSim2.c @@ -606,7 +606,7 @@ Abc_Cex_t * Gia_Sim2GenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int Abc_Cex_t * p; unsigned * pData; int f, i, w, Counter; - p = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); + p = Abc_CexAlloc( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); p->iFrame = iFrame; p->iPo = iOut; // fill in the binary data @@ -663,7 +663,7 @@ int Gia_ManSimSimulateEquiv( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) pPars->iOutFail = iOut; pAig->pCexSeq = Gia_Sim2GenerateCounter( pAig, i, iOut, p->nWords, iPat ); Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d was asserted in frame %d. ", iOut, i ); - if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) + if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) ) { // Abc_Print( 1, "\n" ); Abc_Print( 1, "\nGenerated counter-example is INVALID. " ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 82bdb367..2794956a 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -829,244 +829,6 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob /**Function************************************************************* - Synopsis [Allocates a counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) -{ - Abc_Cex_t * pCex; - int nWords = Gia_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - pCex->nRegs = nRegs; - pCex->nPis = nRealPis; - pCex->nBits = nRegs + nRealPis * nFrames; - return pCex; -} - - -/**Function************************************************************* - - Synopsis [Prints the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManPrintCex( Abc_Cex_t * p ) -{ - int i, f, k; - for ( k = 0; k < p->nRegs; k++ ) - printf( "%d", Gia_InfoHasBit(p->pData, k) ); - printf( "\n" ); - for ( f = 0; f <= p->iFrame; f++ ) - { - for ( i = 0; i < p->nPis; i++ ) - printf( "%d", Gia_InfoHasBit(p->pData, k++) ); - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Derives the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ) -{ - Abc_Cex_t * pCex; - int i; - pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); - assert( Vec_IntSize(vValues) == nSkip + pCex->nBits ); - pCex->iPo = 0; - pCex->iFrame = iFrame; - for ( i = 0; i < pCex->nBits; i++ ) - if ( Vec_IntEntry(vValues, nSkip + i) ) - Gia_InfoSetBit( pCex->pData, i ); - return pCex; -} - -/**Function************************************************************* - - Synopsis [Allocates a counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ) -{ - Abc_Cex_t * pCex; - int i; - pCex = Gia_ManAllocCounterExample( nRegs, nRealPis, 1 ); - pCex->iPo = iPo; - pCex->iFrame = 0; - for ( i = pCex->nRegs; i < pCex->nBits; i++ ) - if ( pModel[i-pCex->nRegs] ) - Gia_InfoSetBit( pCex->pData, i ); - return pCex; -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ) -{ - Gia_Obj_t * pObj, * pObjRi, * pObjRo; - int RetValue, i, k, iBit = 0; - Gia_ManCleanMark0(pAig); - Gia_ManForEachRo( pAig, pObj, i ) - pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); - for ( i = 0; i <= p->iFrame; i++ ) - { - Gia_ManForEachPi( pAig, pObj, k ) - pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); - Gia_ManForEachAnd( pAig, pObj, k ) - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - Gia_ManForEachCo( pAig, pObj, k ) - pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); - if ( i == p->iFrame ) - break; - Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) - { - pObjRo->fMark0 = pObjRi->fMark0; - } - } - assert( iBit == p->nBits ); - if ( fDualOut ) - RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0; - else - RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; - Gia_ManCleanMark0(pAig); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManVerifyCounterExampleAllOuts( Gia_Man_t * pAig, Abc_Cex_t * p ) -{ - Gia_Obj_t * pObj, * pObjRi, * pObjRo; - int RetValue, i, k, iBit = 0; - Gia_ManCleanMark0(pAig); - Gia_ManForEachRo( pAig, pObj, i ) - pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); - for ( i = 0; i <= p->iFrame; i++ ) - { - Gia_ManForEachPi( pAig, pObj, k ) - pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); - Gia_ManForEachAnd( pAig, pObj, k ) - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - Gia_ManForEachCo( pAig, pObj, k ) - pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); - Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) - pObjRo->fMark0 = pObjRi->fMark0; - } - assert( iBit == p->nBits ); - // remember the number of failed output - RetValue = -1; - Gia_ManForEachPo( pAig, pObj, i ) - if ( Gia_ManPo(pAig, i)->fMark0 ) - { - RetValue = i; - break; - } - Gia_ManCleanMark0(pAig); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Make the trivial counter-example for the trivially asserted output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ) -{ - Abc_Cex_t * pCex; - int i; - pCex = Gia_ManAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); - pCex->iPo = p->iPo; - pCex->iFrame = p->iFrame; - for ( i = p->nRegs; i < p->nBits; i++ ) - if ( Gia_InfoHasBit(p->pData, i) ) - Gia_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); - return pCex; -} - -/**Function************************************************************* - - Synopsis [Prints out the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManPrintCounterExample( Abc_Cex_t * p ) -{ - int i, f, k; - printf( "Counter-example: iPo = %d iFrame = %d nRegs = %d nPis = %d nBits = %d\n", - p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits ); - printf( "State : " ); - for ( k = 0; k < p->nRegs; k++ ) - printf( "%d", Gia_InfoHasBit(p->pData, k) ); - printf( "\n" ); - for ( f = 0; f <= p->iFrame; f++ ) - { - printf( "Frame %2d : ", f ); - for ( i = 0; i < p->nPis; i++ ) - printf( "%d", Gia_InfoHasBit(p->pData, k++) ); - printf( "\n" ); - } - assert( k == p->nBits ); -} - -/**Function************************************************************* - Synopsis [Dereferences the node's MFFC.] Description [] @@ -1371,6 +1133,91 @@ void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ) */ } +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManVerifyCex( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + if ( i == p->iFrame ) + break; + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + { + pObjRo->fMark0 = pObjRi->fMark0; + } + } + assert( iBit == p->nBits ); + if ( fDualOut ) + RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0; + else + RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; + Gia_ManCleanMark0(pAig); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManFindFailedPoCex( Gia_Man_t * pAig, Abc_Cex_t * p ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + // remember the number of failed output + RetValue = -1; + Gia_ManForEachPo( pAig, pObj, i ) + if ( Gia_ManPo(pAig, i)->fMark0 ) + { + RetValue = i; + break; + } + Gia_ManCleanMark0(pAig); + return RetValue; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/int/intCheck.c b/src/aig/int/intCheck.c new file mode 100644 index 00000000..564813f4 --- /dev/null +++ b/src/aig/int/intCheck.c @@ -0,0 +1,301 @@ +/**CFile**************************************************************** + + FileName [intCheck.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Interpolation engine.] + + Synopsis [Procedures to perform incremental inductive check.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 24, 2008.] + + Revision [$Id: intCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "intInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// checking manager +struct Inter_Check_t_ +{ + int nFramesK; // the number of timeframes (K=1 for simple induction) + int nVars; // the current number of variables in the solver + Aig_Man_t * pFrames; // unrolled timeframes + Cnf_Dat_t * pCnf; // CNF of unrolled timeframes + sat_solver * pSat; // SAT solver + Vec_Int_t * vOrLits; // OR vars in each time frame (total number is the number nFrames) + Vec_Int_t * vAndLits; // AND vars in the last timeframe (total number is the number of interpolants) + Vec_Int_t * vAssLits; // assumptions (the union of the two) +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Create timeframes of the manager for interpolation.] + + Description [The resulting manager is combinational. The primary inputs + corresponding to register outputs are ordered first.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Inter_ManUnrollFrames( Aig_Man_t * pAig, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f; + assert( Saig_ManRegNum(pAig) > 0 ); + pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); + // create variables for register outputs + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + // create PI nodes for this frame + Saig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // save register inputs + Saig_ManForEachLi( pAig, pObj, i ) + pObj->pData = Aig_ObjChild0Copy(pObj); + // transfer to register outputs + Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) + { + pObjLo->pData = pObjLi->pData; + Aig_ObjCreatePo( pFrames, pObjLo->pData ); + } + } + Aig_ManCleanup( pFrames ); + return pFrames; +} + +/**Function************************************************************* + + Synopsis [This procedure sets default values of interpolation parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Inter_Check_t * Inter_CheckStart( Aig_Man_t * pTrans, int nFramesK ) +{ + Inter_Check_t * p; + // create solver + p = ABC_CALLOC( Inter_Check_t, 1 ); + p->vOrLits = Vec_IntAlloc( 100 ); + p->vAndLits = Vec_IntAlloc( 100 ); + p->vAssLits = Vec_IntAlloc( 100 ); + // generate the timeframes + p->pFrames = Inter_ManUnrollFrames( pTrans, nFramesK ); + assert( Aig_ManPiNum(p->pFrames) == nFramesK * Saig_ManPiNum(pTrans) + Saig_ManRegNum(pTrans) ); + assert( Aig_ManPoNum(p->pFrames) == nFramesK * Saig_ManRegNum(pTrans) ); + // convert to CNF + p->pCnf = Cnf_Derive( p->pFrames, Aig_ManPoNum(p->pFrames) ); + p->pSat = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); + // assign parameters + p->nFramesK = nFramesK; + p->nVars = p->pCnf->nVars; + return p; +} + +/**Function************************************************************* + + Synopsis [This procedure sets default values of interpolation parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Inter_CheckStop( Inter_Check_t * p ) +{ + if ( p == NULL ) + return; + Vec_IntFree( p->vOrLits ); + Vec_IntFree( p->vAndLits ); + Vec_IntFree( p->vAssLits ); + Cnf_DataFree( p->pCnf ); + Aig_ManStop( p->pFrames ); + sat_solver_delete( p->pSat ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Creates one OR-gate: A + B = C.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Inter_CheckAddOrGate( Inter_Check_t * p, int iVarA, int iVarB, int iVarC ) +{ + int RetValue, pLits[3]; + // add A => C or !A + C + pLits[0] = toLitCond(iVarA, 1); + pLits[1] = toLitCond(iVarC, 0); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); + // add B => C or !B + C + pLits[0] = toLitCond(iVarB, 1); + pLits[1] = toLitCond(iVarC, 0); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); + // add !A & !B => !C or A + B + !C + pLits[0] = toLitCond(iVarA, 0); + pLits[1] = toLitCond(iVarB, 0); + pLits[2] = toLitCond(iVarC, 1); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); + assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Creates equality: A = B.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Inter_CheckAddEqual( Inter_Check_t * p, int iVarA, int iVarB ) +{ + int RetValue, pLits[3]; + // add A => B or !A + B + pLits[0] = toLitCond(iVarA, 1); + pLits[1] = toLitCond(iVarB, 0); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); + // add B => A or !B + A + pLits[0] = toLitCond(iVarB, 1); + pLits[1] = toLitCond(iVarA, 0); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Perform the checking.] + + Description [Returns 1 if the check has passed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Inter_CheckPerform( Inter_Check_t * p, Cnf_Dat_t * pCnfInt ) +{ + Aig_Obj_t * pObj, * pObj2; + int i, f, VarA, VarB, RetValue, Entry, status; + int nRegs = Aig_ManPiNum(pCnfInt->pMan); + assert( Aig_ManPoNum(p->pCnf->pMan) == p->nFramesK * nRegs ); + assert( Aig_ManPoNum(pCnfInt->pMan) == 1 ); + + // add clauses to the SAT solver + Cnf_DataLift( pCnfInt, p->nVars ); + for ( f = 0; f <= p->nFramesK; f++ ) + { + // add clauses to the solver + for ( i = 0; i < pCnfInt->nClauses; i++ ) + { + RetValue = sat_solver_addclause( p->pSat, pCnfInt->pClauses[i], pCnfInt->pClauses[i+1] ); + assert( RetValue ); + } + // add equality clauses for the flop variables + Aig_ManForEachPi( pCnfInt->pMan, pObj, i ) + { + pObj2 = f ? Aig_ManPo(p->pFrames, i + (f-1) * nRegs) : Aig_ManPi(p->pFrames, i); + Inter_CheckAddEqual( p, pCnfInt->pVarNums[pObj->Id], p->pCnf->pVarNums[pObj2->Id] ); + } + // add final clauses + if ( f < p->nFramesK ) + { + if ( f == Vec_IntSize(p->vOrLits) ) // find time here + { + // add literal to this frame + VarB = pCnfInt->pVarNums[ Aig_ManPo(pCnfInt->pMan, 0)->Id ]; + Vec_IntPush( p->vOrLits, VarB ); + } + else + { + // add OR gate for this frame + VarA = Vec_IntEntry( p->vOrLits, f ); + VarB = pCnfInt->pVarNums[ Aig_ManPo(pCnfInt->pMan, 0)->Id ]; + Inter_CheckAddOrGate( p, VarA, VarB, p->nVars + pCnfInt->nVars ); + Vec_IntWriteEntry( p->vOrLits, f, p->nVars + pCnfInt->nVars ); // using var ID! + } + } + else + { + // add AND gate for this frame + VarB = pCnfInt->pVarNums[ Aig_ManPo(pCnfInt->pMan, 0)->Id ]; + Vec_IntPush( p->vAndLits, VarB ); + } + // update variable IDs + Cnf_DataLift( pCnfInt, pCnfInt->nVars + 1 ); + p->nVars += pCnfInt->nVars + 1; + } + Cnf_DataLift( pCnfInt, -p->nVars ); + assert( Vec_IntSize(p->vOrLits) == p->nFramesK ); + + // collect the assumption literals + Vec_IntClear( p->vAssLits ); + Vec_IntForEachEntry( p->vOrLits, Entry, i ) + Vec_IntPush( p->vAssLits, toLitCond(Entry, 0) ); + Vec_IntForEachEntry( p->vAndLits, Entry, i ) + Vec_IntPush( p->vAssLits, toLitCond(Entry, 1) ); +/* + if ( pCnfInt->nLiterals == 3635 ) + { + int s = 0; + } +*/ + // call the SAT solver + status = sat_solver_solve( p->pSat, Vec_IntArray(p->vAssLits), + Vec_IntArray(p->vAssLits) + Vec_IntSize(p->vAssLits), + (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + + return status == l_False; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intCore.c b/src/aig/int/intCore.c index c0df48fb..646c83e1 100644 --- a/src/aig/int/intCore.c +++ b/src/aig/int/intCore.c @@ -50,7 +50,7 @@ void Inter_ManSetDefaultParams( Inter_ManParams_t * p ) p->nSecLimit = 0; // time limit in seconds p->nFramesK = 1; // the number of timeframes to use in induction p->fRewrite = 0; // use additional rewriting to simplify timeframes - p->fTransLoop = 1; // add transition into the init state under new PI var + p->fTransLoop = 0; // add transition into the init state under new PI var p->fUsePudlak = 0; // use Pudluk interpolation procedure p->fUseOther = 0; // use other undisclosed option p->fUseMiniSat = 0; // use MiniSat-1.14p instead of internal proof engine @@ -78,6 +78,7 @@ int Inter_ManPerformInterpolation( Aig_Man_t * pAig, Inter_ManParams_t * pPars, { extern int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward ); Inter_Man_t * p; + Inter_Check_t * pCheck = NULL; Aig_Man_t * pAigTemp; int s, i, RetValue, Status, clk, clk2, clkTotal = clock(); // sanity checks @@ -116,12 +117,14 @@ p->timeCnf += clock() - clk; Aig_ManAndNum(pAig), Aig_ManLevelNum(pAig), p->pCnfAig->nVars, p->pCnfAig->nClauses ); } - + // derive interpolant *piFrame = -1; p->nFrames = 1; for ( s = 0; ; s++ ) { + Cnf_Dat_t * pCnfInter2; + clk2 = clock(); // initial state if ( pPars->fUseBackward ) @@ -157,6 +160,23 @@ p->timeCnf += clock() - clk; s+1, p->nFrames, Aig_ManNodeNum(p->pFrames), Aig_ManLevelNum(p->pFrames) ); ABC_PRT( "Time", clock() - clk2 ); } + + + ////////////////////////////////////////// + // start containment checking + if ( !(pPars->fTransLoop || pPars->fUseBackward) ) + { + pCheck = Inter_CheckStart( p->pAigTrans, pPars->nFramesK ); + // try new containment check for the initial state +clk = clock(); + pCnfInter2 = Cnf_Derive( p->pInter, 1 ); +p->timeCnf += clock() - clk; + RetValue = Inter_CheckPerform( pCheck, pCnfInter2 ); +// assert( RetValue == 0 ); + Cnf_DataFree( pCnfInter2 ); + } + ////////////////////////////////////////// + // iterate the interpolation procedure for ( i = 0; ; i++ ) { @@ -166,6 +186,7 @@ p->timeCnf += clock() - clk; printf( "Reached limit (%d) on the number of timeframes.\n", pPars->nFramesMax ); p->timeTotal = clock() - clkTotal; Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return -1; } @@ -199,6 +220,7 @@ p->timeCnf += clock() - clk; *piFrame = p->nFrames; pAig->pSeqModel = (Abc_Cex_t *)Inter_ManGetCounterExample( pAig, p->nFrames+1, pPars->fVerbose ); Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return 0; } // likely spurious counter-example @@ -213,6 +235,7 @@ p->timeCnf += clock() - clk; assert( p->nConfCur >= p->nConfLimit ); p->timeTotal = clock() - clkTotal; Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return -1; } assert( RetValue == 1 ); // found new interpolant @@ -234,6 +257,7 @@ p->timeRwr += clock() - clk; printf( "The problem is trivially true for all states.\n" ); p->timeTotal = clock() - clkTotal; Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return 1; } @@ -242,7 +266,18 @@ clk = clock(); if ( pPars->fCheckKstep ) // k-step unique-state induction { if ( Aig_ManPiNum(p->pInterNew) == Aig_ManPiNum(p->pInter) ) - Status = Inter_ManCheckInductiveContainment( p->pAigTrans, p->pInterNew, pPars->nFramesK, pPars->fUseBackward ); + { + if ( pPars->fTransLoop || pPars->fUseBackward ) + Status = Inter_ManCheckInductiveContainment( p->pAigTrans, p->pInterNew, pPars->nFramesK, pPars->fUseBackward ); + else + { // new containment check +clk2 = clock(); + pCnfInter2 = Cnf_Derive( p->pInterNew, 1 ); +p->timeCnf += clock() - clk2; + Status = Inter_CheckPerform( pCheck, pCnfInter2 ); + Cnf_DataFree( pCnfInter2 ); + } + } else Status = 0; } @@ -260,6 +295,7 @@ p->timeEqu += clock() - clk; printf( "Proved containment of interpolants.\n" ); p->timeTotal = clock() - clkTotal; Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return 1; } if ( pPars->nSecLimit && ((float)pPars->nSecLimit <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) @@ -267,6 +303,7 @@ p->timeEqu += clock() - clk; printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); p->timeTotal = clock() - clkTotal; Inter_ManStop( p ); + Inter_CheckStop( pCheck ); return -1; } // save interpolant and convert it into CNF @@ -277,14 +314,22 @@ p->timeEqu += clock() - clk; } else { - p->pInter = Aig_ManCreateMiter( pAigTemp = p->pInter, p->pInterNew, 2 ); - Aig_ManStop( pAigTemp ); - Aig_ManStop( p->pInterNew ); - // compress the interpolant + if ( pPars->fUseBackward ) + { + p->pInter = Aig_ManCreateMiter( pAigTemp = p->pInter, p->pInterNew, 2 ); + Aig_ManStop( pAigTemp ); + Aig_ManStop( p->pInterNew ); + // compress the interpolant clk = clock(); - p->pInter = Dar_ManRwsat( pAigTemp = p->pInter, 1, 0 ); - Aig_ManStop( pAigTemp ); + p->pInter = Dar_ManRwsat( pAigTemp = p->pInter, 1, 0 ); + Aig_ManStop( pAigTemp ); p->timeRwr += clock() - clk; + } + else // forward with the new containment checking (using only the frontier) + { + Aig_ManStop( p->pInter ); + p->pInter = p->pInterNew; + } } p->pInterNew = NULL; Cnf_DataFree( p->pCnfInter ); @@ -292,6 +337,9 @@ clk = clock(); p->pCnfInter = Cnf_Derive( p->pInter, 0 ); p->timeCnf += clock() - clk; } + + // start containment checking + Inter_CheckStop( pCheck ); } assert( 0 ); return RetValue; diff --git a/src/aig/int/intCtrex.c b/src/aig/int/intCtrex.c index 28b1e293..0aa60040 100644 --- a/src/aig/int/intCtrex.c +++ b/src/aig/int/intCtrex.c @@ -133,7 +133,7 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) if ( status == l_True ) { int i, * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); - pCtrex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(pAig), Saig_ManPiNum(pAig), nFrames ); + pCtrex = Abc_CexAlloc( Saig_ManRegNum(pAig), Saig_ManPiNum(pAig), nFrames ); pCtrex->iFrame = nFrames - 1; pCtrex->iPo = 0; for ( i = 0; i < Vec_IntSize(vCiIds); i++ ) @@ -145,7 +145,7 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) sat_solver_delete( pSat ); Vec_IntFree( vCiIds ); // verify counter-example - status = Ssw_SmlRunCounterExample( pAig, pCtrex ); + status = Saig_ManVerifyCex( pAig, pCtrex ); if ( status == 0 ) printf( "Inter_ManGetCounterExample(): Counter-example verification has FAILED.\n" ); // report the results diff --git a/src/aig/int/intInt.h b/src/aig/int/intInt.h index 72079a49..d5e8ed00 100644 --- a/src/aig/int/intInt.h +++ b/src/aig/int/intInt.h @@ -79,6 +79,9 @@ struct Inter_Man_t_ int timeTotal; }; +// containment checking manager +typedef struct Inter_Check_t_ Inter_Check_t; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -87,38 +90,43 @@ struct Inter_Man_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== intContain.c ==========================================================*/ -extern int Inter_ManCheckContainment( Aig_Man_t * pNew, Aig_Man_t * pOld ); -extern int Inter_ManCheckEquivalence( Aig_Man_t * pNew, Aig_Man_t * pOld ); -extern int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward ); +/*=== intCheck.c ============================================================*/ +extern Inter_Check_t * Inter_CheckStart( Aig_Man_t * pTrans, int nFramesK ); +extern void Inter_CheckStop( Inter_Check_t * p ); +extern int Inter_CheckPerform( Inter_Check_t * p, Cnf_Dat_t * pCnf ); + +/*=== intContain.c ============================================================*/ +extern int Inter_ManCheckContainment( Aig_Man_t * pNew, Aig_Man_t * pOld ); +extern int Inter_ManCheckEquivalence( Aig_Man_t * pNew, Aig_Man_t * pOld ); +extern int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward ); -/*=== intCtrex.c ==========================================================*/ -extern void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ); +/*=== intCtrex.c ============================================================*/ +extern void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ); -/*=== intDup.c ==========================================================*/ -extern Aig_Man_t * Inter_ManStartInitState( int nRegs ); -extern Aig_Man_t * Inter_ManStartDuplicated( Aig_Man_t * p ); -extern Aig_Man_t * Inter_ManStartOneOutput( Aig_Man_t * p, int fAddFirstPo ); +/*=== intDup.c ============================================================*/ +extern Aig_Man_t * Inter_ManStartInitState( int nRegs ); +extern Aig_Man_t * Inter_ManStartDuplicated( Aig_Man_t * p ); +extern Aig_Man_t * Inter_ManStartOneOutput( Aig_Man_t * p, int fAddFirstPo ); -/*=== intFrames.c ==========================================================*/ -extern Aig_Man_t * Inter_ManFramesInter( Aig_Man_t * pAig, int nFrames, int fAddRegOuts ); +/*=== intFrames.c ============================================================*/ +extern Aig_Man_t * Inter_ManFramesInter( Aig_Man_t * pAig, int nFrames, int fAddRegOuts ); -/*=== intMan.c ==========================================================*/ -extern Inter_Man_t * Inter_ManCreate( Aig_Man_t * pAig, Inter_ManParams_t * pPars ); -extern void Inter_ManClean( Inter_Man_t * p ); -extern void Inter_ManStop( Inter_Man_t * p ); +/*=== intMan.c ============================================================*/ +extern Inter_Man_t * Inter_ManCreate( Aig_Man_t * pAig, Inter_ManParams_t * pPars ); +extern void Inter_ManClean( Inter_Man_t * p ); +extern void Inter_ManStop( Inter_Man_t * p ); -/*=== intM114.c ==========================================================*/ -extern int Inter_ManPerformOneStep( Inter_Man_t * p, int fUseBias, int fUseBackward ); +/*=== intM114.c ============================================================*/ +extern int Inter_ManPerformOneStep( Inter_Man_t * p, int fUseBias, int fUseBackward ); -/*=== intM114p.c ==========================================================*/ +/*=== intM114p.c ============================================================*/ #ifdef ABC_USE_LIBRARIES -extern int Inter_ManPerformOneStepM114p( Inter_Man_t * p, int fUsePudlak, int fUseOther ); +extern int Inter_ManPerformOneStepM114p( Inter_Man_t * p, int fUsePudlak, int fUseOther ); #endif -/*=== intUtil.c ==========================================================*/ -extern int Inter_ManCheckInitialState( Aig_Man_t * p ); -extern int Inter_ManCheckAllStates( Aig_Man_t * p ); +/*=== intUtil.c ============================================================*/ +extern int Inter_ManCheckInitialState( Aig_Man_t * p ); +extern int Inter_ManCheckAllStates( Aig_Man_t * p ); diff --git a/src/aig/int/module.make b/src/aig/int/module.make index cf0f827f..8e0e4319 100644 --- a/src/aig/int/module.make +++ b/src/aig/int/module.make @@ -1,4 +1,5 @@ -SRC += src/aig/int/intContain.c \ +SRC += src/aig/int/intCheck.c \ + src/aig/int/intContain.c \ src/aig/int/intCore.c \ src/aig/int/intCtrex.c \ src/aig/int/intDup.c \ diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c index 77b64700..87209ca3 100644 --- a/src/aig/ivy/ivyFraig.c +++ b/src/aig/ivy/ivyFraig.c @@ -200,6 +200,7 @@ static void Ivy_FraigMiterPrint( Ivy_Man_t * pNtk, char * pString, int static int * Ivy_FraigCreateModel( Ivy_FraigMan_t * p ); static int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ); +static int Ivy_FraigCheckCone( Ivy_FraigMan_t * pGlo, Ivy_Man_t * p, Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2, int nConfLimit ); static ABC_INT64_T s_nBTLimitGlobal = 0; static ABC_INT64_T s_nInsLimitGlobal = 0; @@ -356,7 +357,7 @@ int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars ) return -1; } } - +/* if ( RetValue < 0 ) { if ( pParams->fVerbose ) @@ -385,7 +386,7 @@ int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars ) exit(1); } } - +*/ // assign the model if it was proved by rewriting (const 1 miter) if ( RetValue == 0 && pManAig->pData == NULL ) { @@ -593,10 +594,10 @@ Ivy_FraigMan_t * Ivy_FraigStart( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParam } assert( k == Ivy_ManObjNum(pManAig) ); // allocate storage for sim pattern - p->nPatWords = Ivy_BitWordNum( Ivy_ManPiNum(pManAig) ); - p->pPatWords = ABC_ALLOC( unsigned, p->nPatWords ); + p->nPatWords = Ivy_BitWordNum( Ivy_ManPiNum(pManAig) ); + p->pPatWords = ABC_ALLOC( unsigned, p->nPatWords ); p->pPatScores = ABC_ALLOC( int, 32 * p->nSimWords ); - p->vPiVars = Vec_PtrAlloc( 100 ); + p->vPiVars = Vec_PtrAlloc( 100 ); // set random number generator srand( 0xABCABC ); return p; @@ -1992,6 +1993,7 @@ p->nClassesEnd = p->lClasses.nItems; if ( Ivy_ObjFaninVec(pObj) ) Vec_PtrFree( Ivy_ObjFaninVec(pObj) ); pObj->pNextFan0 = pObj->pNextFan1 = NULL; + pObj->pEquiv = NULL; } // remove dangling nodes Ivy_ManCleanup( p->pManFraig ); @@ -2154,6 +2156,14 @@ p->timeSatSat += clock() - clk; else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; +/* + if ( nBTLimit > 1000 ) + { + RetValue = Ivy_FraigCheckCone( p, p->pManFraig, pOld, pNew, nBTLimit ); + if ( RetValue != -1 ) + return RetValue; + } +*/ // mark the node as the failed node if ( pOld != p->pManFraig->pConst1 ) pOld->fFailTfo = 1; @@ -2197,6 +2207,14 @@ p->timeSatSat += clock() - clk; else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; +/* + if ( nBTLimit > 1000 ) + { + RetValue = Ivy_FraigCheckCone( p, p->pManFraig, pOld, pNew, nBTLimit ); + if ( RetValue != -1 ) + return RetValue; + } +*/ // mark the node as the failed node pOld->fFailTfo = 1; pNew->fFailTfo = 1; @@ -2286,6 +2304,14 @@ p->timeSatSat += clock() - clk; else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; +/* + if ( p->pParams->nBTLimitMiter > 1000 ) + { + RetValue = Ivy_FraigCheckCone( p, p->pManFraig, p->pManFraig->pConst1, pNew, p->pParams->nBTLimitMiter ); + if ( RetValue != -1 ) + return RetValue; + } +*/ // mark the node as the failed node pNew->fFailTfo = 1; p->nSatFailsReal++; @@ -2773,6 +2799,150 @@ int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ) return RetValue; } +ABC_NAMESPACE_IMPL_END + +#include "aig.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FraigExtractCone_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ) +{ + if ( pNode->fMarkB ) + return; + pNode->fMarkB = 1; + if ( Ivy_ObjIsPi(pNode) ) + { + Vec_IntPush( vLeaves, pNode->Id ); + return; + } + assert( Ivy_ObjIsAnd(pNode) ); + Ivy_FraigExtractCone_rec( p, Ivy_ObjFanin0(pNode), vLeaves, vNodes ); + Ivy_FraigExtractCone_rec( p, Ivy_ObjFanin1(pNode), vLeaves, vNodes ); + Vec_IntPush( vNodes, pNode->Id ); +} + +/**Function************************************************************* + + Synopsis [Checks equivalence using BDDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Ivy_FraigExtractCone( Ivy_Man_t * p, Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2, Vec_Int_t * vLeaves ) +{ + Aig_Man_t * pMan; + Aig_Obj_t * pMiter; + Vec_Int_t * vNodes; + Ivy_Obj_t * pObjIvy; + int i; + // collect nodes + vNodes = Vec_IntAlloc( 100 ); + Ivy_ManConst1(p)->fMarkB = 1; + Ivy_FraigExtractCone_rec( p, pObj1, vLeaves, vNodes ); + Ivy_FraigExtractCone_rec( p, pObj2, vLeaves, vNodes ); + Ivy_ManConst1(p)->fMarkB = 0; + // create new manager + pMan = Aig_ManStart( 1000 ); + Ivy_ManConst1(p)->pEquiv = (Ivy_Obj_t *)Aig_ManConst1(pMan); + Ivy_ManForEachNodeVec( p, vLeaves, pObjIvy, i ) + { + pObjIvy->pEquiv = (Ivy_Obj_t *)Aig_ObjCreatePi( pMan ); + pObjIvy->fMarkB = 0; + } + // duplicate internal nodes + Ivy_ManForEachNodeVec( p, vNodes, pObjIvy, i ) + { + + pObjIvy->pEquiv = (Ivy_Obj_t *)Aig_And( pMan, (Aig_Obj_t *)Ivy_ObjChild0Equiv(pObjIvy), (Aig_Obj_t *)Ivy_ObjChild1Equiv(pObjIvy) ); + pObjIvy->fMarkB = 0; + + pMiter = (Aig_Obj_t *)pObjIvy->pEquiv; + assert( pMiter->fPhase == pObjIvy->fPhase ); + } + // create the PO + pMiter = Aig_Exor( pMan, (Aig_Obj_t *)pObj1->pEquiv, (Aig_Obj_t *)pObj2->pEquiv ); + pMiter = Aig_NotCond( pMiter, Aig_Regular(pMiter)->fPhase ^ Aig_IsComplement(pMiter) ); + +/* +printf( "Polarity = %d\n", pMiter->fPhase ); + if ( Ivy_ObjIsConst1(pObj1) || Ivy_ObjIsConst1(pObj2) ) + { + pMiter = Aig_NotCond( pMiter, 1 ); +printf( "***************\n" ); + } +*/ + pMiter = Aig_ObjCreatePo( pMan, pMiter ); +//printf( "Polarity = %d\n", pMiter->fPhase ); + Aig_ManCleanup( pMan ); + Vec_IntFree( vNodes ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Checks equivalence using BDDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FraigCheckCone( Ivy_FraigMan_t * pGlo, Ivy_Man_t * p, Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2, int nConfLimit ) +{ + extern int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fFlipBits, int fAndOuts, int fVerbose ); + Vec_Int_t * vLeaves; + Aig_Man_t * pMan; + Aig_Obj_t * pObj; + int i, RetValue; + vLeaves = Vec_IntAlloc( 100 ); + pMan = Ivy_FraigExtractCone( p, pObj1, pObj2, vLeaves ); + RetValue = Fra_FraigSat( pMan, nConfLimit, 0, 0, 0, 1 ); + if ( RetValue == 0 ) + { + int Counter = 0; + memset( pGlo->pPatWords, 0, sizeof(unsigned) * pGlo->nPatWords ); + Aig_ManForEachPi( pMan, pObj, i ) + if ( ((int *)pMan->pData)[i] ) + { + int iObjIvy = Vec_IntEntry( vLeaves, i ); + assert( iObjIvy > 0 && iObjIvy <= Ivy_ManPiNum(p) ); + Ivy_InfoSetBit( pGlo->pPatWords, iObjIvy-1 ); +//printf( "%d ", iObjIvy ); +Counter++; + } + assert( Counter > 0 ); + } + Vec_IntFree( vLeaves ); + if ( RetValue == 1 ) + printf( "UNSAT\n" ); + else if ( RetValue == 0 ) + printf( "SAT\n" ); + else if ( RetValue == -1 ) + printf( "UNDEC\n" ); + +// p->pModel = (int *)pMan->pData, pMan2->pData = NULL; + Aig_ManStop( pMan ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/kit/kit.h b/src/aig/kit/kit.h index f1075c2f..20da1b35 100644 --- a/src/aig/kit/kit.h +++ b/src/aig/kit/kit.h @@ -539,6 +539,7 @@ extern void Kit_DsdTruthPartialTwo( Kit_DsdMan_t * p, Kit_DsdNtk_t * extern void Kit_DsdPrint( FILE * pFile, Kit_DsdNtk_t * pNtk ); extern void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk ); extern void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ); +extern void Kit_DsdWriteFromTruth( char * pBuffer, unsigned * pTruth, int nVars ); extern Kit_DsdNtk_t * Kit_DsdDecompose( unsigned * pTruth, int nVars ); extern Kit_DsdNtk_t * Kit_DsdDecomposeExpand( unsigned * pTruth, int nVars ); extern Kit_DsdNtk_t * Kit_DsdDecomposeMux( unsigned * pTruth, int nVars, int nDecMux ); diff --git a/src/aig/kit/kitDsd.c b/src/aig/kit/kitDsd.c index fbf92e48..c8665c2f 100644 --- a/src/aig/kit/kitDsd.c +++ b/src/aig/kit/kitDsd.c @@ -199,6 +199,32 @@ void Kit_DsdPrintHex( FILE * pFile, unsigned * pTruth, int nFans ) /**Function************************************************************* + Synopsis [Prints the hex unsigned into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Kit_DsdWriteHex( char * pBuff, unsigned * pTruth, int nFans ) +{ + int nDigits, Digit, k; + nDigits = (1 << nFans) / 4; + for ( k = nDigits - 1; k >= 0; k-- ) + { + Digit = ((pTruth[k/8] >> ((k%8) * 4)) & 15); + if ( Digit < 10 ) + *pBuff++ = '0' + Digit; + else + *pBuff++ = 'A' + Digit-10; + } + return pBuff; +} + +/**Function************************************************************* + Synopsis [Recursively print the DSD formula.] Description [] @@ -276,6 +302,83 @@ void Kit_DsdPrint( FILE * pFile, Kit_DsdNtk_t * pNtk ) /**Function************************************************************* + Synopsis [Recursively print the DSD formula.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Kit_DsdWrite_rec( char * pBuff, Kit_DsdNtk_t * pNtk, int Id ) +{ + Kit_DsdObj_t * pObj; + unsigned iLit, i; + char Symbol; + + pObj = Kit_DsdNtkObj( pNtk, Id ); + if ( pObj == NULL ) + { + assert( Id < pNtk->nVars ); + *pBuff++ = 'a' + Id; + return pBuff; + } + + if ( pObj->Type == KIT_DSD_CONST1 ) + { + assert( pObj->nFans == 0 ); + sprintf( pBuff, "%s", "Const1" ); + return pBuff + strlen("Const1"); + } + + if ( pObj->Type == KIT_DSD_VAR ) + assert( pObj->nFans == 1 ); + + if ( pObj->Type == KIT_DSD_AND ) + Symbol = '*'; + else if ( pObj->Type == KIT_DSD_XOR ) + Symbol = '+'; + else + Symbol = ','; + + if ( pObj->Type == KIT_DSD_PRIME ) + pBuff = Kit_DsdWriteHex( pBuff, Kit_DsdObjTruth(pObj), pObj->nFans ); + + *pBuff++ = '('; + Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i ) + { + if ( Kit_DsdLitIsCompl(iLit) ) + *pBuff++ = '!'; + pBuff = Kit_DsdWrite_rec( pBuff, pNtk, Kit_DsdLit2Var(iLit) ); + if ( i < pObj->nFans - 1 ) + *pBuff++ = Symbol; + } + *pBuff++ = ')'; + return pBuff; +} + +/**Function************************************************************* + + Synopsis [Print the DSD formula.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_DsdWrite( char * pBuff, Kit_DsdNtk_t * pNtk ) +{ + if ( Kit_DsdLitIsCompl(pNtk->Root) ) + *pBuff++ = '!'; + pBuff = Kit_DsdWrite_rec( pBuff, pNtk, Kit_DsdLit2Var(pNtk->Root) ); + *pBuff = 0; +} + +/**Function************************************************************* + Synopsis [Print the DSD formula.] Description [] @@ -307,7 +410,8 @@ void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk ) void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ) { Kit_DsdNtk_t * pTemp, * pTemp2; - pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 5 ); +// pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 5 ); + pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 8 ); // Kit_DsdPrintExpanded( pTemp ); pTemp2 = Kit_DsdExpand( pTemp ); Kit_DsdPrint( stdout, pTemp2 ); @@ -318,6 +422,30 @@ void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ) /**Function************************************************************* + Synopsis [Print the DSD formula.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_DsdWriteFromTruth( char * pBuffer, unsigned * pTruth, int nVars ) +{ + Kit_DsdNtk_t * pTemp, * pTemp2; +// pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 5 ); + pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 8 ); +// Kit_DsdPrintExpanded( pTemp ); + pTemp2 = Kit_DsdExpand( pTemp ); + Kit_DsdWrite( pBuffer, pTemp2 ); + Kit_DsdVerify( pTemp2, pTruth, nVars ); + Kit_DsdNtkFree( pTemp2 ); + Kit_DsdNtkFree( pTemp ); +} + +/**Function************************************************************* + Synopsis [Derives the truth table of the DSD node.] Description [] @@ -2090,7 +2218,7 @@ int Kit_DsdTestCofs( Kit_DsdNtk_t * pNtk, unsigned * pTruthInit ) // Extra_PrintBinary( stdout, pTruth, (1 << pNtk->nVars) ); Extra_PrintHexadecimal( stdout, pTruth, pNtk->nVars ); printf( "\n" ); - Kit_DsdPrint( stdout, pNtk ); + Kit_DsdPrint( stdout, pNtk ), printf( "\n" ); } for ( i = 0; i < pNtk->nVars; i++ ) { @@ -2102,7 +2230,7 @@ int Kit_DsdTestCofs( Kit_DsdNtk_t * pNtk, unsigned * pTruthInit ) if ( fVerbose ) { printf( "Cof%d0: ", i ); - Kit_DsdPrint( stdout, pNtk0 ); + Kit_DsdPrint( stdout, pNtk0 ), printf( "\n" ); } Kit_TruthCofactor1New( pCofs2[1], pTruth, pNtk->nVars, i ); @@ -2113,7 +2241,7 @@ int Kit_DsdTestCofs( Kit_DsdNtk_t * pNtk, unsigned * pTruthInit ) if ( fVerbose ) { printf( "Cof%d1: ", i ); - Kit_DsdPrint( stdout, pNtk1 ); + Kit_DsdPrint( stdout, pNtk1 ), printf( "\n" ); } // if ( Kit_DsdCheckVar4Dec2( pNtk0, pNtk1 ) ) @@ -2215,7 +2343,7 @@ void Kit_DsdTest( unsigned * pTruth, int nVars ) pNtk = Kit_DsdExpand( pTemp = pNtk ); Kit_DsdNtkFree( pTemp ); - Kit_DsdPrint( stdout, pNtk ); + Kit_DsdPrint( stdout, pNtk ), printf( "\n" ); // if ( Kit_DsdFindLargeBox(pNtk, Kit_DsdLit2Var(pNtk->Root)) ) // Kit_DsdTestCofs( pNtk, pTruth ); @@ -2277,7 +2405,7 @@ void Kit_DsdPrecompute4Vars() RetValue = Kit_DsdTestCofs( pNtk, &uTruth ); printf( "\n" ); printf( "%3d : Non-DSD function %s %s\n", i, Buffer + 2, RetValue? "implementable" : "" ); - Kit_DsdPrint( stdout, pNtk ); + Kit_DsdPrint( stdout, pNtk ), printf( "\n" ); Counter1++; Counter2 += RetValue; @@ -2456,9 +2584,9 @@ int Kit_DsdCofactoring( unsigned * pTruth, int nVars, int * pCofVars, int nLimit Kit_DsdNtkFree( pTemp ); printf( "Cof%d%d: ", nStep+1, 2*i+0 ); - Kit_DsdPrint( stdout, ppNtks[nStep+1][2*i+0] ); + Kit_DsdPrint( stdout, ppNtks[nStep+1][2*i+0] ), printf( "\n" ); printf( "Cof%d%d: ", nStep+1, 2*i+1 ); - Kit_DsdPrint( stdout, ppNtks[nStep+1][2*i+1] ); + Kit_DsdPrint( stdout, ppNtks[nStep+1][2*i+1] ), printf( "\n" ); } } } @@ -2500,7 +2628,7 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] ); Kit_DsdNtkFree( pTemp ); if ( fVerbose ) - Kit_DsdPrint( stdout, ppNtks[0] ); + Kit_DsdPrint( stdout, ppNtks[0] ), printf( "\n" ); Kit_DsdNtkFree( ppNtks[0] ); // allocate storage for cofactors @@ -2551,7 +2679,7 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe if ( fVerbose ) { printf( "Cof%d%d: ", nSteps, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); + Kit_DsdPrint( stdout, ppNtks[i] ), printf( "\n" ); } // compute the largest non-decomp block nPrimeSizeCur = Kit_DsdNonDsdSizeMax(ppNtks[i]); @@ -2600,7 +2728,7 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe if ( fVerbose ) { printf( "Cof%d%d: ", nSteps, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); + Kit_DsdPrint( stdout, ppNtks[i] ), printf( "\n" ); } // compute the largest non-decomp block nPrimeSizeCur = Kit_DsdNonDsdSizeMax(ppNtks[i]); @@ -2651,7 +2779,7 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe if ( fVerbose ) { printf( "Cof%d%d: ", nSteps, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); + Kit_DsdPrint( stdout, ppNtks[i] ), printf( "\n" ); } // compute the largest non-decomp block nPrimeSizeCur = Kit_DsdNonDsdSizeMax(ppNtks[i]); @@ -2704,7 +2832,7 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe if ( fVerbose ) { printf( "Cof%d%d: ", nSteps, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); + Kit_DsdPrint( stdout, ppNtks[i] ), printf( "\n" ); } // compute the largest non-decomp block nPrimeSizeCur = Kit_DsdNonDsdSizeMax(ppNtks[i]); diff --git a/src/aig/live/ltl_parser.c b/src/aig/live/ltl_parser.c index 58125818..de113ba7 100644 --- a/src/aig/live/ltl_parser.c +++ b/src/aig/live/ltl_parser.c @@ -22,9 +22,9 @@ #include <string.h> #include <assert.h> #include <stdlib.h> -#include <aig.h> -#include <abc.h> -#include <mainInt.h> +#include "aig.h" +#include "abc.h" +#include "mainInt.h" ABC_NAMESPACE_IMPL_START diff --git a/src/aig/llb/llb1Core.c b/src/aig/llb/llb1Core.c index ff7eadbb..ad2c5934 100644 --- a/src/aig/llb/llb1Core.c +++ b/src/aig/llb/llb1Core.c @@ -208,6 +208,7 @@ int Llb_ManModelCheckGia( Gia_Man_t * pGia, Gia_ParLlb_t * pPars ) RetValue = Llb_ManModelCheckAig( pAig, pPars, NULL, NULL ); else RetValue = Llb_ManModelCheckAigWithHints( pAig, pPars ); + pGia->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL; Aig_ManStop( pAig ); return RetValue; } diff --git a/src/aig/llb/llb1Man.c b/src/aig/llb/llb1Man.c index d9c13a76..f5de25e0 100644 --- a/src/aig/llb/llb1Man.c +++ b/src/aig/llb/llb1Man.c @@ -47,9 +47,13 @@ void Llb_ManPrepareVarMap( Llb_Man_t * p ) Aig_Obj_t * pObjLi, * pObjLo; int i, iVarLi, iVarLo; assert( p->vNs2Glo == NULL ); + assert( p->vCs2Glo == NULL ); assert( p->vGlo2Cs == NULL ); + assert( p->vGlo2Ns == NULL ); p->vNs2Glo = Vec_IntStartFull( Vec_IntSize(p->vVar2Obj) ); + p->vCs2Glo = Vec_IntStartFull( Vec_IntSize(p->vVar2Obj) ); p->vGlo2Cs = Vec_IntStartFull( Aig_ManRegNum(p->pAig) ); + p->vGlo2Ns = Vec_IntStartFull( Aig_ManRegNum(p->pAig) ); Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) { iVarLi = Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObjLi)); @@ -57,7 +61,16 @@ void Llb_ManPrepareVarMap( Llb_Man_t * p ) assert( iVarLi >= 0 && iVarLi < Vec_IntSize(p->vVar2Obj) ); assert( iVarLo >= 0 && iVarLo < Vec_IntSize(p->vVar2Obj) ); Vec_IntWriteEntry( p->vNs2Glo, iVarLi, i ); + Vec_IntWriteEntry( p->vCs2Glo, iVarLo, i ); Vec_IntWriteEntry( p->vGlo2Cs, i, iVarLo ); + Vec_IntWriteEntry( p->vGlo2Ns, i, iVarLi ); + } + // add mapping of the PIs + Saig_ManForEachPi( p->pAig, pObjLo, i ) + { + iVarLo = Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObjLo)); + Vec_IntWriteEntry( p->vCs2Glo, iVarLo, Aig_ManRegNum(p->pAig)+i ); + Vec_IntWriteEntry( p->vNs2Glo, iVarLo, Aig_ManRegNum(p->pAig)+i ); } } @@ -117,6 +130,7 @@ void Llb_ManPrepareVarLimits( Llb_Man_t * p ) void Llb_ManStop( Llb_Man_t * p ) { Llb_Grp_t * pGrp; + DdNode * bTemp; int i; // Vec_IntFreeP( &p->vMem ); @@ -128,25 +142,39 @@ void Llb_ManStop( Llb_Man_t * p ) Llb_MtrFree( p->pMatrix ); Vec_PtrForEachEntry( Llb_Grp_t *, p->vGroups, pGrp, i ) Llb_ManGroupStop( pGrp ); - Vec_PtrFreeP( &p->vGroups ); - Vec_IntFreeP( &p->vVar2Obj ); - Vec_IntFreeP( &p->vObj2Var ); - Vec_IntFreeP( &p->vVarBegs ); - Vec_IntFreeP( &p->vVarEnds ); - Vec_IntFreeP( &p->vNs2Glo ); - Vec_IntFreeP( &p->vGlo2Cs ); -// Vec_IntFreeP( &p->vHints ); if ( p->dd ) { +// printf( "Manager dd\n" ); Extra_StopManager( p->dd ); } if ( p->ddG ) { +// printf( "Manager ddG\n" ); if ( p->ddG->bFunc ) Cudd_RecursiveDeref( p->ddG, p->ddG->bFunc ); Extra_StopManager( p->ddG ); } + if ( p->ddR ) + { +// printf( "Manager ddR\n" ); + if ( p->ddR->bFunc ) + Cudd_RecursiveDeref( p->ddR, p->ddR->bFunc ); + Vec_PtrForEachEntry( DdNode *, p->vRings, bTemp, i ) + Cudd_RecursiveDeref( p->ddR, bTemp ); + Extra_StopManager( p->ddR ); + } Aig_ManStop( p->pAig ); + Vec_PtrFreeP( &p->vGroups ); + Vec_IntFreeP( &p->vVar2Obj ); + Vec_IntFreeP( &p->vObj2Var ); + Vec_IntFreeP( &p->vVarBegs ); + Vec_IntFreeP( &p->vVarEnds ); + Vec_PtrFreeP( &p->vRings ); + Vec_IntFreeP( &p->vNs2Glo ); + Vec_IntFreeP( &p->vCs2Glo ); + Vec_IntFreeP( &p->vGlo2Cs ); + Vec_IntFreeP( &p->vGlo2Ns ); +// Vec_IntFreeP( &p->vHints ); ABC_FREE( p ); } @@ -172,6 +200,7 @@ Llb_Man_t * Llb_ManStart( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * p->pAig = pAig; p->vVar2Obj = Llb_ManMarkPivotNodes( p->pAig, pPars->fUsePivots ); p->vObj2Var = Vec_IntInvert( p->vVar2Obj, -1 ); + p->vRings = Vec_PtrAlloc( 100 ); Llb_ManPrepareVarMap( p ); Llb_ManPrepareGroups( p ); Aig_ManCleanMarkA( pAig ); diff --git a/src/aig/llb/llb1Reach.c b/src/aig/llb/llb1Reach.c index 443d2d81..341ebd95 100644 --- a/src/aig/llb/llb1Reach.c +++ b/src/aig/llb/llb1Reach.c @@ -48,9 +48,10 @@ DdNode * Llb_ManConstructOutBdd( Aig_Man_t * pAig, Aig_Obj_t * pNode, DdManager DdNode * bBdd0, * bBdd1, * bFunc; Vec_Ptr_t * vNodes; Aig_Obj_t * pObj; - int i; + int i, TimeStop; if ( Aig_ObjFanin0(pNode) == Aig_ManConst1(pAig) ) return Cudd_NotCond( Cudd_ReadOne(dd), Aig_ObjFaninC0(pNode) ); + TimeStop = dd->TimeStop; dd->TimeStop = 0; vNodes = Aig_ManDfsNodes( pAig, &pNode, 1 ); assert( Vec_PtrSize(vNodes) > 0 ); Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) @@ -72,6 +73,7 @@ DdNode * Llb_ManConstructOutBdd( Aig_Man_t * pAig, Aig_Obj_t * pNode, DdManager if ( Aig_ObjIsPo(pNode) ) bFunc = Cudd_NotCond( bFunc, Aig_ObjFaninC0(pNode) ); Cudd_Deref( bFunc ); + dd->TimeStop = TimeStop; return bFunc; } @@ -98,7 +100,8 @@ DdNode * Llb_ManConstructGroupBdd( Llb_Man_t * p, Llb_Grp_t * pGroup ) { bBdd0 = Cudd_NotCond( Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); - pObj->pData = Extra_bddAndTime( p->dd, bBdd0, bBdd1, p->pPars->TimeTarget ); +// pObj->pData = Extra_bddAndTime( p->dd, bBdd0, bBdd1, p->pPars->TimeTarget ); + pObj->pData = Cudd_bddAnd( p->dd, bBdd0, bBdd1 ); if ( pObj->pData == NULL ) { Vec_PtrForEachEntryStop( Aig_Obj_t *, pGroup->vNodes, pObj, k, i ) @@ -117,7 +120,8 @@ DdNode * Llb_ManConstructGroupBdd( Llb_Man_t * p, Llb_Grp_t * pGroup ) bBdd0 = (DdNode *)pObj->pData; bBdd1 = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); bXor = Cudd_bddXor( p->dd, bBdd0, bBdd1 ); Cudd_Ref( bXor ); - bRes = Extra_bddAndTime( p->dd, bTemp = bRes, Cudd_Not(bXor), p->pPars->TimeTarget ); +// bRes = Extra_bddAndTime( p->dd, bTemp = bRes, Cudd_Not(bXor), p->pPars->TimeTarget ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, Cudd_Not(bXor) ); if ( bRes == NULL ) { Cudd_RecursiveDeref( p->dd, bTemp ); @@ -148,14 +152,18 @@ DdNode * Llb_ManConstructGroupBdd( Llb_Man_t * p, Llb_Grp_t * pGroup ) SeeAlso [] ***********************************************************************/ -DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) +DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace, int fBackward ) { Aig_Obj_t * pObj; DdNode * bRes, * bTemp, * bVar; int i, iGroupFirst, iGroupLast; + int TimeStop; + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) { + if ( fBackward && Saig_ObjIsPi(p->pAig, pObj) ) + continue; iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); assert( iGroupFirst <= iGroupLast ); @@ -167,6 +175,8 @@ DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int } Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) { + if ( fBackward && Saig_ObjIsPi(p->pAig, pObj) ) + continue; iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); assert( iGroupFirst <= iGroupLast ); @@ -177,6 +187,7 @@ DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int Cudd_RecursiveDeref( p->dd, bTemp ); } Cudd_Deref( bRes ); + p->dd->TimeStop = TimeStop; return bRes; } @@ -191,11 +202,12 @@ DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int SeeAlso [] ***********************************************************************/ -DdNode * Llb_ManConstructQuantCube( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) +DdNode * Llb_ManConstructQuantCubeFwd( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) { Aig_Obj_t * pObj; DdNode * bRes, * bTemp, * bVar; - int i, iGroupLast; + int i, iGroupLast, TimeStop; + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) { @@ -218,6 +230,54 @@ DdNode * Llb_ManConstructQuantCube( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpP Cudd_RecursiveDeref( p->dd, bTemp ); } Cudd_Deref( bRes ); + p->dd->TimeStop = TimeStop; + return bRes; +} + +/**Function************************************************************* + + Synopsis [Derives quantification cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManConstructQuantCubeBwd( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) +{ + Aig_Obj_t * pObj; + DdNode * bRes, * bTemp, * bVar; + int i, iGroupFirst, TimeStop; + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; + bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + { + if ( Saig_ObjIsPi(p->pAig, pObj) ) + continue; + iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); + assert( iGroupFirst <= iGrpPlace ); + if ( iGroupFirst < iGrpPlace ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + { + if ( Saig_ObjIsPi(p->pAig, pObj) ) + continue; + iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); + assert( iGroupFirst <= iGrpPlace ); + if ( iGroupFirst < iGrpPlace ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Cudd_Deref( bRes ); + p->dd->TimeStop = TimeStop; return bRes; } @@ -236,7 +296,8 @@ DdNode * Llb_ManComputeInitState( Llb_Man_t * p, DdManager * dd ) { Aig_Obj_t * pObj; DdNode * bRes, * bVar, * bTemp; - int i, iVar; + int i, iVar, TimeStop; + TimeStop = dd->TimeStop; dd->TimeStop = 0; bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes ); Saig_ManForEachLo( p->pAig, pObj, i ) { @@ -246,6 +307,7 @@ DdNode * Llb_ManComputeInitState( Llb_Man_t * p, DdManager * dd ) Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bRes ); + dd->TimeStop = TimeStop; return bRes; } @@ -260,17 +322,22 @@ DdNode * Llb_ManComputeInitState( Llb_Man_t * p, DdManager * dd ) SeeAlso [] ***********************************************************************/ -DdNode * Llb_ManComputeImage( Llb_Man_t * p, DdNode * bInit ) +DdNode * Llb_ManComputeImage( Llb_Man_t * p, DdNode * bInit, int fBackward ) { int fCheckSupport = 0; Llb_Grp_t * pGroup; DdNode * bImage, * bGroup, * bCube, * bTemp; - int i; + int k, Index; bImage = bInit; Cudd_Ref( bImage ); - for ( i = 1; i < p->pMatrix->nCols-1; i++ ) + for ( k = 1; k < p->pMatrix->nCols-1; k++ ) { + if ( fBackward ) + Index = p->pMatrix->nCols - 1 - k; + else + Index = k; + // compute group BDD - pGroup = p->pMatrix->pColGrps[i]; + pGroup = p->pMatrix->pColGrps[Index]; bGroup = Llb_ManConstructGroupBdd( p, pGroup ); if ( bGroup == NULL ) { @@ -279,13 +346,25 @@ DdNode * Llb_ManComputeImage( Llb_Man_t * p, DdNode * bInit ) } Cudd_Ref( bGroup ); // quantify variables appearing only in this group - bCube = Llb_ManConstructQuantCubeIntern( p, pGroup, i ); Cudd_Ref( bCube ); - bGroup = Cudd_bddExistAbstract( p->dd, bTemp = bGroup, bCube ); Cudd_Ref( bGroup ); + bCube = Llb_ManConstructQuantCubeIntern( p, pGroup, Index, fBackward ); Cudd_Ref( bCube ); + bGroup = Cudd_bddExistAbstract( p->dd, bTemp = bGroup, bCube ); + if ( bGroup == NULL ) + { + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bCube ); + return NULL; + } + Cudd_Ref( bGroup ); Cudd_RecursiveDeref( p->dd, bTemp ); Cudd_RecursiveDeref( p->dd, bCube ); // perform partial product - bCube = Llb_ManConstructQuantCube( p, pGroup, i ); Cudd_Ref( bCube ); - bImage = Extra_bddAndAbstractTime( p->dd, bTemp = bImage, bGroup, bCube, p->pPars->TimeTarget ); + if ( fBackward ) + bCube = Llb_ManConstructQuantCubeBwd( p, pGroup, Index ); + else + bCube = Llb_ManConstructQuantCubeFwd( p, pGroup, Index ); + Cudd_Ref( bCube ); +// bImage = Extra_bddAndAbstractTime( p->dd, bTemp = bImage, bGroup, bCube, p->pPars->TimeTarget ); + bImage = Cudd_bddAndAbstract( p->dd, bTemp = bImage, bGroup, bCube ); if ( bImage == NULL ) { Cudd_RecursiveDeref( p->dd, bTemp ); @@ -331,9 +410,10 @@ DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNs { DdNode * bConstr, * bFunc, * bTemp; Aig_Obj_t * pObj; - int i, Entry; + int i, Entry, TimeStop; if ( vHints == NULL ) return Cudd_ReadOne( p->dd ); + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; assert( Aig_ManPiNum(p->pAig) == Aig_ManPiNum(p->pAigGlo) ); // assign const and PI nodes to the original AIG Aig_ManCleanData( p->pAig ); @@ -367,12 +447,13 @@ DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNs Cudd_RecursiveDeref( p->dd, bFunc ); } Cudd_Deref( bConstr ); + p->dd->TimeStop = TimeStop; return bConstr; } /**Function************************************************************* - Synopsis [] + Synopsis [Perform reachability with hints and returns reached states in ppGlo.] Description [] @@ -381,9 +462,106 @@ DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNs SeeAlso [] ***********************************************************************/ -Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter ) +Abc_Cex_t * Llb_ManReachDeriveCex( Llb_Man_t * p ) { - return NULL; + Abc_Cex_t * pCex; + Aig_Obj_t * pObj; + DdNode * bState, * bImage, * bOneCube, * bTemp, * bRing; + int i, v, RetValue, nPiOffset; + char * pValues = ABC_ALLOC( char, Cudd_ReadSize(p->ddR) ); + assert( Vec_PtrSize(p->vRings) > 0 ); + + p->dd->TimeStop = 0; + p->ddR->TimeStop = 0; + +/* + Saig_ManForEachLo( p->pAig, pObj, i ) + printf( "%d ", pObj->Id ); + printf( "\n" ); + Saig_ManForEachLi( p->pAig, pObj, i ) + printf( "%d(%d) ", pObj->Id, Aig_ObjFaninId0(pObj) ); + printf( "\n" ); +*/ + // allocate room for the counter-example + pCex = Abc_CexAlloc( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) ); + pCex->iFrame = Vec_PtrSize(p->vRings) - 1; + pCex->iPo = -1; + + // get the last cube + bOneCube = Cudd_bddIntersect( p->ddR, (DdNode *)Vec_PtrEntryLast(p->vRings), p->ddR->bFunc ); Cudd_Ref( bOneCube ); + RetValue = Cudd_bddPickOneCube( p->ddR, bOneCube, pValues ); + Cudd_RecursiveDeref( p->ddR, bOneCube ); + assert( RetValue ); + + // write PIs of counter-example + nPiOffset = Saig_ManRegNum(p->pAig) + Saig_ManPiNum(p->pAig) * (Vec_PtrSize(p->vRings) - 1); + Saig_ManForEachPi( p->pAig, pObj, i ) + if ( pValues[Saig_ManRegNum(p->pAig)+i] == 1 ) + Aig_InfoSetBit( pCex->pData, nPiOffset + i ); + + // write state in terms of NS variables + if ( Vec_PtrSize(p->vRings) > 1 ) + { + bState = Llb_CoreComputeCube( p->dd, p->vGlo2Ns, 1, pValues ); Cudd_Ref( bState ); + } + // perform backward analysis + Vec_PtrForEachEntryReverse( DdNode *, p->vRings, bRing, v ) + { + if ( v == Vec_PtrSize(p->vRings) - 1 ) + continue; +//Extra_bddPrintSupport( p->dd, bState ); printf( "\n" ); +//Extra_bddPrintSupport( p->dd, bRing ); printf( "\n" ); + // compute the next states + bImage = Llb_ManComputeImage( p, bState, 1 ); + assert( bImage != NULL ); + Cudd_Ref( bImage ); + Cudd_RecursiveDeref( p->dd, bState ); +//Extra_bddPrintSupport( p->dd, bImage ); printf( "\n" ); + + // move reached states into ring manager + bImage = Extra_TransferPermute( p->dd, p->ddR, bTemp = bImage, Vec_IntArray(p->vCs2Glo) ); Cudd_Ref( bImage ); + Cudd_RecursiveDeref( p->dd, bTemp ); +//Extra_bddPrintSupport( p->ddR, bImage ); printf( "\n" ); + + // intersect with the previous set + bOneCube = Cudd_bddIntersect( p->ddR, bImage, bRing ); Cudd_Ref( bOneCube ); + Cudd_RecursiveDeref( p->ddR, bImage ); + + // find any assignment of the BDD + RetValue = Cudd_bddPickOneCube( p->ddR, bOneCube, pValues ); + Cudd_RecursiveDeref( p->ddR, bOneCube ); + assert( RetValue ); +/* + for ( i = 0; i < p->ddR->size; i++ ) + printf( "%d ", pValues[i] ); + printf( "\n" ); +*/ + // write PIs of counter-example + nPiOffset -= Saig_ManPiNum(p->pAig); + Saig_ManForEachPi( p->pAig, pObj, i ) + if ( pValues[Saig_ManRegNum(p->pAig)+i] == 1 ) + Aig_InfoSetBit( pCex->pData, nPiOffset + i ); + + // check that we get the init state + if ( v == 0 ) + { + Saig_ManForEachLo( p->pAig, pObj, i ) + assert( pValues[i] == 0 ); + break; + } + + // write state in terms of NS variables + bState = Llb_CoreComputeCube( p->dd, p->vGlo2Ns, 1, pValues ); Cudd_Ref( bState ); + } + assert( nPiOffset == Saig_ManRegNum(p->pAig) ); + // update the output number +//Abc_CexPrint( pCex ); + RetValue = Saig_ManFindFailedPoCex( p->pAigGlo, pCex ); + assert( RetValue >= 0 && RetValue < Saig_ManPoNum(p->pAigGlo) ); // invalid CEX!!! + pCex->iPo = RetValue; + // cleanup + ABC_FREE( pValues ); + return pCex; } /**Function************************************************************* @@ -399,12 +577,12 @@ Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int ***********************************************************************/ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo ) { - int fCheckOutputs = !p->pPars->fSkipOutCheck; int * pNs2Glo = Vec_IntArray( p->vNs2Glo ); + int * pCs2Glo = Vec_IntArray( p->vCs2Glo ); int * pGlo2Cs = Vec_IntArray( p->vGlo2Cs ); DdNode * bCurrent, * bReached, * bNext, * bTemp, * bCube; DdNode * bConstrCs, * bConstrNs; - int clk2, clk = clock(), nIters, nBddSize = 0, iOutFail = -1; + int clk2, clk = clock(), nIters, nBddSize = 0; int nThreshold = 10000; // compute time to stop @@ -419,7 +597,9 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo // start the managers assert( p->dd == NULL ); assert( p->ddG == NULL ); + assert( p->ddR == NULL ); p->dd = Cudd_Init( Vec_IntSize(p->vVar2Obj), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + p->ddR = Cudd_Init( Aig_ManPiNum(p->pAig), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); if ( pddGlo && *pddGlo ) p->ddG = *pddGlo, *pddGlo = NULL; else @@ -429,16 +609,29 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo { Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT ); Cudd_AutodynEnable( p->ddG, CUDD_REORDER_SYMM_SIFT ); + Cudd_AutodynEnable( p->ddR, CUDD_REORDER_SYMM_SIFT ); } else { Cudd_AutodynDisable( p->dd ); Cudd_AutodynDisable( p->ddG ); + Cudd_AutodynDisable( p->ddR ); } // set the stop time parameter p->dd->TimeStop = p->pPars->TimeTarget; p->ddG->TimeStop = p->pPars->TimeTarget; + p->ddR->TimeStop = p->pPars->TimeTarget; + + // create bad state in the ring manager + p->ddR->bFunc = Llb_BddComputeBad( p->pAigGlo, p->ddR, p->pPars->TimeTarget ); + if ( p->ddR->bFunc == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during constructing the bad states.\n", p->pPars->TimeLimit ); + return -1; + } + Cudd_Ref( p->ddR->bFunc ); // derive constraints bConstrCs = Llb_ManCreateConstraints( p, vHints, 0 ); Cudd_Ref( bConstrCs ); @@ -478,61 +671,58 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo return -1; } - // check outputs - if ( fCheckOutputs ) + // save the onion ring + bTemp = Extra_TransferPermute( p->dd, p->ddR, bCurrent, pCs2Glo ); + if ( bTemp == NULL ) { - Aig_Obj_t * pObj; - int i; - Aig_ManConst1( p->pAigGlo )->pData = Cudd_ReadOne( p->dd ); - Aig_ManForEachPi( p->pAig, pObj, i ) - pObj->pData = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var,Aig_ObjId(pObj)) ); - Aig_ManForEachPi( p->pAigGlo, pObj, i ) - pObj->pData = Aig_ManPi(p->pAig, i)->pData; + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during ring transfer.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL; + Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return -1; + } + Cudd_Ref( bTemp ); + Vec_PtrPush( p->vRings, bTemp ); -//Extra_bddPrintSupport( p->dd, bCurrent ); printf( "\n" ); - for ( iOutFail = 0; iOutFail < Saig_ManPoNum(p->pAig); iOutFail++ ) - { - DdNode * bFunc, * bInter; - bFunc = Llb_ManConstructOutBdd( p->pAigGlo, Aig_ManPo(p->pAigGlo, iOutFail), p->dd ); Cudd_Ref( bFunc ); -//Extra_bddPrint( p->dd, bFunc ); printf( "\n" ); - if ( Cudd_bddLeq( p->dd, bCurrent, Cudd_Not(bFunc) ) ) // no cex - { - Cudd_RecursiveDeref( p->dd, bFunc ); - continue; - } - bInter = Cudd_bddIntersect( p->dd, bCurrent, bFunc ); Cudd_Ref( bInter ); - assert( p->pAig->pSeqModel == NULL ); - p->pAig->pSeqModel = Llb_ManDeriveCex( p, bInter, iOutFail, nIters ); - Cudd_RecursiveDeref( p->dd, bInter ); - Cudd_RecursiveDeref( p->dd, bFunc ); - break; - } - if ( iOutFail < Saig_ManPoNum(p->pAig) ) + // check it for bad states + if ( !p->pPars->fSkipOutCheck && !Cudd_bddLeq( p->ddR, bTemp, Cudd_Not(p->ddR->bFunc) ) ) + { + assert( p->pAigGlo->pSeqModel == NULL ); + if ( !p->pPars->fBackward ) + p->pAigGlo->pSeqModel = Llb_ManReachDeriveCex( p ); + if ( !p->pPars->fSilent ) { - if ( !p->pPars->fSilent ) - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", iOutFail, nIters ); - Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; - Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; - p->pPars->iFrame = nIters; - break; + if ( !p->pPars->fBackward ) + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", p->pAigGlo->pSeqModel->iPo, nIters ); + else + printf( "Output ??? was asserted in frame %d (counter-example is not produced). ", nIters ); + Abc_PrintTime( 1, "Time", clock() - clk ); } + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL; + Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return 0; } // restrict reachable states using constraints if ( vHints ) { - bCurrent = Cudd_bddAnd( p->dd, bTemp = bCurrent, bConstrCs ); Cudd_Ref( bCurrent ); + bCurrent = Cudd_bddAnd( p->dd, bTemp = bCurrent, bConstrCs ); Cudd_Ref( bCurrent ); Cudd_RecursiveDeref( p->dd, bTemp ); } // quantify variables appearing only in the init state - bCube = Llb_ManConstructQuantCubeIntern( p, (Llb_Grp_t *)Vec_PtrEntry(p->vGroups,0), 0 ); Cudd_Ref( bCube ); - bCurrent = Cudd_bddExistAbstract( p->dd, bTemp = bCurrent, bCube ); Cudd_Ref( bCurrent ); + bCube = Llb_ManConstructQuantCubeIntern( p, (Llb_Grp_t *)Vec_PtrEntry(p->vGroups,0), 0, 0 ); Cudd_Ref( bCube ); + bCurrent = Cudd_bddExistAbstract( p->dd, bTemp = bCurrent, bCube ); Cudd_Ref( bCurrent ); Cudd_RecursiveDeref( p->dd, bTemp ); Cudd_RecursiveDeref( p->dd, bCube ); // compute the next states - bNext = Llb_ManComputeImage( p, bCurrent ); + bNext = Llb_ManComputeImage( p, bCurrent, 0 ); if ( bNext == NULL ) { if ( !p->pPars->fSilent ) @@ -558,7 +748,8 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo // remap these states into the current state vars // bNext = Extra_TransferPermute( p->dd, p->ddG, bTemp = bNext, pNs2Glo ); Cudd_Ref( bNext ); // Cudd_RecursiveDeref( p->dd, bTemp ); - bNext = Extra_TransferPermuteTime( p->dd, p->ddG, bTemp = bNext, pNs2Glo, p->pPars->TimeTarget ); +// bNext = Extra_TransferPermuteTime( p->dd, p->ddG, bTemp = bNext, pNs2Glo, p->pPars->TimeTarget ); + bNext = Extra_TransferPermute( p->dd, p->ddG, bTemp = bNext, pNs2Glo ); if ( bNext == NULL ) { if ( !p->pPars->fSilent ) @@ -590,7 +781,14 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo } // get the new states - bCurrent = Cudd_bddAnd( p->ddG, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); + bCurrent = Cudd_bddAnd( p->ddG, bNext, Cudd_Not(bReached) ); + if ( bCurrent == NULL ) + { + Cudd_RecursiveDeref( p->ddG, bNext ); bNext = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + break; + } + Cudd_Ref( bCurrent ); // minimize the new states with the reached states // bCurrent = Cudd_bddConstrain( p->ddG, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); // bCurrent = Cudd_bddRestrict( p->ddG, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); @@ -600,7 +798,8 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo // remap these states into the current state vars // bCurrent = Extra_TransferPermute( p->ddG, p->dd, bTemp = bCurrent, pGlo2Cs ); Cudd_Ref( bCurrent ); // Cudd_RecursiveDeref( p->ddG, bTemp ); - bCurrent = Extra_TransferPermuteTime( p->ddG, p->dd, bTemp = bCurrent, pGlo2Cs, p->pPars->TimeTarget ); +// bCurrent = Extra_TransferPermuteTime( p->ddG, p->dd, bTemp = bCurrent, pGlo2Cs, p->pPars->TimeTarget ); + bCurrent = Extra_TransferPermute( p->ddG, p->dd, bTemp = bCurrent, pGlo2Cs ); if ( bCurrent == NULL ) { if ( !p->pPars->fSilent ) @@ -617,7 +816,14 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo // add to the reached states - bReached = Cudd_bddOr( p->ddG, bTemp = bReached, bNext ); Cudd_Ref( bReached ); + bReached = Cudd_bddOr( p->ddG, bTemp = bReached, bNext ); + if ( bReached == NULL ) + { + Cudd_RecursiveDeref( p->ddG, bTemp ); bTemp = NULL; + Cudd_RecursiveDeref( p->ddG, bNext ); bNext = NULL; + break; + } + Cudd_Ref( bReached ); Cudd_RecursiveDeref( p->ddG, bTemp ); Cudd_RecursiveDeref( p->ddG, bNext ); bNext = NULL; diff --git a/src/aig/llb/llb2Bad.c b/src/aig/llb/llb2Bad.c index 88ff4c75..9aecb9ff 100644 --- a/src/aig/llb/llb2Bad.c +++ b/src/aig/llb/llb2Bad.c @@ -63,7 +63,8 @@ DdNode * Llb_BddComputeBad( Aig_Man_t * pInit, DdManager * dd, int TimeOut ) continue; bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); - pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeOut ); +// pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeOut ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); if ( pObj->pData == NULL ) { Vec_PtrForEachEntryStop( Aig_Obj_t *, vNodes, pObj, k, i ) @@ -87,7 +88,7 @@ DdNode * Llb_BddComputeBad( Aig_Man_t * pInit, DdManager * dd, int TimeOut ) { if ( !Aig_ObjIsNode(pObj) ) continue; - Cudd_RecursiveDeref( dd, pObj->pData ); + Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); } Vec_PtrFree( vNodes ); Cudd_Deref( bResult ); @@ -109,8 +110,9 @@ DdNode * Llb_BddQuantifyPis( Aig_Man_t * pInit, DdManager * dd, DdNode * bFunc ) { DdNode * bVar, * bCube, * bTemp; Aig_Obj_t * pObj; - int i; + int i, TimeStop; assert( Cudd_ReadSize(dd) == Aig_ManPiNum(pInit) ); + TimeStop = dd->TimeStop; dd->TimeStop = 0; // create PI cube bCube = Cudd_ReadOne( dd ); Cudd_Ref( bCube ); Saig_ManForEachPi( pInit, pObj, i ) { @@ -122,6 +124,7 @@ DdNode * Llb_BddQuantifyPis( Aig_Man_t * pInit, DdManager * dd, DdNode * bFunc ) bFunc = Cudd_bddExistAbstract( dd, bFunc, bCube ); Cudd_Ref( bFunc ); Cudd_RecursiveDeref( dd, bCube ); Cudd_Deref( bFunc ); + dd->TimeStop = TimeStop; return bFunc; } diff --git a/src/aig/llb/llb2Core.c b/src/aig/llb/llb2Core.c index 7fa361b9..446f1a67 100644 --- a/src/aig/llb/llb2Core.c +++ b/src/aig/llb/llb2Core.c @@ -68,7 +68,8 @@ struct Llb_Img_t_ DdNode * Llb_CoreComputeCube( DdManager * dd, Vec_Int_t * vVars, int fUseVarIndex, char * pValues ) { DdNode * bRes, * bVar, * bTemp; - int i, iVar, Index; + int i, iVar, Index, TimeStop; + TimeStop = dd->TimeStop; dd->TimeStop = 0; bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes ); Vec_IntForEachEntry( vVars, Index, i ) { @@ -78,6 +79,7 @@ DdNode * Llb_CoreComputeCube( DdManager * dd, Vec_Int_t * vVars, int fUseVarInde Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bRes ); + dd->TimeStop = TimeStop; return bRes; } @@ -94,8 +96,6 @@ DdNode * Llb_CoreComputeCube( DdManager * dd, Vec_Int_t * vVars, int fUseVarInde ***********************************************************************/ Abc_Cex_t * Llb_CoreDeriveCex( Llb_Img_t * p ) { - extern Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); - extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); Abc_Cex_t * pCex; Aig_Obj_t * pObj; Vec_Ptr_t * vSupps, * vQuant0, * vQuant1; @@ -104,6 +104,9 @@ Abc_Cex_t * Llb_CoreDeriveCex( Llb_Img_t * p ) char * pValues = ABC_ALLOC( char, Cudd_ReadSize(p->ddR) ); assert( Vec_PtrSize(p->vRings) > 0 ); + p->dd->TimeStop = 0; + p->ddR->TimeStop = 0; + // get supports and quantified variables Vec_PtrReverseOrder( p->vDdMans ); vSupps = Llb_ImgSupports( p->pAig, p->vDdMans, p->vVarsNs, p->vVarsCs, 1, 0 ); @@ -113,12 +116,12 @@ Abc_Cex_t * Llb_CoreDeriveCex( Llb_Img_t * p ) // Llb_ImgQuantifyFirst( p->pAig, p->vDdMans, vQuant0 ); // allocate room for the counter-example - pCex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) ); + pCex = Abc_CexAlloc( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) ); pCex->iFrame = Vec_PtrSize(p->vRings) - 1; pCex->iPo = -1; // get the last cube - bOneCube = Cudd_bddIntersect( p->ddR, Vec_PtrEntryLast(p->vRings), p->ddR->bFunc ); Cudd_Ref( bOneCube ); + bOneCube = Cudd_bddIntersect( p->ddR, (DdNode *)Vec_PtrEntryLast(p->vRings), p->ddR->bFunc ); Cudd_Ref( bOneCube ); RetValue = Cudd_bddPickOneCube( p->ddR, bOneCube, pValues ); Cudd_RecursiveDeref( p->ddR, bOneCube ); assert( RetValue ); @@ -179,7 +182,7 @@ Abc_Cex_t * Llb_CoreDeriveCex( Llb_Img_t * p ) } assert( nPiOffset == Saig_ManRegNum(p->pAig) ); // update the output number - RetValue = Ssw_SmlFindOutputCounterExample( p->pInit, pCex ); + RetValue = Saig_ManFindFailedPoCex( p->pInit, pCex ); assert( RetValue >= 0 && RetValue < Saig_ManPoNum(p->pInit) ); // invalid CEX!!! pCex->iPo = RetValue; // cleanup @@ -246,7 +249,15 @@ int Llb_CoreReachability_int( Llb_Img_t * p, Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQ bReached = Cudd_bddTransfer( p->ddR, p->ddG, bCurrent ); Cudd_Ref( bReached ); Cudd_RecursiveDeref( p->ddR, bCurrent ); // move init state to the working manager - bCurrent = Extra_TransferPermute( p->ddG, p->dd, bReached, pGlo2Loc ); Cudd_Ref( bCurrent ); + bCurrent = Extra_TransferPermute( p->ddG, p->dd, bReached, pGlo2Loc ); + if ( bCurrent == NULL ) + { + Cudd_RecursiveDeref( p->ddG, bReached ); + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during transfer 0.\n", p->pPars->TimeLimit ); + return -1; + } + Cudd_Ref( bCurrent ); } else { @@ -284,7 +295,17 @@ int Llb_CoreReachability_int( Llb_Img_t * p, Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQ } // save the onion ring - bTemp = Extra_TransferPermute( p->dd, p->ddR, bCurrent, pLoc2GloR ); Cudd_Ref( bTemp ); + bTemp = Extra_TransferPermute( p->dd, p->ddR, bCurrent, pLoc2GloR ); + if ( bTemp == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during image computation.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return -1; + } + Cudd_Ref( bTemp ); Vec_PtrPush( p->vRings, bTemp ); // check it for bad states @@ -327,7 +348,8 @@ int Llb_CoreReachability_int( Llb_Img_t * p, Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQ // bNext = Extra_TransferPermute( p->dd, p->ddG, bTemp = bNext, pLoc2Glo ); Cudd_Ref( bNext ); // Cudd_RecursiveDeref( p->dd, bTemp ); - bNext = Extra_TransferPermuteTime( p->dd, p->ddG, bTemp = bNext, pLoc2Glo, p->pPars->TimeTarget ); +// bNext = Extra_TransferPermuteTime( p->dd, p->ddG, bTemp = bNext, pLoc2Glo, p->pPars->TimeTarget ); + bNext = Extra_TransferPermute( p->dd, p->ddG, bTemp = bNext, pLoc2Glo ); if ( bNext == NULL ) { if ( !p->pPars->fSilent ) @@ -349,13 +371,24 @@ int Llb_CoreReachability_int( Llb_Img_t * p, Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQ } // get the new states - bCurrent = Cudd_bddAnd( p->ddG, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); + bCurrent = Cudd_bddAnd( p->ddG, bNext, Cudd_Not(bReached) ); + if ( bCurrent == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during image computation in transfer 2.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->ddG, bNext ); + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return -1; + } + Cudd_Ref( bCurrent ); // remap these states into the current state vars // bCurrent = Extra_TransferPermute( p->ddG, p->dd, bTemp = bCurrent, pGlo2Loc ); Cudd_Ref( bCurrent ); // Cudd_RecursiveDeref( p->ddG, bTemp ); - bCurrent = Extra_TransferPermuteTime( p->ddG, p->dd, bTemp = bCurrent, pGlo2Loc, p->pPars->TimeTarget ); +// bCurrent = Extra_TransferPermuteTime( p->ddG, p->dd, bTemp = bCurrent, pGlo2Loc, p->pPars->TimeTarget ); + bCurrent = Extra_TransferPermute( p->ddG, p->dd, bTemp = bCurrent, pGlo2Loc ); if ( bCurrent == NULL ) { if ( !p->pPars->fSilent ) diff --git a/src/aig/llb/llb2Driver.c b/src/aig/llb/llb2Driver.c index aab65317..3b4f23fc 100644 --- a/src/aig/llb/llb2Driver.c +++ b/src/aig/llb/llb2Driver.c @@ -129,7 +129,8 @@ DdNode * Llb_DriverPhaseCube( Aig_Man_t * pAig, Vec_Int_t * vDriRefs, DdManager { DdNode * bCube, * bVar, * bTemp; Aig_Obj_t * pObj; - int i; + int i, TimeStop; + TimeStop = dd->TimeStop; dd->TimeStop = 0; bCube = Cudd_ReadOne( dd ); Cudd_Ref( bCube ); Saig_ManForEachLi( pAig, pObj, i ) { @@ -143,6 +144,7 @@ DdNode * Llb_DriverPhaseCube( Aig_Man_t * pAig, Vec_Int_t * vDriRefs, DdManager Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bCube ); + dd->TimeStop = TimeStop; return bCube; } @@ -181,7 +183,8 @@ DdManager * Llb_DriverLastPartition( Aig_Man_t * p, Vec_Int_t * vVarsNs, int Tim bVar2 = Cudd_NotCond( bVar2, Aig_ObjFaninC0(pObj) ); bProd = Cudd_bddXnor( dd, bVar1, bVar2 ); Cudd_Ref( bProd ); // bRes = Cudd_bddAnd( dd, bTemp = bRes, bProd ); Cudd_Ref( bRes ); - bRes = Extra_bddAndTime( dd, bTemp = bRes, bProd, TimeTarget ); +// bRes = Extra_bddAndTime( dd, bTemp = bRes, bProd, TimeTarget ); + bRes = Cudd_bddAnd( dd, bTemp = bRes, bProd ); if ( bRes == NULL ) { Cudd_RecursiveDeref( dd, bTemp ); diff --git a/src/aig/llb/llb2Dump.c b/src/aig/llb/llb2Dump.c index 55f94907..3e1dd8c5 100644 --- a/src/aig/llb/llb2Dump.c +++ b/src/aig/llb/llb2Dump.c @@ -83,7 +83,7 @@ void Llb_ManDumpReached( DdManager * ddG, DdNode * bReached, char * pModel, char // write the file pFile = fopen( pFileName, "wb" ); - Cudd_DumpBlif( ddG, 1, &bReached, (char **)Vec_PtrArray(vNamesIn), (char **)Vec_PtrArray(vNamesOut), pModel, pFile ); + Cudd_DumpBlif( ddG, 1, &bReached, (char **)Vec_PtrArray(vNamesIn), (char **)Vec_PtrArray(vNamesOut), pModel, pFile, 0 ); fclose( pFile ); // cleanup diff --git a/src/aig/llb/llb2Flow.c b/src/aig/llb/llb2Flow.c index 36b3ff1b..1b177807 100644 --- a/src/aig/llb/llb2Flow.c +++ b/src/aig/llb/llb2Flow.c @@ -144,7 +144,7 @@ Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupp continue; if ( piFirst[i] == piLast[i] ) { - vMap = Vec_PtrEntry( vMaps, piFirst[i] ); + vMap = (Vec_Int_t *)Vec_PtrEntry( vMaps, piFirst[i] ); Vec_IntWriteEntry( vMap, pObj->Id, 2 ); continue; } @@ -152,7 +152,7 @@ Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupp // set support for all in between for ( k = piFirst[i]; k <= piLast[i]; k++ ) { - vMap = Vec_PtrEntry( vMaps, k ); + vMap = (Vec_Int_t *)Vec_PtrEntry( vMaps, k ); Vec_IntWriteEntry( vMap, pObj->Id, 1 ); } } @@ -165,8 +165,8 @@ Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupp printf( "%d ", Counter ); Vec_PtrForEachEntryStart( Vec_Int_t *, vMaps, vMap, i, 1 ) { - vPrev = Vec_PtrEntry( vMaps, i-1 ); - vNext = (i == Vec_PtrSize(vMaps)-1)? NULL: Vec_PtrEntry( vMaps, i+1 ); + vPrev = (Vec_Int_t *)Vec_PtrEntry( vMaps, i-1 ); + vNext = (i == Vec_PtrSize(vMaps)-1)? NULL: (Vec_Int_t *)Vec_PtrEntry( vMaps, i+1 ); CounterPlus = CounterMinus = 0; Aig_ManForEachObj( p, pObj, k ) @@ -1134,7 +1134,7 @@ void Llb_ManFlowGetObjSet( Aig_Man_t * p, Vec_Ptr_t * vLower, int iStart, int nS Vec_PtrClear( vSet ); for ( i = 0; i < nSize; i++ ) { - pObj = Vec_PtrEntry( vLower, (iStart + i) % Vec_PtrSize(vLower) ); + pObj = (Aig_Obj_t *)Vec_PtrEntry( vLower, (iStart + i) % Vec_PtrSize(vLower) ); Vec_PtrPush( vSet, pObj ); } } @@ -1334,7 +1334,7 @@ void Llb_ManMinCutTest( Aig_Man_t * pAig, int Num ) { extern void Llb_BddConstructTest( Aig_Man_t * p, Vec_Ptr_t * vResult ); extern void Llb_BddExperiment( Aig_Man_t * pInit, Aig_Man_t * pAig, Gia_ParLlb_t * pPars, Vec_Ptr_t * vResult, Vec_Ptr_t * vMaps ); - extern void Llb_CoreExperiment( Aig_Man_t * pInit, Aig_Man_t * pAig, Gia_ParLlb_t * pPars, Vec_Ptr_t * vResult ); + int fVerbose = 1; Gia_ParLlb_t Pars, * pPars = &Pars; @@ -1354,7 +1354,7 @@ void Llb_ManMinCutTest( Aig_Man_t * pAig, int Num ) // vMaps = Llb_ManCutMap( p, vResult, vSupps ); // Llb_BddExperiment( pAig, p, pPars, vResult, vMaps ); - Llb_CoreExperiment( pAig, p, pPars, vResult ); + Llb_CoreExperiment( pAig, p, pPars, vResult, 0 ); // Vec_VecFree( (Vec_Vec_t *)vMaps ); // Vec_VecFree( (Vec_Vec_t *)vSupps ); diff --git a/src/aig/llb/llb2Image.c b/src/aig/llb/llb2Image.c index 78ff9da1..caf8f9f7 100644 --- a/src/aig/llb/llb2Image.c +++ b/src/aig/llb/llb2Image.c @@ -200,7 +200,8 @@ DdManager * Llb_ImgPartition( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUp bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); // pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); - pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeTarget ); +// pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeTarget ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); if ( pObj->pData == NULL ) { Cudd_Quit( dd ); @@ -217,7 +218,8 @@ DdManager * Llb_ImgPartition( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUp assert( Aig_ObjIsNode(pObj) ); bProd = Cudd_bddXnor( dd, Cudd_bddIthVar(dd, Aig_ObjId(pObj)), (DdNode *)pObj->pData ); Cudd_Ref( bProd ); // bRes = Cudd_bddAnd( dd, bTemp = bRes, bProd ); Cudd_Ref( bRes ); - bRes = Extra_bddAndTime( dd, bTemp = bRes, bProd, TimeTarget ); +// bRes = Extra_bddAndTime( dd, bTemp = bRes, bProd, TimeTarget ); + bRes = Cudd_bddAnd( dd, bTemp = bRes, bProd ); if ( bRes == NULL ) { Cudd_Quit( dd ); @@ -257,7 +259,8 @@ DdNode * Llb_ImgComputeCube( Aig_Man_t * pAig, Vec_Int_t * vNodeIds, DdManager * { DdNode * bProd, * bTemp; Aig_Obj_t * pObj; - int i; + int i, TimeStop; + TimeStop = dd->TimeStop; dd->TimeStop = 0; bProd = Cudd_ReadOne(dd); Cudd_Ref( bProd ); Aig_ManForEachNodeVec( pAig, vNodeIds, pObj, i ) { @@ -265,6 +268,7 @@ DdNode * Llb_ImgComputeCube( Aig_Man_t * pAig, Vec_Int_t * vNodeIds, DdManager * Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bProd ); + dd->TimeStop = TimeStop; return bProd; } @@ -376,7 +380,14 @@ DdNode * Llb_ImgComputeImage( Aig_Man_t * pAig, Vec_Ptr_t * vDdMans, DdManager * { // quantify unique vriables bCube = Llb_ImgComputeCube( pAig, (Vec_Int_t *)Vec_PtrEntry(vQuant0, 0), dd ); Cudd_Ref( bCube ); - bImage = Cudd_bddExistAbstract( dd, bTemp = bImage, bCube ); Cudd_Ref( bImage ); + bImage = Cudd_bddExistAbstract( dd, bTemp = bImage, bCube ); + if ( bImage == NULL ) + { + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bCube ); + return NULL; + } + Cudd_Ref( bImage ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bCube ); } @@ -387,13 +398,17 @@ DdNode * Llb_ImgComputeImage( Aig_Man_t * pAig, Vec_Ptr_t * vDdMans, DdManager * if ( fVerbose ) printf( " %2d : ", i ); // transfer the BDD from the group manager to the main manager - bGroup = Cudd_bddTransfer( ddPart, dd, ddPart->bFunc ); Cudd_Ref( bGroup ); + bGroup = Cudd_bddTransfer( ddPart, dd, ddPart->bFunc ); + if ( bGroup == NULL ) + return NULL; + Cudd_Ref( bGroup ); if ( fVerbose ) printf( "Pt0 =%6d. Pt1 =%6d. ", Cudd_DagSize(ddPart->bFunc), Cudd_DagSize(bGroup) ); // perform partial product bCube = Llb_ImgComputeCube( pAig, (Vec_Int_t *)Vec_PtrEntry(vQuant1, i+1), dd ); Cudd_Ref( bCube ); // bImage = Cudd_bddAndAbstract( dd, bTemp = bImage, bGroup, bCube ); - bImage = Extra_bddAndAbstractTime( dd, bTemp = bImage, bGroup, bCube, TimeTarget ); +// bImage = Extra_bddAndAbstractTime( dd, bTemp = bImage, bGroup, bCube, TimeTarget ); + bImage = Cudd_bddAndAbstract( dd, bTemp = bImage, bGroup, bCube ); if ( bImage == NULL ) { Cudd_RecursiveDeref( dd, bTemp ); diff --git a/src/aig/llb/llb3Image.c b/src/aig/llb/llb3Image.c index 9bb01195..098f9f45 100644 --- a/src/aig/llb/llb3Image.c +++ b/src/aig/llb/llb3Image.c @@ -50,7 +50,6 @@ struct Llb_Mgr_t_ Vec_Ptr_t * vLeaves; // leaves in the AIG manager Vec_Ptr_t * vRoots; // roots in the AIG manager DdManager * dd; // working BDD manager - DdNode * bCurrent; // current state functions in terms of vLeaves int * pVars2Q; // variables to quantify // internal Llb_Prt_t ** pParts; // partitions @@ -141,7 +140,8 @@ DdNode * Llb_NonlinCreateCube1( Llb_Mgr_t * p, Llb_Prt_t * pPart ) { DdNode * bCube, * bTemp; Llb_Var_t * pVar; - int i; + int i, TimeStop; + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; bCube = Cudd_ReadOne(p->dd); Cudd_Ref( bCube ); Llb_PartForEachVar( p, pPart, pVar, i ) { @@ -153,6 +153,7 @@ DdNode * Llb_NonlinCreateCube1( Llb_Mgr_t * p, Llb_Prt_t * pPart ) Cudd_RecursiveDeref( p->dd, bTemp ); } Cudd_Deref( bCube ); + p->dd->TimeStop = TimeStop; return bCube; } @@ -171,7 +172,8 @@ DdNode * Llb_NonlinCreateCube2( Llb_Mgr_t * p, Llb_Prt_t * pPart1, Llb_Prt_t * p { DdNode * bCube, * bTemp; Llb_Var_t * pVar; - int i; + int i, TimeStop; + TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; bCube = Cudd_ReadOne(p->dd); Cudd_Ref( bCube ); Llb_PartForEachVar( p, pPart1, pVar, i ) { @@ -186,6 +188,7 @@ DdNode * Llb_NonlinCreateCube2( Llb_Mgr_t * p, Llb_Prt_t * pPart1, Llb_Prt_t * p } } Cudd_Deref( bCube ); + p->dd->TimeStop = TimeStop; return bCube; } @@ -376,7 +379,8 @@ Extra_bddPrintSupport( p->dd, bCube ); printf( "\n" ); Cudd_Ref( bFunc ); */ - bFunc = Extra_bddAndAbstractTime( p->dd, pPart1->bFunc, pPart2->bFunc, bCube, TimeOut ); +// bFunc = Extra_bddAndAbstractTime( p->dd, pPart1->bFunc, pPart2->bFunc, bCube, TimeOut ); + bFunc = Cudd_bddAndAbstract( p->dd, pPart1->bFunc, pPart2->bFunc, bCube ); if ( bFunc == NULL ) { Cudd_RecursiveDeref( p->dd, bCube ); @@ -549,7 +553,8 @@ Vec_Ptr_t * Llb_NonlinBuildBdds( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * { bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); - pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeOut ); +// pObj->pData = Extra_bddAndTime( dd, bBdd0, bBdd1, TimeOut ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); if ( pObj->pData == NULL ) { Vec_PtrForEachEntryStop( Aig_Obj_t *, vNodes, pObj, k, i ) @@ -618,42 +623,51 @@ void Llb_NonlinAddPair( Llb_Mgr_t * p, DdNode * bFunc, int iPart, int iVar ) SeeAlso [] ***********************************************************************/ +void Llb_NonlinAddPartition( Llb_Mgr_t * p, int i, DdNode * bFunc ) +{ + int k, nSuppSize; + assert( !Cudd_IsConstant(bFunc) ); + // create partition + p->pParts[i] = ABC_CALLOC( Llb_Prt_t, 1 ); + p->pParts[i]->iPart = i; + p->pParts[i]->bFunc = bFunc; + p->pParts[i]->vVars = Vec_IntAlloc( 8 ); + // add support dependencies + nSuppSize = 0; + Extra_SupportArray( p->dd, bFunc, p->pSupp ); + for ( k = 0; k < p->nVars; k++ ) + { + nSuppSize += p->pSupp[k]; + if ( p->pSupp[k] && p->pVars2Q[k] ) + Llb_NonlinAddPair( p, bFunc, i, k ); + } + p->nSuppMax = ABC_MAX( p->nSuppMax, nSuppSize ); +} + +/**Function************************************************************* + + Synopsis [Starts non-linear quantification scheduling.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Llb_NonlinStart( Llb_Mgr_t * p, int TimeOut ) { Vec_Ptr_t * vRootBdds; - Llb_Prt_t * pPart; DdNode * bFunc; - int i, k, nSuppSize; + int i; // create and collect BDDs vRootBdds = Llb_NonlinBuildBdds( p->pAig, p->vLeaves, p->vRoots, p->dd, TimeOut ); // come referenced if ( vRootBdds == NULL ) return 0; - Vec_PtrPush( vRootBdds, p->bCurrent ); // add pairs (refs are consumed inside) Vec_PtrForEachEntry( DdNode *, vRootBdds, bFunc, i ) - { - assert( !Cudd_IsConstant(bFunc) ); - // create partition - p->pParts[i] = ABC_CALLOC( Llb_Prt_t, 1 ); - p->pParts[i]->iPart = i; - p->pParts[i]->bFunc = bFunc; - p->pParts[i]->vVars = Vec_IntAlloc( 8 ); - // add support dependencies - nSuppSize = 0; - Extra_SupportArray( p->dd, bFunc, p->pSupp ); - for ( k = 0; k < p->nVars; k++ ) - { - nSuppSize += p->pSupp[k]; - if ( p->pSupp[k] && p->pVars2Q[k] ) - Llb_NonlinAddPair( p, bFunc, i, k ); - } - p->nSuppMax = ABC_MAX( p->nSuppMax, nSuppSize ); - } + Llb_NonlinAddPartition( p, i, bFunc ); Vec_PtrFree( vRootBdds ); - // remove singles - Llb_MgrForEachPart( p, pPart, i ) - if ( Llb_NonlinHasSingletonVars(p, pPart) ) - Llb_NonlinQuantify1( p, pPart, 0 ); return 1; } @@ -666,8 +680,7 @@ int Llb_NonlinStart( Llb_Mgr_t * p, int TimeOut ) SideEffects [] SeeAlso [] - -***********************************************************************/ +**********************************************************************/ void Llb_NonlinCheckVars( Llb_Mgr_t * p ) { Llb_Var_t * pVar; @@ -730,7 +743,7 @@ int Llb_NonlinNextPartitions( Llb_Mgr_t * p, Llb_Prt_t ** ppPart1, Llb_Prt_t ** SeeAlso [] ***********************************************************************/ -void Llb_NonlinReorder( DdManager * dd, int fVerbose ) +void Llb_NonlinReorder( DdManager * dd, int fTwice, int fVerbose ) { int clk = clock(); if ( fVerbose ) @@ -738,9 +751,12 @@ void Llb_NonlinReorder( DdManager * dd, int fVerbose ) Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); if ( fVerbose ) Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); - if ( fVerbose ) - Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + if ( fTwice ) + { + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); + if ( fVerbose ) + Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + } if ( fVerbose ) Abc_PrintTime( 1, "Time", clock() - clk ); } @@ -809,7 +825,7 @@ void Llb_NonlinVerifyScores( Llb_Mgr_t * p ) SeeAlso [] ***********************************************************************/ -Llb_Mgr_t * Llb_NonlinAlloc( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q, DdManager * dd, DdNode * bCurrent ) +Llb_Mgr_t * Llb_NonlinAlloc( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q, DdManager * dd ) { Llb_Mgr_t * p; p = ABC_CALLOC( Llb_Mgr_t, 1 ); @@ -817,12 +833,11 @@ Llb_Mgr_t * Llb_NonlinAlloc( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * p->vLeaves = vLeaves; p->vRoots = vRoots; p->dd = dd; - p->bCurrent = bCurrent; p->pVars2Q = pVars2Q; p->nVars = Cudd_ReadSize(dd); - p->iPartFree = Vec_PtrSize(vRoots) + 1; + p->iPartFree = Vec_PtrSize(vRoots); p->pVars = ABC_CALLOC( Llb_Var_t *, p->nVars ); - p->pParts = ABC_CALLOC( Llb_Prt_t *, 2 * p->iPartFree ); + p->pParts = ABC_CALLOC( Llb_Prt_t *, 2 * p->iPartFree + 2 ); p->pSupp = ABC_ALLOC( int, Cudd_ReadSize(dd) ); return p; } @@ -874,17 +889,24 @@ DdNode * Llb_NonlinImage( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRo int clk = clock(), clk2; // start the manager clk2 = clock(); - p = Llb_NonlinAlloc( pAig, vLeaves, vRoots, pVars2Q, dd, bCurrent ); + p = Llb_NonlinAlloc( pAig, vLeaves, vRoots, pVars2Q, dd ); if ( !Llb_NonlinStart( p, TimeOut ) ) { Llb_NonlinFree( p ); return NULL; } + // add partition + Llb_NonlinAddPartition( p, p->iPartFree++, bCurrent ); + // remove singles + Llb_MgrForEachPart( p, pPart, i ) + if ( Llb_NonlinHasSingletonVars(p, pPart) ) + Llb_NonlinQuantify1( p, pPart, 0 ); timeBuild += clock() - clk2; timeInside = clock() - clk2; // compute scores Llb_NonlinRecomputeScores( p ); // save permutation + if ( pOrder ) memcpy( pOrder, dd->invperm, sizeof(int) * dd->size ); // iteratively quantify variables while ( Llb_NonlinNextPartitions(p, &pPart1, &pPart2) ) @@ -914,13 +936,152 @@ DdNode * Llb_NonlinImage( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRo Llb_NonlinFree( p ); // reorder variables if ( fReorder ) - Llb_NonlinReorder( dd, fVerbose ); + Llb_NonlinReorder( dd, 0, fVerbose ); timeOther += clock() - clk - timeInside; // return Cudd_Deref( bFunc ); return bFunc; } + + +static Llb_Mgr_t * p = NULL; + +/**Function************************************************************* + + Synopsis [Starts image computation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdManager * Llb_NonlinImageStart( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q, int * pOrder, int fFirst ) +{ + DdManager * dd; + int clk = clock(); + assert( p == NULL ); + // start a new manager (disable reordering) + dd = Cudd_Init( Aig_ManObjNumMax(pAig), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_ShuffleHeap( dd, pOrder ); +// if ( fFirst ) + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + // start the manager + p = Llb_NonlinAlloc( pAig, vLeaves, vRoots, pVars2Q, dd ); + if ( !Llb_NonlinStart( p, 0 ) ) + { + Llb_NonlinFree( p ); + return NULL; + } + timeBuild += clock() - clk; +// if ( !fFirst ) +// Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + return dd; +} + +/**Function************************************************************* + + Synopsis [Performs image computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_NonlinImageCompute( DdNode * bCurrent, int fReorder, int fDrop, int fVerbose, int * pOrder ) +{ + Llb_Prt_t * pPart, * pPart1, * pPart2; + DdNode * bFunc, * bTemp; + int i, nReorders, timeInside = 0; + int clk = clock(), clk2; + + // add partition + Llb_NonlinAddPartition( p, p->iPartFree++, bCurrent ); + // remove singles + Llb_MgrForEachPart( p, pPart, i ) + if ( Llb_NonlinHasSingletonVars(p, pPart) ) + Llb_NonlinQuantify1( p, pPart, 0 ); + // reorder + if ( fReorder ) + Llb_NonlinReorder( p->dd, 0, 0 ); + // save permutation + memcpy( pOrder, p->dd->invperm, sizeof(int) * p->dd->size ); + + // compute scores + Llb_NonlinRecomputeScores( p ); + // iteratively quantify variables + while ( Llb_NonlinNextPartitions(p, &pPart1, &pPart2) ) + { + clk2 = clock(); + nReorders = Cudd_ReadReorderings(p->dd); + if ( !Llb_NonlinQuantify2( p, pPart1, pPart2, 0, 0 ) ) + { + Llb_NonlinFree( p ); + return NULL; + } + timeAndEx += clock() - clk2; + timeInside += clock() - clk2; + if ( nReorders < Cudd_ReadReorderings(p->dd) ) + Llb_NonlinRecomputeScores( p ); +// else +// Llb_NonlinVerifyScores( p ); + } + // load partitions + bFunc = Cudd_ReadOne(p->dd); Cudd_Ref( bFunc ); + Llb_MgrForEachPart( p, pPart, i ) + { + bFunc = Cudd_bddAnd( p->dd, bTemp = bFunc, pPart->bFunc ); + if ( bFunc == NULL ) + { + Cudd_RecursiveDeref( p->dd, bTemp ); + Llb_NonlinFree( p ); + return NULL; + } + Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + nSuppMax = p->nSuppMax; + // reorder variables +// if ( fReorder ) +// Llb_NonlinReorder( p->dd, 0, fVerbose ); + // save permutation +// memcpy( pOrder, p->dd->invperm, sizeof(int) * Cudd_ReadSize(p->dd) ); + + timeOther += clock() - clk - timeInside; + // return + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Quits image computation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_NonlinImageQuit() +{ + DdManager * dd; + if ( p == NULL ) + return; + dd = p->dd; + Llb_NonlinFree( p ); + if ( dd->bFunc ) + Cudd_RecursiveDeref( dd, dd->bFunc ); + Extra_StopManager( dd ); +// Cudd_Quit ( dd ); + p = NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/llb/llb3Nonlin.c b/src/aig/llb/llb3Nonlin.c index adab5b0b..6a0c871e 100644 --- a/src/aig/llb/llb3Nonlin.c +++ b/src/aig/llb/llb3Nonlin.c @@ -42,13 +42,18 @@ struct Llb_Mnn_t_ Vec_Ptr_t * vLeaves; Vec_Ptr_t * vRoots; int * pVars2Q; - int * pOrder; + int * pOrderL; + int * pOrderL2; + int * pOrderG; Vec_Int_t * vCs2Glo; // cur state variables into global variables Vec_Int_t * vNs2Glo; // next state variables into global variables Vec_Int_t * vGlo2Cs; // global variables into cur state variables Vec_Int_t * vGlo2Ns; // global variables into next state variables + int ddLocReos; + int ddLocGrbs; + int timeImage; int timeTran1; int timeTran2; @@ -210,7 +215,8 @@ DdNode * Llb_NonlinComputeInitState( Aig_Man_t * pAig, DdManager * dd ) { Aig_Obj_t * pObj; DdNode * bRes, * bVar, * bTemp; - int i, iVar; + int i, iVar, TimeStop; + TimeStop = dd->TimeStop; dd->TimeStop = 0; bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes ); Saig_ManForEachLo( pAig, pObj, i ) { @@ -220,6 +226,7 @@ DdNode * Llb_NonlinComputeInitState( Aig_Man_t * pAig, DdManager * dd ) Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bRes ); + dd->TimeStop = TimeStop; return bRes; } @@ -237,8 +244,6 @@ DdNode * Llb_NonlinComputeInitState( Aig_Man_t * pAig, DdManager * dd ) ***********************************************************************/ Abc_Cex_t * Llb_NonlinDeriveCex( Llb_Mnn_t * p ) { - extern Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); - extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); Abc_Cex_t * pCex; Aig_Obj_t * pObj; Vec_Int_t * vVarsNs; @@ -247,6 +252,9 @@ Abc_Cex_t * Llb_NonlinDeriveCex( Llb_Mnn_t * p ) char * pValues = ABC_ALLOC( char, Cudd_ReadSize(p->ddR) ); assert( Vec_PtrSize(p->vRings) > 0 ); + p->dd->TimeStop = 0; + p->ddR->TimeStop = 0; + // update quantifiable vars memset( p->pVars2Q, 0, sizeof(int) * Cudd_ReadSize(p->dd) ); vVarsNs = Vec_IntAlloc( Aig_ManRegNum(p->pAig) ); @@ -264,12 +272,12 @@ Abc_Cex_t * Llb_NonlinDeriveCex( Llb_Mnn_t * p ) printf( "\n" ); */ // allocate room for the counter-example - pCex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) ); + pCex = Abc_CexAlloc( Saig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Vec_PtrSize(p->vRings) ); pCex->iFrame = Vec_PtrSize(p->vRings) - 1; pCex->iPo = -1; // get the last cube - bOneCube = Cudd_bddIntersect( p->ddR, Vec_PtrEntryLast(p->vRings), p->ddR->bFunc ); Cudd_Ref( bOneCube ); + bOneCube = Cudd_bddIntersect( p->ddR, (DdNode *)Vec_PtrEntryLast(p->vRings), p->ddR->bFunc ); Cudd_Ref( bOneCube ); RetValue = Cudd_bddPickOneCube( p->ddR, bOneCube, pValues ); Cudd_RecursiveDeref( p->ddR, bOneCube ); assert( RetValue ); @@ -294,7 +302,7 @@ Abc_Cex_t * Llb_NonlinDeriveCex( Llb_Mnn_t * p ) //Extra_bddPrintSupport( p->dd, bRing ); printf( "\n" ); // compute the next states bImage = Llb_NonlinImage( p->pAig, p->vLeaves, p->vRoots, p->pVars2Q, p->dd, bState, - p->pPars->fReorder, p->pPars->fVeryVerbose, p->pOrder, ABC_INFINITY, ABC_INFINITY ); // consumed reference + p->pPars->fReorder, p->pPars->fVeryVerbose, NULL, ABC_INFINITY, ABC_INFINITY ); // consumed reference assert( bImage != NULL ); Cudd_Ref( bImage ); //Extra_bddPrintSupport( p->dd, bImage ); printf( "\n" ); @@ -331,7 +339,8 @@ Abc_Cex_t * Llb_NonlinDeriveCex( Llb_Mnn_t * p ) } assert( nPiOffset == Saig_ManRegNum(p->pAig) ); // update the output number - RetValue = Ssw_SmlFindOutputCounterExample( p->pInit, pCex ); +//Abc_CexPrint( pCex ); + RetValue = Saig_ManFindFailedPoCex( p->pInit, pCex ); assert( RetValue >= 0 && RetValue < Saig_ManPoNum(p->pInit) ); // invalid CEX!!! pCex->iPo = RetValue; // cleanup @@ -389,10 +398,37 @@ int Llb_NonlinReoHook( DdManager * dd, char * Type, void * Method ) SeeAlso [] ***********************************************************************/ +int Llb_NonlinCompPerms( DdManager * dd, int * pVar2Lev ) +{ + DdSubtable * pSubt; + int i, Sum = 0, Entry; + for ( i = 0; i < dd->size; i++ ) + { + pSubt = &(dd->subtables[dd->perm[i]]); + if ( pSubt->keys == pSubt->dead + 1 ) + continue; + Entry = ABC_MAX(dd->perm[i], pVar2Lev[i]) - ABC_MIN(dd->perm[i], pVar2Lev[i]); + Sum += Entry; +//printf( "%d-%d(%d) ", dd->perm[i], pV2L[i], Entry ); + } + return Sum; +} + +/**Function************************************************************* + + Synopsis [Perform reachability with hints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Llb_NonlinReachability( Llb_Mnn_t * p ) { - DdNode * bCurrent, * bNext, * bTemp; - int iVar, nIters, nBddSize0, nBddSize, Limit = p->pPars->nBddMax; + DdNode * bTemp, * bNext; + int nIters, nBddSize0, nBddSize, NumCmp, Limit = p->pPars->nBddMax; int clk2, clk3, clk = clock(); assert( Aig_ManRegNum(p->pAig) > 0 ); @@ -421,7 +457,9 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) } Cudd_Ref( p->ddR->bFunc ); // compute the starting set of states - bCurrent = Llb_NonlinComputeInitState( p->pAig, p->dd ); Cudd_Ref( bCurrent ); + Cudd_Quit( p->dd ); + p->dd = Llb_NonlinImageStart( p->pAig, p->vLeaves, p->vRoots, p->pVars2Q, p->pOrderL, 1 ); + p->dd->bFunc = Llb_NonlinComputeInitState( p->pAig, p->dd ); Cudd_Ref( p->dd->bFunc ); // current p->ddG->bFunc = Llb_NonlinComputeInitState( p->pAig, p->ddG ); Cudd_Ref( p->ddG->bFunc ); // reached p->ddG->bFunc2 = Llb_NonlinComputeInitState( p->pAig, p->ddG ); Cudd_Ref( p->ddG->bFunc2 ); // frontier for ( nIters = 0; nIters < p->pPars->nIterMax; nIters++ ) @@ -433,12 +471,21 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) if ( !p->pPars->fSilent ) printf( "Reached timeout (%d seconds) during image computation.\n", p->pPars->TimeLimit ); p->pPars->iFrame = nIters - 1; - Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Llb_NonlinImageQuit(); return -1; } // save the onion ring - bTemp = Extra_TransferPermute( p->dd, p->ddR, bCurrent, Vec_IntArray(p->vCs2Glo) ); Cudd_Ref( bTemp ); + bTemp = Extra_TransferPermute( p->dd, p->ddR, p->dd->bFunc, Vec_IntArray(p->vCs2Glo) ); + if ( bTemp == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during ring transfer.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Llb_NonlinImageQuit(); + return -1; + } + Cudd_Ref( bTemp ); Vec_PtrPush( p->vRings, bTemp ); // check it for bad states @@ -447,7 +494,6 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) assert( p->pInit->pSeqModel == NULL ); if ( !p->pPars->fBackward ) p->pInit->pSeqModel = Llb_NonlinDeriveCex( p ); - Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; if ( !p->pPars->fSilent ) { if ( !p->pPars->fBackward ) @@ -456,124 +502,110 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) printf( "Output ??? was asserted in frame %d (counter-example is not produced). ", nIters ); Abc_PrintTime( 1, "Time", clock() - clk ); } + Llb_NonlinImageQuit(); return 0; } - // check the size - if ( Cudd_DagSize(bCurrent) > p->pPars->nBddMax ) - { - DdNode * bVar, * bVarG; - - // find the best variable - iVar = Llb_NonlinFindBestVar( p->dd, bCurrent, p->pAig ); - - // get cofactor in the working manager - bVar = Cudd_bddIthVar( p->dd, Aig_ObjId(Saig_ManLo(p->pAig,iVar)) ); - bCurrent = Cudd_bddAnd( p->dd, bTemp = bCurrent, Cudd_Not(bVar) ); Cudd_Ref( bCurrent ); - Cudd_RecursiveDeref( p->dd, bTemp ); - - // get cofactor in the global manager - bVarG = Cudd_bddIthVar(p->ddG, iVar); - p->ddG->bFunc2 = Cudd_bddAnd( p->ddG, bTemp = p->ddG->bFunc2, Cudd_Not(bVarG) ); Cudd_Ref( p->ddG->bFunc2 ); - Cudd_RecursiveDeref( p->ddG, bTemp ); - } - // compute the next states clk3 = clock(); - nBddSize0 = Cudd_DagSize( bCurrent ); - bNext = Llb_NonlinImage( p->pAig, p->vLeaves, p->vRoots, p->pVars2Q, p->dd, bCurrent, -// p->pPars->fReorder, p->pPars->fVeryVerbose, p->pOrder, nIters ? p->pPars->nBddMax : ABC_INFINITY ); - p->pPars->fReorder, p->pPars->fVeryVerbose, p->pOrder, ABC_INFINITY, p->pPars->TimeTarget ); -// Abc_PrintTime( 1, "Image time", clock() - clk3 ); + nBddSize0 = Cudd_DagSize( p->dd->bFunc ); + bNext = Llb_NonlinImageCompute( p->dd->bFunc, p->pPars->fReorder, 0, 1, p->pOrderL ); // consumes ref +// bNext = Llb_NonlinImage( p->pAig, p->vLeaves, p->vRoots, p->pVars2Q, p->dd, bCurrent, +// p->pPars->fReorder, p->pPars->fVeryVerbose, NULL, ABC_INFINITY, p->pPars->TimeTarget ); if ( bNext == NULL ) { if ( !p->pPars->fSilent ) printf( "Reached timeout (%d seconds) during image computation in quantification.\n", p->pPars->TimeLimit ); p->pPars->iFrame = nIters - 1; - Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Llb_NonlinImageQuit(); return -1; } - if ( bNext == NULL ) // Llb_NonlimImage() consumes reference of bCurrent!!! - { - DdNode * bVar, * bVarG; -// if ( !p->pPars->fSilent ) -// printf( "Reached timeout during image computation (%d seconds).\n", p->pPars->TimeLimit ); -// p->pPars->iFrame = nIters - 1; -// return -1; - - printf( "Should never happen!\n" ); - - // get the frontier in the working manager - bCurrent = Extra_TransferPermute( p->ddG, p->dd, p->ddG->bFunc2, Vec_IntArray(p->vGlo2Cs) ); Cudd_Ref( bCurrent ); - - // find the best variable - iVar = Llb_NonlinFindBestVar( p->dd, bCurrent, p->pAig ); - - // get cofactor in the working manager - bVar = Cudd_bddIthVar( p->dd, Aig_ObjId(Saig_ManLo(p->pAig,iVar)) ); - bCurrent = Cudd_bddAnd( p->dd, bTemp = bCurrent, Cudd_Not(bVar) ); Cudd_Ref( bCurrent ); - Cudd_RecursiveDeref( p->dd, bTemp ); - - // get cofactor in the global manager - bVarG = Cudd_bddIthVar(p->dd, iVar); - p->ddG->bFunc2 = Cudd_bddAnd( p->ddG, bTemp = p->ddG->bFunc2, Cudd_Not(bVarG) ); Cudd_Ref( p->ddG->bFunc2 ); - Cudd_RecursiveDeref( p->ddG, bTemp ); - -// Cudd_ReduceHeap( p->dd, CUDD_REORDER_SIFT, 1 ); - p->pPars->nBddMax = ABC_INFINITY; - nIters--; - continue; - } - else - p->pPars->nBddMax = Limit; - Cudd_Ref( bNext ); nBddSize = Cudd_DagSize( bNext ); p->timeImage += clock() - clk3; + // transfer to the state manager clk3 = clock(); Cudd_RecursiveDeref( p->ddG, p->ddG->bFunc2 ); - p->ddG->bFunc2 = Extra_TransferPermuteTime( p->dd, p->ddG, bNext, Vec_IntArray(p->vNs2Glo), p->pPars->TimeTarget ); + p->ddG->bFunc2 = Extra_TransferPermute( p->dd, p->ddG, bNext, Vec_IntArray(p->vNs2Glo) ); +// p->ddG->bFunc2 = Extra_bddAndPermute( p->ddG, Cudd_Not(p->ddG->bFunc), p->dd, bNext, Vec_IntArray(p->vNs2Glo) ); if ( p->ddG->bFunc2 == NULL ) { if ( !p->pPars->fSilent ) printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit ); p->pPars->iFrame = nIters - 1; Cudd_RecursiveDeref( p->dd, bNext ); + Llb_NonlinImageQuit(); return -1; } Cudd_Ref( p->ddG->bFunc2 ); Cudd_RecursiveDeref( p->dd, bNext ); p->timeTran1 += clock() - clk3; + // save permutation + NumCmp = Llb_NonlinCompPerms( p->dd, p->pOrderL2 ); + // save order before image computation + memcpy( p->pOrderL2, p->dd->perm, sizeof(int) * p->dd->size ); + // update the image computation manager + p->timeReo += Cudd_ReadReorderingTime(p->dd); + p->ddLocReos += Cudd_ReadReorderings(p->dd); + p->ddLocGrbs += Cudd_ReadGarbageCollections(p->dd); + Llb_NonlinImageQuit(); + p->dd = Llb_NonlinImageStart( p->pAig, p->vLeaves, p->vRoots, p->pVars2Q, p->pOrderL, 0 ); + //Extra_TestAndPerm( p->ddG, Cudd_Not(p->ddG->bFunc), p->ddG->bFunc2 ); + // derive new states clk3 = clock(); - p->ddG->bFunc2 = Cudd_bddAnd( p->ddG, bTemp = p->ddG->bFunc2, Cudd_Not(p->ddG->bFunc) ); Cudd_Ref( p->ddG->bFunc2 ); + p->ddG->bFunc2 = Cudd_bddAnd( p->ddG, bTemp = p->ddG->bFunc2, Cudd_Not(p->ddG->bFunc) ); + if ( p->ddG->bFunc2 == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->ddG, bTemp ); + Llb_NonlinImageQuit(); + return -1; + } + Cudd_Ref( p->ddG->bFunc2 ); Cudd_RecursiveDeref( p->ddG, bTemp ); + p->timeGloba += clock() - clk3; + if ( Cudd_IsConstant(p->ddG->bFunc2) ) break; // add to the reached set - p->ddG->bFunc = Cudd_bddOr( p->ddG, bTemp = p->ddG->bFunc, p->ddG->bFunc2 ); Cudd_Ref( p->ddG->bFunc ); + clk3 = clock(); + p->ddG->bFunc = Cudd_bddOr( p->ddG, bTemp = p->ddG->bFunc, p->ddG->bFunc2 ); + if ( p->ddG->bFunc == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->ddG, bTemp ); + Llb_NonlinImageQuit(); + return -1; + } + Cudd_Ref( p->ddG->bFunc ); Cudd_RecursiveDeref( p->ddG, bTemp ); p->timeGloba += clock() - clk3; // reset permutation // RetValue = Cudd_CheckZeroRef( dd ); // assert( RetValue == 0 ); -// Cudd_ShuffleHeap( dd, pOrder ); +// Cudd_ShuffleHeap( dd, pOrderG ); // move new states to the working manager clk3 = clock(); - bCurrent = Extra_TransferPermuteTime( p->ddG, p->dd, p->ddG->bFunc2, Vec_IntArray(p->vGlo2Cs), p->pPars->TimeTarget ); - if ( bCurrent == NULL ) + p->dd->bFunc = Extra_TransferPermute( p->ddG, p->dd, p->ddG->bFunc2, Vec_IntArray(p->vGlo2Cs) ); + if ( p->dd->bFunc == NULL ) { if ( !p->pPars->fSilent ) printf( "Reached timeout (%d seconds) during image computation in transfer 2.\n", p->pPars->TimeLimit ); p->pPars->iFrame = nIters - 1; + Llb_NonlinImageQuit(); return -1; } - Cudd_Ref( bCurrent ); + Cudd_Ref( p->dd->bFunc ); p->timeTran2 += clock() - clk3; // report the results @@ -582,11 +614,14 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) printf( "I =%3d : ", nIters ); printf( "Fr =%7d ", nBddSize0 ); printf( "Im =%7d ", nBddSize ); - printf( "(%4d %4d) ", Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) ); + printf( "(%4d %4d) ", p->ddLocReos, p->ddLocGrbs ); printf( "Rea =%6d ", Cudd_DagSize(p->ddG->bFunc) ); printf( "(%4d %4d) ", Cudd_ReadReorderings(p->ddG), Cudd_ReadGarbageCollections(p->ddG) ); printf( "S =%4d ", nSuppMax ); + printf( "cL =%5d ", NumCmp ); + printf( "cG =%5d ", Llb_NonlinCompPerms( p->ddG, p->pOrderG ) ); Abc_PrintTime( 1, "T", clock() - clk2 ); + memcpy( p->pOrderG, p->ddG->perm, sizeof(int) * p->ddG->size ); } /* if ( pPars->fVerbose ) @@ -597,18 +632,16 @@ int Llb_NonlinReachability( Llb_Mnn_t * p ) fflush( stdout ); } */ - if ( nIters == p->pPars->nIterMax - 1 ) { if ( !p->pPars->fSilent ) printf( "Reached limit on the number of timeframes (%d).\n", p->pPars->nIterMax ); p->pPars->iFrame = nIters; - Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Llb_NonlinImageQuit(); return -1; } -// Llb_NonlinReorder( p->ddG, 1 ); -// Llb_NonlinFindBestVar( p->ddG, bReached, NULL ); } + Llb_NonlinImageQuit(); // report the stats if ( p->pPars->fVerbose ) @@ -671,10 +704,14 @@ Llb_Mnn_t * Llb_MnnStart( Aig_Man_t * pInit, Aig_Man_t * pAig, Gia_ParLlb_t * p Saig_ManForEachLi( pAig, pObj, i ) Vec_PtrPush( p->vRoots, pObj ); // variables to quantify - p->pOrder = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); + p->pOrderL = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); + p->pOrderL2= ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); + p->pOrderG = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); p->pVars2Q = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); Aig_ManForEachPi( pAig, pObj, i ) p->pVars2Q[Aig_ObjId(pObj)] = 1; + for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ ) + p->pOrderL[i] = p->pOrderL2[i] = p->pOrderG[i] = i; Llb_NonlinPrepareVarMap( p ); return p; } @@ -697,7 +734,6 @@ void Llb_MnnStop( Llb_Mnn_t * p ) if ( p->pPars->fVerbose ) { p->timeOther = p->timeTotal - p->timeImage - p->timeTran1 - p->timeTran2 - p->timeGloba; - p->timeReo = Cudd_ReadReorderingTime(p->dd); p->timeReoG = Cudd_ReadReorderingTime(p->ddG); ABC_PRTP( "Image ", p->timeImage, p->timeTotal ); ABC_PRTP( " build ", timeBuild, p->timeTotal ); @@ -711,7 +747,6 @@ void Llb_MnnStop( Llb_Mnn_t * p ) ABC_PRTP( " reo ", p->timeReo, p->timeTotal ); ABC_PRTP( " reoG ", p->timeReoG, p->timeTotal ); } - p->dd->bFunc = NULL; if ( p->ddR->bFunc ) Cudd_RecursiveDeref( p->ddR, p->ddR->bFunc ); Vec_PtrForEachEntry( DdNode *, p->vRings, bTemp, i ) @@ -722,7 +757,7 @@ void Llb_MnnStop( Llb_Mnn_t * p ) if ( p->ddG->bFunc2 ) Cudd_RecursiveDeref( p->ddG, p->ddG->bFunc2 ); // printf( "manager1\n" ); - Extra_StopManager( p->dd ); +// Extra_StopManager( p->dd ); // printf( "manager2\n" ); Extra_StopManager( p->ddG ); // printf( "manager3\n" ); @@ -734,7 +769,9 @@ void Llb_MnnStop( Llb_Mnn_t * p ) Vec_PtrFree( p->vLeaves ); Vec_PtrFree( p->vRoots ); ABC_FREE( p->pVars2Q ); - ABC_FREE( p->pOrder ); + ABC_FREE( p->pOrderL ); + ABC_FREE( p->pOrderL2 ); + ABC_FREE( p->pOrderG ); ABC_FREE( p ); } diff --git a/src/aig/llb/llbInt.h b/src/aig/llb/llbInt.h index 3ee1f5c2..dd938436 100644 --- a/src/aig/llb/llbInt.h +++ b/src/aig/llb/llbInt.h @@ -29,6 +29,7 @@ #include <stdio.h> #include "aig.h" #include "saig.h" +#include "ssw.h" #include "cuddInt.h" #include "extra.h" #include "llb.h" @@ -54,16 +55,20 @@ struct Llb_Man_t_ Aig_Man_t * pAig; // derived AIG manager (created in this package) DdManager * dd; // BDD manager DdManager * ddG; // BDD manager + DdManager * ddR; // BDD manager Vec_Int_t * vObj2Var; // mapping AIG ObjId into BDD var index Vec_Int_t * vVar2Obj; // mapping BDD var index into AIG ObjId Vec_Ptr_t * vGroups; // group Id into group pointer Llb_Mtr_t * pMatrix; // dependency matrix // image computation + Vec_Ptr_t * vRings; // onion rings Vec_Int_t * vVarBegs; // the first group where the var appears Vec_Int_t * vVarEnds; // the last group where the var appears // variable mapping Vec_Int_t * vNs2Glo; // next state variables into global variables + Vec_Int_t * vCs2Glo; // next state variables into global variables Vec_Int_t * vGlo2Cs; // global variables into current state variables + Vec_Int_t * vGlo2Ns; // global variables into current state variables // flow computation // Vec_Int_t * vMem; // Vec_Ptr_t * vTops; @@ -150,6 +155,7 @@ extern DdNode * Llb_BddComputeBad( Aig_Man_t * pInit, DdManager * dd, int extern DdNode * Llb_BddQuantifyPis( Aig_Man_t * pInit, DdManager * dd, DdNode * bFunc ); /*=== llb2Core.c ======================================================*/ extern DdNode * Llb_CoreComputeCube( DdManager * dd, Vec_Int_t * vVars, int fUseVarIndex, char * pValues ); +extern int Llb_CoreExperiment( Aig_Man_t * pInit, Aig_Man_t * pAig, Gia_ParLlb_t * pPars, Vec_Ptr_t * vResult, int TimeTarget ); /*=== llb2Driver.c ======================================================*/ extern Vec_Int_t * Llb_DriverCountRefs( Aig_Man_t * p ); extern Vec_Int_t * Llb_DriverCollectNs( Aig_Man_t * pAig, Vec_Int_t * vDriRefs ); @@ -166,9 +172,15 @@ extern DdNode * Llb_ImgComputeImage( Aig_Man_t * pAig, Vec_Ptr_t * vDdMan Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQuant1, Vec_Int_t * vDriRefs, int TimeTarget, int fBackward, int fReorder, int fVerbose ); +extern DdManager * Llb_NonlinImageStart( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q, int * pOrder, int fFirst ); +extern DdNode * Llb_NonlinImageCompute( DdNode * bCurrent, int fReorder, int fDrop, int fVerbose, int * pOrder ); +extern void Llb_NonlinImageQuit(); + /*=== llb3Image.c ======================================================*/ extern DdNode * Llb_NonlinImage( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q, DdManager * dd, DdNode * bCurrent, int fReorder, int fVerbose, int * pOrder, int Limit, int TimeTarget ); +/*=== llb3Nonlin.c ======================================================*/ +extern DdNode * Llb_NonlinComputeInitState( Aig_Man_t * pAig, DdManager * dd ); ABC_NAMESPACE_HEADER_END diff --git a/src/aig/mem/mem.c b/src/aig/mem/mem.c index 28d7e86e..23d8d7ec 100644 --- a/src/aig/mem/mem.c +++ b/src/aig/mem/mem.c @@ -72,10 +72,13 @@ struct Mem_Flex_t_ struct Mem_Step_t_ { - int nMems; // the number of fixed memory managers employed - Mem_Fixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc - int nMapSize; // the size of the memory array - Mem_Fixed_t ** pMap; // maps the number of bytes into its memory manager + int nMems; // the number of fixed memory managers employed + Mem_Fixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc + int nMapSize; // the size of the memory array + Mem_Fixed_t ** pMap; // maps the number of bytes into its memory manager + int nLargeChunksAlloc; // the maximum number of large memory chunks + int nLargeChunks; // the current number of large memory chunks + void ** pLargeChunks; // the allocated large memory chunks }; //////////////////////////////////////////////////////////////////////// @@ -316,7 +319,7 @@ Mem_Flex_t * Mem_FlexStart() p->pCurrent = NULL; p->pEnd = NULL; - p->nChunkSize = (1 << 14); + p->nChunkSize = (1 << 12); p->nChunksAlloc = 64; p->nChunks = 0; p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); @@ -509,12 +512,12 @@ void Mem_StepStop( Mem_Step_t * p, int fVerbose ) int i; for ( i = 0; i < p->nMems; i++ ) Mem_FixedStop( p->pMems[i], fVerbose ); -// if ( p->pLargeChunks ) -// { -// for ( i = 0; i < p->nLargeChunks; i++ ) -// ABC_FREE( p->pLargeChunks[i] ); -// ABC_FREE( p->pLargeChunks ); -// } + if ( p->pLargeChunks ) + { + for ( i = 0; i < p->nLargeChunks; i++ ) + ABC_FREE( p->pLargeChunks[i] ); + ABC_FREE( p->pLargeChunks ); + } ABC_FREE( p->pMems ); ABC_FREE( p->pMap ); ABC_FREE( p ); @@ -538,18 +541,16 @@ char * Mem_StepEntryFetch( Mem_Step_t * p, int nBytes ) if ( nBytes > p->nMapSize ) { // printf( "Allocating %d bytes.\n", nBytes ); -/* +// return ABC_ALLOC( char, nBytes ); if ( p->nLargeChunks == p->nLargeChunksAlloc ) { if ( p->nLargeChunksAlloc == 0 ) - p->nLargeChunksAlloc = 5; + p->nLargeChunksAlloc = 32; p->nLargeChunksAlloc *= 2; - p->pLargeChunks = ABC_REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc ); + p->pLargeChunks = (void **)ABC_REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc ); } p->pLargeChunks[ p->nLargeChunks++ ] = ABC_ALLOC( char, nBytes ); - return p->pLargeChunks[ p->nLargeChunks - 1 ]; -*/ - return ABC_ALLOC( char, nBytes ); + return (char *)p->pLargeChunks[ p->nLargeChunks - 1 ]; } return Mem_FixedEntryFetch( p->pMap[nBytes] ); } diff --git a/src/aig/saig/module.make b/src/aig/saig/module.make index a1f0e976..a83ac5e2 100644 --- a/src/aig/saig/module.make +++ b/src/aig/saig/module.make @@ -18,6 +18,7 @@ SRC += src/aig/saig/saigAbs.c \ src/aig/saig/saigRetStep.c \ src/aig/saig/saigScl.c \ src/aig/saig/saigSimExt.c \ + src/aig/saig/saigSimExt2.c \ src/aig/saig/saigSimFast.c \ src/aig/saig/saigSimMv.c \ src/aig/saig/saigSimSeq.c \ diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index b1017bdb..62ac35ac 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -29,14 +29,15 @@ #include "aig.h" #include "giaAbs.h" +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_HEADER_START - +#define SAIG_ZER 1 +#define SAIG_ONE 2 +#define SAIG_UND 3 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -149,6 +150,8 @@ extern Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFr extern Aig_Man_t * Saig_ManDupOrpos( Aig_Man_t * p ); extern Aig_Man_t * Saig_ManCreateEquivMiter( Aig_Man_t * pAig, Vec_Int_t * vPairs ); extern Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); +extern int Saig_ManVerifyCex( Aig_Man_t * pAig, Abc_Cex_t * p ); +extern int Saig_ManFindFailedPoCex( Aig_Man_t * pAig, Abc_Cex_t * p ); /*=== saigHaig.c ==========================================================*/ extern Aig_Man_t * Saig_ManHaigRecord( Aig_Man_t * p, int nIters, int nSteps, int fRetimingOnly, int fAddBugs, int fUseCnf, int fVerbose ); /*=== saigInd.c ==========================================================*/ @@ -179,7 +182,9 @@ extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fFo extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); /*=== saigSimExt.c ==========================================================*/ extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ); -extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); +extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fTryFour, int fVerbose ); +/*=== saigSimExt.c ==========================================================*/ +extern Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); /*=== saigSimMv.c ==========================================================*/ extern int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose ); /*=== saigStrSim.c ==========================================================*/ diff --git a/src/aig/saig/saigAbs.c b/src/aig/saig/saigAbs.c index 938a66e2..bed5edaf 100644 --- a/src/aig/saig/saigAbs.c +++ b/src/aig/saig/saigAbs.c @@ -101,12 +101,12 @@ Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexA Abc_Cex_t * pCex; Aig_Obj_t * pObj; int i, f; - if ( !Ssw_SmlRunCounterExample( pAbs, pCexAbs ) ) + if ( !Saig_ManVerifyCex( pAbs, pCexAbs ) ) printf( "Saig_ManCexRemap(): The intial counter-example is invalid.\n" ); else printf( "Saig_ManCexRemap(): The intial counter-example is correct.\n" ); // start the counter-example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); + pCex = Abc_CexAlloc( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); pCex->iFrame = pCexAbs->iFrame; pCex->iPo = pCexAbs->iPo; // copy the bit data @@ -121,10 +121,10 @@ Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexA } } // verify the counter example - if ( !Ssw_SmlRunCounterExample( p, pCex ) ) + if ( !Saig_ManVerifyCex( p, pCex ) ) { printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); + Abc_CexFree( pCex ); pCex = NULL; } else @@ -194,7 +194,7 @@ Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlo printf( "Running property directed reachability...\n" ); RetValue = Pdr_ManSolve( pAbsOrpos, pPars, &pCex ); if ( pCex ) - pCex->iPo = Ssw_SmlFindOutputCounterExample( pAbs, pCex ); + pCex->iPo = Saig_ManFindFailedPoCex( pAbs, pCex ); Aig_ManStop( pAbsOrpos ); pAbs->pSeqModel = pCex; if ( RetValue ) @@ -225,7 +225,7 @@ Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlo return NULL; if ( pnUseStart ) *pnUseStart = pAbs->pSeqModel->iFrame; - vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); + vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, 1, fVerbose ); if ( vFlopsNew == NULL ) return NULL; if ( Vec_IntSize(vFlopsNew) == 0 ) @@ -267,13 +267,16 @@ Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlo SeeAlso [] ***********************************************************************/ -int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ) +int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fTryFour, int fSensePath, int fVerbose ) { Aig_Man_t * pAbs; Vec_Int_t * vFlopsNew; - int i, Entry; + int i, Entry, clk = clock(); pAbs = Saig_ManDeriveAbstraction( p, vFlops ); - vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); + if ( fSensePath ) + vFlopsNew = Saig_ManExtendCounterExampleTest2( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); + else + vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fTryFour, fVerbose ); if ( vFlopsNew == NULL ) { Aig_ManStop( pAbs ); @@ -289,7 +292,10 @@ int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, return 0; } if ( fVerbose ) - printf( "Adding %d registers to the abstraction.\n", Vec_IntSize(vFlopsNew) ); + { + printf( "Adding %d registers to the abstraction. ", Vec_IntSize(vFlopsNew) ); + Abc_PrintTime( 0, "Time", clock() - clk ); + } // vFlopsNew contains PI number that should be kept in pAbs // add to the abstraction Vec_IntForEachEntry( vFlopsNew, Entry, i ) diff --git a/src/aig/saig/saigBmc.c b/src/aig/saig/saigBmc.c index 8aa3af80..cb506054 100644 --- a/src/aig/saig/saigBmc.c +++ b/src/aig/saig/saigBmc.c @@ -301,11 +301,10 @@ int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLim } else if ( status == l_True ) { -// extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); pModel[Aig_ManPiNum(pFrames)] = pObj->Id; - pAig->pSeqModel = (Abc_Cex_t *)Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); + pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); ABC_FREE( pModel ); Vec_IntFree( vCiIds ); diff --git a/src/aig/saig/saigBmc2.c b/src/aig/saig/saigBmc2.c index 3d57ae6e..9c36deb3 100644 --- a/src/aig/saig/saigBmc2.c +++ b/src/aig/saig/saigBmc2.c @@ -637,7 +637,7 @@ Abc_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) Aig_Obj_t * pObj, * pObjFrm; int i, f, iVarNum; // start the counter-example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); pCex->iFrame = p->iFrameFail; pCex->iPo = p->iOutputFail; // copy the bit data @@ -656,10 +656,10 @@ Abc_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) } } // verify the counter example - if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) + if ( !Saig_ManVerifyCex( p->pAig, pCex ) ) { printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); + Abc_CexFree( pCex ); pCex = NULL; } return pCex; diff --git a/src/aig/saig/saigBmc3.c b/src/aig/saig/saigBmc3.c index a75297f7..570e8a26 100644 --- a/src/aig/saig/saigBmc3.c +++ b/src/aig/saig/saigBmc3.c @@ -1108,8 +1108,7 @@ clkOther += clock() - clk2; continue; if ( Lit == 1 ) { - extern Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); - Abc_Cex_t * pCex = Fra_SmlTrivCounterExample( pAig, f*Saig_ManPoNum(pAig)+i ); + Abc_Cex_t * pCex = Abc_CexMakeTriv( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), f*Saig_ManPoNum(pAig)+i ); printf( "Output %d is trivially SAT in frame %d.\n", i, f ); if ( !pPars->fSolveAll ) { @@ -1137,9 +1136,8 @@ clkOther += clock() - clk2; } else if ( status == l_True ) { -// extern void * Fra_SmlSimpleCounterExample( Aig_Man_t * p, int * pModel, int iFrame, int iPo ); int * pModel = Sat_SolverGetModel( p->pSat, Vec_IntArray(p->vPiVars), Vec_IntSize(p->vPiVars) ); - Abc_Cex_t * pCex = Fra_SmlSimpleCounterExample( pAig, pModel, f, i ); + Abc_Cex_t * pCex = Abc_CexCreate( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), pModel, f, i, 1 ); ABC_FREE( pModel ); fFirst = 0; if ( !pPars->fSolveAll ) diff --git a/src/aig/saig/saigDup.c b/src/aig/saig/saigDup.c index 4d34224e..b2b33bdb 100644 --- a/src/aig/saig/saigDup.c +++ b/src/aig/saig/saigDup.c @@ -115,7 +115,7 @@ Aig_Man_t * Saig_ManCreateEquivMiter( Aig_Man_t * pAig, Vec_Int_t * vPairs ) Aig_ManForEachNodeVec( pAig, vPairs, pObj, i ) { pObj2 = Aig_ManObj( pAig, Vec_IntEntry(vPairs, ++i) ); - pMiter = Aig_Exor( pAigNew, pObj->pData, pObj2->pData ); + pMiter = Aig_Exor( pAigNew, (Aig_Obj_t *)pObj->pData, (Aig_Obj_t *)pObj2->pData ); pMiter = Aig_NotCond( pMiter, pObj->fPhase ^ pObj2->fPhase ); Aig_ObjCreatePo( pAigNew, pMiter ); } @@ -265,6 +265,91 @@ Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) return pNew; } +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManVerifyCex( Aig_Man_t * pAig, Abc_Cex_t * p ) +{ + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Aig_ManCleanMarkB(pAig); + Aig_ManConst1(pAig)->fMarkB = 1; + Saig_ManForEachLo( pAig, pObj, i ) + pObj->fMarkB = Aig_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Saig_ManForEachPi( pAig, pObj, k ) + pObj->fMarkB = Aig_InfoHasBit(p->pData, iBit++); + Aig_ManForEachNode( pAig, pObj, k ) + pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & + (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj)); + Aig_ManForEachPo( pAig, pObj, k ) + pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); + if ( i == p->iFrame ) + break; + Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMarkB = pObjRi->fMarkB; + } + assert( iBit == p->nBits ); + RetValue = Aig_ManPo(pAig, p->iPo)->fMarkB; + Aig_ManCleanMarkB(pAig); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManFindFailedPoCex( Aig_Man_t * pAig, Abc_Cex_t * p ) +{ + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Aig_ManCleanMarkB(pAig); + Aig_ManConst1(pAig)->fMarkB = 1; + Saig_ManForEachLo( pAig, pObj, i ) + pObj->fMarkB = Aig_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Saig_ManForEachPi( pAig, pObj, k ) + pObj->fMarkB = Aig_InfoHasBit(p->pData, iBit++); + Aig_ManForEachNode( pAig, pObj, k ) + pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & + (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj)); + Aig_ManForEachPo( pAig, pObj, k ) + pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); + if ( i == p->iFrame ) + break; + Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMarkB = pObjRi->fMarkB; + } + assert( iBit == p->nBits ); + // remember the number of failed output + RetValue = -1; + Saig_ManForEachPo( pAig, pObj, i ) + if ( pObj->fMarkB ) + { + RetValue = i; + break; + } + Aig_ManCleanMarkB(pAig); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/saig/saigSimExt.c b/src/aig/saig/saigSimExt.c index 9828d17e..ac0fa697 100644 --- a/src/aig/saig/saigSimExt.c +++ b/src/aig/saig/saigSimExt.c @@ -28,10 +28,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define SAIG_ZER 1 -#define SAIG_ONE 2 -#define SAIG_UND 3 - static inline int Saig_ManSimInfoNot( int Value ) { if ( Value == SAIG_ZER ) @@ -521,7 +517,7 @@ Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Abc_C SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) +Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fTryFour, int fVerbose ) { Vec_Int_t * vRes; Vec_Ptr_t * vSimInfo; @@ -537,8 +533,10 @@ Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, A Vec_PtrCleanSimInfo( vSimInfo, 0, Aig_BitWordNum(2*(pCex->iFrame+1)) ); clk = clock(); -// vRes = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - vRes = Saig_ManExtendCounterExample( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + if ( fTryFour ) + vRes = Saig_ManExtendCounterExample( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + else + vRes = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); if ( fVerbose ) { printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); diff --git a/src/aig/saig/saigSimExt2.c b/src/aig/saig/saigSimExt2.c new file mode 100644 index 00000000..cb5d3b77 --- /dev/null +++ b/src/aig/saig/saigSimExt2.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [saigSimExt2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Extending simulation trace to contain ternary values.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigSimExt2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "ssw.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SAIG_ZER_NEW 0 // 0 not visited +#define SAIG_ONE_NEW 1 // 1 not visited +#define SAIG_ZER_OLD 2 // 0 visited +#define SAIG_ONE_OLD 3 // 1 visited + +static inline int Saig_ManSimInfo2IsOld( int Value ) +{ + return Value == SAIG_ZER_OLD || Value == SAIG_ONE_OLD; +} + +static inline int Saig_ManSimInfo2SetOld( int Value ) +{ + if ( Value == SAIG_ZER_NEW ) + return SAIG_ZER_OLD; + if ( Value == SAIG_ONE_NEW ) + return SAIG_ONE_OLD; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2Not( int Value ) +{ + if ( Value == SAIG_ZER_NEW ) + return SAIG_ONE_NEW; + if ( Value == SAIG_ONE_NEW ) + return SAIG_ZER_NEW; + if ( Value == SAIG_ZER_OLD ) + return SAIG_ONE_OLD; + if ( Value == SAIG_ONE_OLD ) + return SAIG_ZER_OLD; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2And( int Value0, int Value1 ) +{ + if ( Value0 == SAIG_ZER_NEW || Value1 == SAIG_ZER_NEW ) + return SAIG_ZER_NEW; + if ( Value0 == SAIG_ONE_NEW && Value1 == SAIG_ONE_NEW ) + return SAIG_ONE_NEW; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2Get( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); +} + +static inline void Saig_ManSimInfo2Set( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + Value ^= Saig_ManSimInfo2Get( vSimInfo, pObj, iFrame ); + pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); +} + +// performs ternary simulation +extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs ternary simulation for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManExtendOneEval2( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + int Value0, Value1, Value; + Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pObj), iFrame ); + if ( Aig_ObjFaninC0(pObj) ) + Value0 = Saig_ManSimInfo2Not( Value0 ); + if ( Aig_ObjIsPo(pObj) ) + { + Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value0 ); + return Value0; + } + assert( Aig_ObjIsNode(pObj) ); + Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pObj), iFrame ); + if ( Aig_ObjFaninC1(pObj) ) + Value1 = Saig_ManSimInfo2Not( Value1 ); + Value = Saig_ManSimInfo2And( Value0, Value1 ); + Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value ); + return Value; +} + +/**Function************************************************************* + + Synopsis [Performs sensitization analysis for one design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManSimDataInit2( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo ) +{ + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f, iBit = 0; + Saig_ManForEachLo( p, pObj, i ) + Saig_ManSimInfo2Set( vSimInfo, pObj, 0, Aig_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); + for ( f = 0; f <= pCex->iFrame; f++ ) + { + Saig_ManSimInfo2Set( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE_NEW ); + Saig_ManForEachPi( p, pObj, i ) + Saig_ManSimInfo2Set( vSimInfo, pObj, f, Aig_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); + Aig_ManForEachNode( p, pObj, i ) + Saig_ManExtendOneEval2( vSimInfo, pObj, f ); + Aig_ManForEachPo( p, pObj, i ) + Saig_ManExtendOneEval2( vSimInfo, pObj, f ); + if ( f == pCex->iFrame ) + break; + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + Saig_ManSimInfo2Set( vSimInfo, pObjLo, f+1, Saig_ManSimInfo2Get(vSimInfo, pObjLi, f) ); + } + // make sure the output of the property failed + pObj = Aig_ManPo( p, pCex->iPo ); + return Saig_ManSimInfo2Get( vSimInfo, pObj, pCex->iFrame ); +} + +/**Function************************************************************* + + Synopsis [Drive implications of the given node towards primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) +{ + Aig_Obj_t * pFanout; + int k, iFanout, Value0, Value1; + int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); + assert( !Saig_ManSimInfo2IsOld( Value ) ); + Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) ); + if ( (Aig_ObjIsPo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) ) + return; + if ( Saig_ObjIsLi( p, pObj ) ) + { + assert( f < fMax ); + pFanout = Saig_ObjLiToLo(p, pObj); + Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 ); + if ( !Saig_ManSimInfo2IsOld( Value ) ) + Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo ); + return; + } + assert( Aig_ObjIsPi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) ); + Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k ) + { + Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + continue; + if ( Aig_ObjIsPo(pFanout) ) + { + Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); + continue; + } + assert( Aig_ObjIsNode(pFanout) ); + Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f ); + Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f ); + if ( Aig_ObjFaninC0(pFanout) ) + Value0 = Saig_ManSimInfo2Not( Value0 ); + if ( Aig_ObjFaninC1(pFanout) ) + Value1 = Saig_ManSimInfo2Not( Value1 ); + if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD || + (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) ) + Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); + } +} + +/**Function************************************************************* + + Synopsis [Performs recursive sensetization analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManExplorePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) +{ + int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + return; + Saig_ManSetAndDriveImplications_rec( p, pObj, f, fMax, vSimInfo ); + assert( !Aig_ObjIsConst1(pObj) ); + if ( Saig_ObjIsLo(p, pObj) && f == 0 ) + return; + if ( Saig_ObjIsPi(p, pObj) ) + { + // propagate implications of this assignment + int i, iPiNum = Aig_ObjPioNum(pObj); + for ( i = fMax; i >= 0; i-- ) + if ( i != f ) + Saig_ManSetAndDriveImplications_rec( p, Aig_ManPi(p, iPiNum), i, fMax, vSimInfo ); + return; + } + if ( Saig_ObjIsLo( p, pObj ) ) + { + assert( f > 0 ); + Saig_ManExplorePaths_rec( p, Saig_ObjLoToLi(p, pObj), f-1, fMax, vSimInfo ); + return; + } + if ( Aig_ObjIsPo(pObj) ) + { + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); + return; + } + assert( Aig_ObjIsNode(pObj) ); + if ( Value == SAIG_ZER_OLD ) + { +// if ( (Aig_ObjId(pObj) & 1) == 0 ) + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); +// else +// Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); + } + else + { + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); + Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); + } +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManProcessCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vRes, * vResInv; + int i, f, Value; +// assert( Aig_ManRegNum(p) > 0 ); + assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Aig_BitWordNum(2*(pCex->iFrame+1)) ); + // start simulation data + Value = Saig_ManSimDataInit2( p, pCex, vSimInfo ); + assert( Value == SAIG_ONE_NEW ); + // derive implications of constants and primary inputs + Saig_ManForEachLo( p, pObj, i ) + Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + { + Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo ); + for ( i = 0; i < iFirstFlopPi; i++ ) + Saig_ManSetAndDriveImplications_rec( p, Aig_ManPi(p, i), f, pCex->iFrame, vSimInfo ); + } + // recursively compute justification + Saig_ManExplorePaths_rec( p, Aig_ManPo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo ); + // select the result + vRes = Vec_IntAlloc( 1000 ); + vResInv = Vec_IntAlloc( 1000 ); + for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + { + Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManPi(p, i), f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + // resimulate to make sure it is valid + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); + assert( Value == SAIG_ONE ); + Vec_IntFree( vResInv ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) +{ + Vec_Int_t * vRes; + Vec_Ptr_t * vSimInfo; + int clk; + if ( Saig_ManPiNum(p) != pCex->nPis ) + { + printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", + Aig_ManPiNum(p), pCex->nPis ); + return NULL; + } + Aig_ManFanoutStart( p ); + vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Aig_BitWordNum(2*(pCex->iFrame+1)) ); + Vec_PtrCleanSimInfo( vSimInfo, 0, Aig_BitWordNum(2*(pCex->iFrame+1)) ); + +clk = clock(); + vRes = Saig_ManProcessCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + if ( fVerbose ) + { + printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + } + Vec_PtrFree( vSimInfo ); + Aig_ManFanoutStop( p ); + return vRes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimSeq.c b/src/aig/saig/saigSimSeq.c index 37bb12b5..cc5a9e05 100644 --- a/src/aig/saig/saigSimSeq.c +++ b/src/aig/saig/saigSimSeq.c @@ -418,7 +418,7 @@ Abc_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; - p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); + p = Abc_CexAlloc( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); p->iFrame = iFrame; p->iPo = iOut; // fill in the binary data diff --git a/src/aig/saig/saigTempor.c b/src/aig/saig/saigTempor.c index 74f4a9d3..962a81de 100644 --- a/src/aig/saig/saigTempor.c +++ b/src/aig/saig/saigTempor.c @@ -69,7 +69,7 @@ Aig_Man_t * Saig_ManTemporFrames( Aig_Man_t * pAig, int nFrames ) } // create POs for the flop inputs Saig_ManForEachLi( pAig, pObj, i ) - Aig_ObjCreatePo( pFrames, pObj->pData ); + Aig_ObjCreatePo( pFrames, (Aig_Obj_t *)pObj->pData ); Aig_ManCleanup( pFrames ); return pFrames; } @@ -123,7 +123,7 @@ Aig_Man_t * Saig_ManTemporDecompose( Aig_Man_t * pAig, int nFrames ) // create flop output values Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_Mux( pAigNew, pReset, Aig_ObjCreatePi(pAigNew), Aig_ManPo(pFrames, i)->pData ); + pObj->pData = Aig_Mux( pAigNew, pReset, Aig_ObjCreatePi(pAigNew), (Aig_Obj_t *)Aig_ManPo(pFrames, i)->pData ); Aig_ManStop( pFrames ); // add internal nodes of this frame diff --git a/src/aig/ssw/ssw.h b/src/aig/ssw/ssw.h index bf8c918e..437e6ec8 100644 --- a/src/aig/ssw/ssw.h +++ b/src/aig/ssw/ssw.h @@ -123,18 +123,9 @@ extern int Ssw_SmlNumFrames( Ssw_Sml_t * p ); extern int Ssw_SmlNumWordsTotal( Ssw_Sml_t * p ); extern unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj ); extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ); -extern Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); -extern void Ssw_SmlFreeCounterExample( Abc_Cex_t * pCex ); -extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); -extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); -extern Abc_Cex_t * Ssw_SmlDupCounterExample( Abc_Cex_t * p, int nRegsNew ); - - ABC_NAMESPACE_HEADER_END - - #endif //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/ssw/sswBmc.c b/src/aig/ssw/sswBmc.c index aba32304..d565d5d3 100644 --- a/src/aig/ssw/sswBmc.c +++ b/src/aig/ssw/sswBmc.c @@ -94,7 +94,7 @@ Abc_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iP int f, i, nShift; assert( Saig_ManRegNum(pFrm->pAig) > 0 ); // allocate the counter example - pCex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(pFrm->pAig), Saig_ManPiNum(pFrm->pAig), iFrame + 1 ); + pCex = Abc_CexAlloc( Saig_ManRegNum(pFrm->pAig), Saig_ManPiNum(pFrm->pAig), iFrame + 1 ); pCex->iPo = iPo; pCex->iFrame = iFrame; // create data-bits diff --git a/src/aig/ssw/sswInt.h b/src/aig/ssw/sswInt.h index ad868c6e..189494bc 100644 --- a/src/aig/ssw/sswInt.h +++ b/src/aig/ssw/sswInt.h @@ -29,6 +29,7 @@ #include "saig.h" #include "satSolver.h" #include "ssw.h" +#include "ioa.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// diff --git a/src/aig/ssw/sswSim.c b/src/aig/ssw/sswSim.c index 404302f2..e68f08cd 100644 --- a/src/aig/ssw/sswSim.c +++ b/src/aig/ssw/sswSim.c @@ -1248,131 +1248,6 @@ unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj ) return Ssw_ObjSim( p, pObj->Id ); } - -/**Function************************************************************* - - Synopsis [Allocates a counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) -{ - Abc_Cex_t * pCex; - int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); - pCex->nRegs = nRegs; - pCex->nPis = nRealPis; - pCex->nBits = nRegs + nRealPis * nFrames; - return pCex; -} - -/**Function************************************************************* - - Synopsis [Frees the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ssw_SmlFreeCounterExample( Abc_Cex_t * pCex ) -{ - ABC_FREE( pCex ); -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) -{ - Ssw_Sml_t * pSml; - Aig_Obj_t * pObj; - int RetValue, i, k, iBit; - if ( Saig_ManPiNum(pAig) != p->nPis ) - return 0; -// if ( Saig_ManRegNum(pAig) != p->nRegs ) -// return 0; -// assert( Aig_ManRegNum(pAig) > 0 ); -// assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); - // start a new sequential simulator - pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 ); - // assign simulation info for the registers - iBit = 0; - Saig_ManForEachLo( pAig, pObj, i ) - Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); - // assign simulation info for the primary inputs - iBit = Saig_ManRegNum(pAig); - for ( i = 0; i <= p->iFrame; i++ ) - Saig_ManForEachPi( pAig, pObj, k ) - Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); -// assert( iBit == p->nBits ); - // run random simulation - Ssw_SmlSimulateOne( pSml ); - // check if the given output has failed - RetValue = !Ssw_SmlNodeIsZeroFrame( pSml, Aig_ManPo(pAig, p->iPo), p->iFrame ); - Ssw_SmlStop( pSml ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) -{ - Ssw_Sml_t * pSml; - Aig_Obj_t * pObj; - int i, k, iBit, iOut; - assert( Aig_ManRegNum(pAig) > 0 ); - assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); - // start a new sequential simulator - pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 ); - // assign simulation info for the registers - iBit = 0; - Saig_ManForEachLo( pAig, pObj, i ) - Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); - // assign simulation info for the primary inputs - for ( i = 0; i <= p->iFrame; i++ ) - Saig_ManForEachPi( pAig, pObj, k ) - Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); - assert( iBit == p->nBits ); - // run random simulation - Ssw_SmlSimulateOne( pSml ); - // check if the given output has failed - iOut = -1; - Saig_ManForEachPo( pAig, pObj, k ) - if ( !Ssw_SmlNodeIsZeroFrame( pSml, Aig_ManPo(pAig, k), p->iFrame ) ) - { - iOut = k; - break; - } - Ssw_SmlStop( pSml ); - return iOut; -} - /**Function************************************************************* Synopsis [Creates sequential counter-example from the simulation info.] @@ -1417,7 +1292,7 @@ Abc_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) assert( iBit < 32 * p->nWordsFrame ); // allocate the counter example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 ); + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 ); pCex->iPo = iPo; pCex->iFrame = iFrame; @@ -1438,126 +1313,14 @@ Abc_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) } } // verify the counter example - if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) + if ( !Saig_ManVerifyCex( p->pAig, pCex ) ) { printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); + Abc_CexFree( pCex ); pCex = NULL; } return pCex; } - -/**Function************************************************************* - - Synopsis [Generates seq counter-example from the combinational one.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) -{ - Abc_Cex_t * pCex; - Aig_Obj_t * pObj; - int i, nFrames, nTruePis, nTruePos, iPo, iFrame; - // get the number of frames - assert( Aig_ManRegNum(pAig) > 0 ); - assert( Aig_ManRegNum(pFrames) == 0 ); - nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); - nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig); - nFrames = Aig_ManPiNum(pFrames) / nTruePis; - assert( nTruePis * nFrames == Aig_ManPiNum(pFrames) ); - assert( nTruePos * nFrames == Aig_ManPoNum(pFrames) ); - // find the PO that failed - iPo = -1; - iFrame = -1; - Aig_ManForEachPo( pFrames, pObj, i ) - if ( pObj->Id == pModel[Aig_ManPiNum(pFrames)] ) - { - iPo = i % nTruePos; - iFrame = i / nTruePos; - break; - } - assert( iPo >= 0 ); - // allocate the counter example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); - pCex->iPo = iPo; - pCex->iFrame = iFrame; - - // copy the bit data - for ( i = 0; i < Aig_ManPiNum(pFrames); i++ ) - { - if ( pModel[i] ) - Aig_InfoSetBit( pCex->pData, pCex->nRegs + i ); - if ( pCex->nRegs + i == pCex->nBits - 1 ) - break; - } - - // verify the counter example - if ( !Ssw_SmlRunCounterExample( pAig, pCex ) ) - { - printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); - pCex = NULL; - } - return pCex; - -} - -/**Function************************************************************* - - Synopsis [Make the trivial counter-example for the trivially asserted output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) -{ - Abc_Cex_t * pCex; - int nTruePis, nTruePos, iPo, iFrame; - assert( Aig_ManRegNum(pAig) > 0 ); - nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); - nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig); - iPo = iFrameOut % nTruePos; - iFrame = iFrameOut / nTruePos; - // allocate the counter example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); - pCex->iPo = iPo; - pCex->iFrame = iFrame; - return pCex; -} - -/**Function************************************************************* - - Synopsis [Make the trivial counter-example for the trivially asserted output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Ssw_SmlDupCounterExample( Abc_Cex_t * p, int nRegsNew ) -{ - Abc_Cex_t * pCex; - int i; - pCex = Ssw_SmlAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); - pCex->iPo = p->iPo; - pCex->iFrame = p->iFrame; - for ( i = p->nRegs; i < p->nBits; i++ ) - if ( Aig_InfoHasBit(p->pData, i) ) - Aig_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); - return pCex; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/ssw/sswSweep.c b/src/aig/ssw/sswSweep.c index 40121e42..edae0846 100644 --- a/src/aig/ssw/sswSweep.c +++ b/src/aig/ssw/sswSweep.c @@ -331,7 +331,6 @@ p->timeBmc += clock() - clk; ***********************************************************************/ void Ssw_ManDumpEquivMiter( Aig_Man_t * p, Vec_Int_t * vPairs, int Num ) { - extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); FILE * pFile; char pBuffer[16]; Aig_Man_t * pNew; diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 3357ff46..fbd6b479 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -33,11 +33,12 @@ #include <time.h> #include "vec.h" -#include "cuddInt.h" #include "hop.h" -#include "extra.h" +#include "st.h" #include "stmm.h" #include "nm.h" +#include "mem.h" +#include "utilCex.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -84,18 +85,16 @@ typedef enum { typedef enum { ABC_OBJ_NONE = 0, // 0: unknown ABC_OBJ_CONST1, // 1: constant 1 node (AIG only) - ABC_OBJ_PIO, // 2: inout terminal - ABC_OBJ_PI, // 3: primary input terminal - ABC_OBJ_PO, // 4: primary output terminal - ABC_OBJ_BI, // 5: box input terminal - ABC_OBJ_BO, // 6: box output terminal - ABC_OBJ_ASSERT, // 7: assertion terminal - ABC_OBJ_NET, // 8: net - ABC_OBJ_NODE, // 9: node - ABC_OBJ_LATCH, // 10: latch - ABC_OBJ_WHITEBOX, // 11: box with known contents - ABC_OBJ_BLACKBOX, // 12: box with unknown contents - ABC_OBJ_NUMBER // 13: unused + ABC_OBJ_PI, // 2: primary input terminal + ABC_OBJ_PO, // 3: primary output terminal + ABC_OBJ_BI, // 4: box input terminal + ABC_OBJ_BO, // 5: box output terminal + ABC_OBJ_NET, // 6: net + ABC_OBJ_NODE, // 7: node + ABC_OBJ_LATCH, // 8: latch + ABC_OBJ_WHITEBOX, // 9: box with known contents + ABC_OBJ_BLACKBOX, // 10: box with unknown contents + ABC_OBJ_NUMBER // 11: unused } Abc_ObjType_t; // latch initial values @@ -149,8 +148,8 @@ struct Abc_Obj_t_ // 12 words Vec_Int_t vFanouts; // the array of fanouts // miscellaneous union { - void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc) - int iData; + void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc) + int iData; }; Abc_Obj_t * pNext; // the next pointer in the hash table union { // temporary store for user's data @@ -192,8 +191,8 @@ struct Abc_Ntk_t_ short fHiePath; // flag to mark the network on the path // miscellaneous data members int nTravIds; // the unique traversal IDs of nodes - Extra_MmFixed_t * pMmObj; // memory manager for objects - Extra_MmStep_t * pMmStep; // memory manager for arrays + Mem_Fixed_t * pMmObj; // memory manager for objects + Mem_Step_t * pMmStep; // memory manager for arrays void * pManFunc; // functionality manager (AIG manager, BDD manager, or memory manager for SOPs) // Abc_Lib_t * pVerLib; // for structural verilog designs Abc_ManTime_t * pManTime; // the timing manager (for mapped networks) stores arrival/required times for all nodes @@ -208,7 +207,7 @@ struct Abc_Ntk_t_ void * pExcare; // the EXDC network (if given) void * pData; // misc Abc_Ntk_t * pCopy; // copy of this network - Hop_Man_t * pHaig; // history AIG + void * pHaig; // history AIG float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model Vec_Ptr_t * vOnehots; // names of one-hot-encoded registers // node attributes @@ -314,7 +313,6 @@ static inline Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) { return Ab static inline Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_PO ); } static inline Abc_Obj_t * Abc_NtkCreateBi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BI ); } static inline Abc_Obj_t * Abc_NtkCreateBo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BO ); } -static inline Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_ASSERT ); } static inline Abc_Obj_t * Abc_NtkCreateNet( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NET ); } static inline Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NODE ); } static inline Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_LATCH ); } @@ -354,14 +352,13 @@ static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; } // checking the object type -static inline int Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PIO; } +static inline int Abc_ObjIsNone( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NONE; } static inline int Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; } static inline int Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; } static inline int Abc_ObjIsBi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BI; } static inline int Abc_ObjIsBo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BO; } -static inline int Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; } static inline int Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BO; } -static inline int Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BI || pObj->Type == ABC_OBJ_ASSERT; } +static inline int Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BI; } static inline int Abc_ObjIsTerm( Abc_Obj_t * pObj ) { return Abc_ObjIsCi(pObj) || Abc_ObjIsCo(pObj); } static inline int Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; } static inline int Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; } @@ -419,29 +416,29 @@ static inline int Abc_NodeIsTravIdCurrent( Abc_Obj_t * pNode ) { r static inline int Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { return (int )(pNode->TravId == pNode->pNtk->nTravIds - 1); } // checking initial state of the latches -static inline void Abc_LatchSetInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_NONE; } -static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ZERO; } -static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ONE; } -static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_DC; } -static inline int Abc_LatchIsInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_NONE; } -static inline int Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ZERO; } -static inline int Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ONE; } -static inline int Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_DC; } -static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)(ABC_PTRINT_T)pLatch->pData; } +static inline void Abc_LatchSetInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_NONE; } +static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ZERO; } +static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ONE; } +static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_DC; } +static inline int Abc_LatchIsInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_NONE; } +static inline int Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ZERO; } +static inline int Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ONE; } +static inline int Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_DC; } +static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)(ABC_PTRINT_T)pLatch->pData; } // global BDDs of the nodes -static inline void * Abc_NtkGlobalBdd( Abc_Ntk_t * pNtk ) { return (void *)Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_GLOBAL_BDD); } -static inline DdManager * Abc_NtkGlobalBddMan( Abc_Ntk_t * pNtk ) { return (DdManager *)Vec_AttMan( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } -static inline DdNode ** Abc_NtkGlobalBddArray( Abc_Ntk_t * pNtk ) { return (DdNode **)Vec_AttArray( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } -static inline DdNode * Abc_ObjGlobalBdd( Abc_Obj_t * pObj ) { return (DdNode *)Vec_AttEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id ); } -static inline void Abc_ObjSetGlobalBdd( Abc_Obj_t * pObj, DdNode * bF ) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id, bF ); } +static inline void * Abc_NtkGlobalBdd( Abc_Ntk_t * pNtk ) { return Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_GLOBAL_BDD); } +static inline void * Abc_NtkGlobalBddMan( Abc_Ntk_t * pNtk ) { return Vec_AttMan( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } +static inline void ** Abc_NtkGlobalBddArray( Abc_Ntk_t * pNtk ) { return Vec_AttArray( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } +static inline void * Abc_ObjGlobalBdd( Abc_Obj_t * pObj ) { return Vec_AttEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id ); } +static inline void Abc_ObjSetGlobalBdd( Abc_Obj_t * pObj, void * bF ) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id, bF ); } // MV variables of the nodes -static inline void * Abc_NtkMvVar( Abc_Ntk_t * pNtk ) { return Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_MVVAR); } -static inline void * Abc_NtkMvVarMan( Abc_Ntk_t * pNtk ) { return Abc_NtkMvVar(pNtk)? Vec_AttMan( (Vec_Att_t *)Abc_NtkMvVar(pNtk) ) : NULL; } +static inline void * Abc_NtkMvVar( Abc_Ntk_t * pNtk ) { return Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_MVVAR); } +static inline void * Abc_NtkMvVarMan( Abc_Ntk_t * pNtk ) { return Abc_NtkMvVar(pNtk)? Vec_AttMan( (Vec_Att_t *)Abc_NtkMvVar(pNtk) ) : NULL; } static inline void * Abc_ObjMvVar( Abc_Obj_t * pObj ) { return Abc_NtkMvVar(pObj->pNtk)? Vec_AttEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id ) : NULL; } -static inline int Abc_ObjMvVarNum( Abc_Obj_t * pObj ) { return (Abc_NtkMvVar(pObj->pNtk) && Abc_ObjMvVar(pObj))? *((int*)Abc_ObjMvVar(pObj)) : 2; } -static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id, pV ); } +static inline int Abc_ObjMvVarNum( Abc_Obj_t * pObj ) { return (Abc_NtkMvVar(pObj->pNtk) && Abc_ObjMvVar(pObj))? *((int*)Abc_ObjMvVar(pObj)) : 2; } +static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id, pV ); } //////////////////////////////////////////////////////////////////////// /// ITERATORS /// @@ -451,6 +448,9 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At #define Abc_NtkForEachObj( pNtk, pObj, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pObj) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pObj) == NULL ) {} else +#define Abc_NtkForEachObjVec( pNtk, vIds, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(vIds) && (((pObj) = Abc_NtkObj(pNtk, Vec_IntEntry(vIds,i))), 1); i++ ) \ + if ( (pObj) == NULL ) {} else #define Abc_NtkForEachNet( pNtk, pNet, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else @@ -608,11 +608,8 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkFraigRestore(); extern ABC_DLL void Abc_NtkFraigStoreClean(); /*=== abcFunc.c ==========================================================*/ extern ABC_DLL int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ); -extern ABC_DLL DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ); -extern ABC_DLL char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ); extern ABC_DLL int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ); -extern ABC_DLL void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ); -extern ABC_DLL int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ); +extern ABC_DLL void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Mem_Flex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ); extern ABC_DLL void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkSopToAig( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk ); @@ -687,10 +684,10 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ); /*=== abcNtbdd.c ==========================================================*/ -extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ); +extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ); extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ); -extern ABC_DLL DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); -extern ABC_DLL DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); +extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); +extern ABC_DLL void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); extern ABC_DLL int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ); /*=== abcNtk.c ==========================================================*/ extern ABC_DLL Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan ); @@ -781,8 +778,6 @@ extern ABC_DLL Vec_Ptr_t * Abc_NtkManCutReadCutSmall( Abc_ManCut_t * p ); extern ABC_DLL Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p ); extern ABC_DLL Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, int fContain ); extern ABC_DLL void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited, int fIncludeFanins ); -extern ABC_DLL DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited ); -extern ABC_DLL DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited ); extern ABC_DLL Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, int LevelMax ); /*=== abcRefs.c ==========================================================*/ extern ABC_DLL int Abc_NodeMffcSize( Abc_Obj_t * pNode ); @@ -801,30 +796,31 @@ extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateL extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects ); extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes ); /*=== abcSop.c ==========================================================*/ -extern ABC_DLL char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ); -extern ABC_DLL char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ); -extern ABC_DLL char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan ); -extern ABC_DLL char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan ); -extern ABC_DLL char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ); -extern ABC_DLL char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); -extern ABC_DLL char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars ); -extern ABC_DLL char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); -extern ABC_DLL char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); -extern ABC_DLL char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars ); -extern ABC_DLL char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars ); -extern ABC_DLL char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ); -extern ABC_DLL char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ); -extern ABC_DLL char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ); -extern ABC_DLL char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ); -extern ABC_DLL char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ); -extern ABC_DLL char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth ); -extern ABC_DLL char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ); +extern ABC_DLL char * Abc_SopRegister( Mem_Flex_t * pMan, char * pName ); +extern ABC_DLL char * Abc_SopStart( Mem_Flex_t * pMan, int nCubes, int nVars ); +extern ABC_DLL char * Abc_SopCreateConst0( Mem_Flex_t * pMan ); +extern ABC_DLL char * Abc_SopCreateConst1( Mem_Flex_t * pMan ); +extern ABC_DLL char * Abc_SopCreateAnd2( Mem_Flex_t * pMan, int fCompl0, int fCompl1 ); +extern ABC_DLL char * Abc_SopCreateAnd( Mem_Flex_t * pMan, int nVars, int * pfCompl ); +extern ABC_DLL char * Abc_SopCreateNand( Mem_Flex_t * pMan, int nVars ); +extern ABC_DLL char * Abc_SopCreateOr( Mem_Flex_t * pMan, int nVars, int * pfCompl ); +extern ABC_DLL char * Abc_SopCreateOrMultiCube( Mem_Flex_t * pMan, int nVars, int * pfCompl ); +extern ABC_DLL char * Abc_SopCreateNor( Mem_Flex_t * pMan, int nVars ); +extern ABC_DLL char * Abc_SopCreateXor( Mem_Flex_t * pMan, int nVars ); +extern ABC_DLL char * Abc_SopCreateXorSpecial( Mem_Flex_t * pMan, int nVars ); +extern ABC_DLL char * Abc_SopCreateNxor( Mem_Flex_t * pMan, int nVars ); +extern ABC_DLL char * Abc_SopCreateMux( Mem_Flex_t * pMan ); +extern ABC_DLL char * Abc_SopCreateInv( Mem_Flex_t * pMan ); +extern ABC_DLL char * Abc_SopCreateBuf( Mem_Flex_t * pMan ); +extern ABC_DLL char * Abc_SopCreateFromTruth( Mem_Flex_t * pMan, int nVars, unsigned * pTruth ); +extern ABC_DLL char * Abc_SopCreateFromIsop( Mem_Flex_t * pMan, int nVars, Vec_Int_t * vCover ); extern ABC_DLL int Abc_SopGetCubeNum( char * pSop ); extern ABC_DLL int Abc_SopGetLitNum( char * pSop ); extern ABC_DLL int Abc_SopGetVarNum( char * pSop ); extern ABC_DLL int Abc_SopGetPhase( char * pSop ); extern ABC_DLL int Abc_SopGetIthCareLit( char * pSop, int i ); extern ABC_DLL void Abc_SopComplement( char * pSop ); +extern ABC_DLL void Abc_SopComplementVar( char * pSop, int iVar ); extern ABC_DLL int Abc_SopIsComplement( char * pSop ); extern ABC_DLL int Abc_SopIsConst0( char * pSop ); extern ABC_DLL int Abc_SopIsConst1( char * pSop ); @@ -836,10 +832,10 @@ extern ABC_DLL int Abc_SopIsExorType( char * pSop ); extern ABC_DLL int Abc_SopCheck( char * pSop, int nFanins ); extern ABC_DLL char * Abc_SopFromTruthBin( char * pTruth ); extern ABC_DLL char * Abc_SopFromTruthHex( char * pTruth ); -extern ABC_DLL char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues ); -extern ABC_DLL char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues ); -extern ABC_DLL char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues ); -extern ABC_DLL char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues ); +extern ABC_DLL char * Abc_SopEncoderPos( Mem_Flex_t * pMan, int iValue, int nValues ); +extern ABC_DLL char * Abc_SopEncoderLog( Mem_Flex_t * pMan, int iBit, int nValues ); +extern ABC_DLL char * Abc_SopDecoderPos( Mem_Flex_t * pMan, int nValues ); +extern ABC_DLL char * Abc_SopDecoderLog( Mem_Flex_t * pMan, int nValues ); /*=== abcStrash.c ==========================================================*/ extern ABC_DLL Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fRecord ); extern ABC_DLL Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int fRecord ); @@ -900,6 +896,10 @@ extern ABC_DLL Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies ); extern ABC_DLL void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ); +extern ABC_DLL void Abc_NtkCleanMarkB( Abc_Ntk_t * pNtk ); +extern ABC_DLL void Abc_NtkCleanMarkC( Abc_Ntk_t * pNtk ); +extern ABC_DLL void Abc_NtkCleanMarkAB( Abc_Ntk_t * pNtk ); +extern ABC_DLL void Abc_NtkCleanMarkABC( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode ); extern ABC_DLL Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode ); extern ABC_DLL Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ); diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 956a26b9..b624fb10 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -109,6 +110,7 @@ static void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan ); static void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode ); static void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -131,7 +133,7 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig ) pMan = ABC_ALLOC( Abc_Aig_t, 1 ); memset( pMan, 0, sizeof(Abc_Aig_t) ); // allocate the table - pMan->nBins = Cudd_PrimeCopy( 10000 ); + pMan->nBins = Cudd_Prime( 10000 ); pMan->pBins = ABC_ALLOC( Abc_Obj_t *, pMan->nBins ); memset( pMan->pBins, 0, sizeof(Abc_Obj_t *) * pMan->nBins ); pMan->vNodes = Vec_PtrAlloc( 100 ); @@ -593,7 +595,7 @@ void Abc_AigResize( Abc_Aig_t * pMan ) clk = clock(); // get the new table size - nBinsNew = Cudd_PrimeCopy( 3 * pMan->nBins ); + nBinsNew = Cudd_Prime( 3 * pMan->nBins ); // allocate a new array pBinsNew = ABC_ALLOC( Abc_Obj_t *, nBinsNew ); memset( pBinsNew, 0, sizeof(Abc_Obj_t *) * nBinsNew ); diff --git a/src/base/abc/abcBlifMv.c b/src/base/abc/abcBlifMv.c index 946e3f75..21535cb5 100644 --- a/src/base/abc/abcBlifMv.c +++ b/src/base/abc/abcBlifMv.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -46,7 +47,7 @@ void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk ) { Vec_Att_t * pAttMan; assert( Abc_NtkMvVar(pNtk) == NULL ); - pAttMan = Vec_AttAlloc( Abc_NtkObjNumMax(pNtk) + 1, Extra_MmFlexStart(), (void(*)(void*))Extra_MmFlexStop, NULL, NULL ); + pAttMan = Vec_AttAlloc( Abc_NtkObjNumMax(pNtk) + 1, Mem_FlexStart(), (void(*)(void*))Mem_FlexStop, NULL, NULL ); Vec_PtrWriteEntry( pNtk->vAttrs, VEC_ATTR_MVVAR, pAttMan ); //printf( "allocing attr\n" ); } @@ -64,9 +65,9 @@ void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk ) ***********************************************************************/ void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk ) { - Extra_MmFlex_t * pUserMan; - pUserMan = (Extra_MmFlex_t *)Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, 0 ); - Extra_MmFlexStop( pUserMan ); + Mem_Flex_t * pUserMan; + pUserMan = (Mem_Flex_t *)Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, 0 ); + Mem_FlexStop( pUserMan, 0 ); } /**Function************************************************************* @@ -82,7 +83,7 @@ void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk ) ***********************************************************************/ void Abc_NtkSetMvVarValues( Abc_Obj_t * pObj, int nValues ) { - Extra_MmFlex_t * pFlex; + Mem_Flex_t * pFlex; struct temp { int nValues; @@ -96,8 +97,8 @@ void Abc_NtkSetMvVarValues( Abc_Obj_t * pObj, int nValues ) if ( Abc_ObjMvVar(pObj) != NULL ) return; // create the structure - pFlex = (Extra_MmFlex_t *)Abc_NtkMvVarMan( pObj->pNtk ); - pVarStruct = (struct temp *)Extra_MmFlexEntryFetch( pFlex, sizeof(struct temp) ); + pFlex = (Mem_Flex_t *)Abc_NtkMvVarMan( pObj->pNtk ); + pVarStruct = (struct temp *)Mem_FlexEntryFetch( pFlex, sizeof(struct temp) ); pVarStruct->nValues = nValues; pVarStruct->pNames = NULL; Abc_ObjSetMvVar( pObj, pVarStruct ); @@ -784,7 +785,7 @@ Abc_Ntk_t * Abc_NtkSkeletonBlifMv( Abc_Ntk_t * pNtk ) for ( v = 0; v < nValues; v++ ) { pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopEncoderPos( (Extra_MmFlex_t *)pNtkNew->pManFunc, v, nValues ); + pNodeNew->pData = Abc_SopEncoderPos( (Mem_Flex_t *)pNtkNew->pManFunc, v, nValues ); pNetNew = Abc_NtkCreateNet( pNtkNew ); pTermNew = Abc_NtkCreateBi( pNtkNew ); Abc_ObjAddFanin( pNodeNew, pNet->pCopy ); @@ -806,7 +807,7 @@ Abc_Ntk_t * Abc_NtkSkeletonBlifMv( Abc_Ntk_t * pNtk ) for ( k = 0; k < nBits; k++ ) { pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopEncoderLog( (Extra_MmFlex_t *)pNtkNew->pManFunc, k, nValues ); + pNodeNew->pData = Abc_SopEncoderLog( (Mem_Flex_t *)pNtkNew->pManFunc, k, nValues ); pNetNew = Abc_NtkCreateNet( pNtkNew ); pTermNew = Abc_NtkCreateBi( pNtkNew ); Abc_ObjAddFanin( pNodeNew, pNet->pCopy ); @@ -831,7 +832,7 @@ Abc_Ntk_t * Abc_NtkSkeletonBlifMv( Abc_Ntk_t * pNtk ) Abc_NodeSetTravIdCurrent( pNet ); nValues = Abc_ObjMvVarNum(pNet); pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopDecoderPos( (Extra_MmFlex_t *)pNtkNew->pManFunc, nValues ); + pNodeNew->pData = Abc_SopDecoderPos( (Mem_Flex_t *)pNtkNew->pManFunc, nValues ); for ( v = 0; v < nValues; v++ ) { pTermNew = Abc_NtkCreateBo( pNtkNew ); @@ -855,7 +856,7 @@ Abc_Ntk_t * Abc_NtkSkeletonBlifMv( Abc_Ntk_t * pNtk ) nValues = Abc_ObjMvVarNum(pNet); nBits = Extra_Base2Log( nValues ); pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopDecoderLog( (Extra_MmFlex_t *)pNtkNew->pManFunc, nValues ); + pNodeNew->pData = Abc_SopDecoderLog( (Mem_Flex_t *)pNtkNew->pManFunc, nValues ); for ( k = 0; k < nBits; k++ ) { pTermNew = Abc_NtkCreateBo( pNtkNew ); @@ -950,7 +951,7 @@ Abc_Ntk_t * Abc_NtkInsertBlifMv( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtkLogic ) ***********************************************************************/ int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk ) { - Extra_MmFlex_t * pMmFlex; + Mem_Flex_t * pMmFlex; Abc_Obj_t * pNode; Vec_Str_t * vCube; char * pSop0, * pSop1, * pBlifMv, * pCube, * pCur; @@ -963,7 +964,7 @@ int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk ) return 0; } - pMmFlex = Extra_MmFlexStart(); + pMmFlex = Mem_FlexStart(); vCube = Vec_StrAlloc( 100 ); Abc_NtkForEachNode( pNtk, pNode, i ) { @@ -972,7 +973,7 @@ int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk ) // allocate room for the MV-SOP nCubes = Abc_SopGetCubeNum(pSop0) + Abc_SopGetCubeNum(pSop1); nSize = nCubes*(2*Abc_ObjFaninNum(pNode) + 2)+1; - pBlifMv = Extra_MmFlexEntryFetch( pMmFlex, nSize ); + pBlifMv = Mem_FlexEntryFetch( pMmFlex, nSize ); // add the cubes pCur = pBlifMv; Abc_SopForEachCube( pSop0, Abc_ObjFaninNum(pNode), pCube ) diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index ee6f4173..5fb22d79 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry ) +static inline void Vec_IntPushMem( Mem_Step_t * pMemMan, Vec_Int_t * p, int Entry ) { if ( p->nSize == p->nCap ) { @@ -52,7 +52,7 @@ static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int if ( p->nSize == 0 ) p->nCap = 1; if ( pMemMan ) - pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 ); + pArray = (int *)Mem_StepEntryFetch( pMemMan, p->nCap * 8 ); else pArray = ABC_ALLOC( int, p->nCap * 2 ); if ( p->pArray ) @@ -60,7 +60,7 @@ static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int for ( i = 0; i < p->nSize; i++ ) pArray[i] = p->pArray[i]; if ( pMemMan ) - Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); + Mem_StepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); else ABC_FREE( p->pArray ); } diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index 35ea8332..81990bac 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -35,59 +35,14 @@ static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, in static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot); static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop ); +extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Converts the network from SOP to BDD representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - DdManager * dd; - int nFaninsMax, i; - - assert( Abc_NtkHasSop(pNtk) ); - - // start the functionality manager - nFaninsMax = Abc_NtkGetFaninMax( pNtk ); - if ( nFaninsMax == 0 ) - printf( "Warning: The network has only constant nodes.\n" ); - - dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - - // convert each node from SOP to BDD - Abc_NtkForEachNode( pNtk, pNode, i ) - { - assert( pNode->pData ); - pNode->pData = Abc_ConvertSopToBdd( dd, (char *)pNode->pData ); - if ( pNode->pData == NULL ) - { - printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" ); - return 0; - } - Cudd_Ref( (DdNode *)pNode->pData ); - } - - Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pManFunc ); - pNtk->pManFunc = dd; - - // update the network type - pNtk->ntkFunc = ABC_FUNC_BDD; - return 1; -} - -/**Function************************************************************* - Synopsis [Converts the node from SOP to BDD representation.] Description [] @@ -97,7 +52,7 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) +DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars ) { DdNode * bSum, * bCube, * bTemp, * bVar; char * pCube; @@ -110,7 +65,7 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) { for ( v = 0; v < nVars; v++ ) { - bSum = Cudd_bddXor( dd, bTemp = bSum, Cudd_bddIthVar(dd, v) ); Cudd_Ref( bSum ); + bSum = Cudd_bddXor( dd, bTemp = bSum, pbVars? pbVars[v] : Cudd_bddIthVar(dd, v) ); Cudd_Ref( bSum ); Cudd_RecursiveDeref( dd, bTemp ); } } @@ -123,9 +78,9 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) Abc_CubeForEachVar( pCube, Value, v ) { if ( Value == '0' ) - bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) ); + bVar = Cudd_Not( pbVars? pbVars[v] : Cudd_bddIthVar( dd, v ) ); else if ( Value == '1' ) - bVar = Cudd_bddIthVar( dd, v ); + bVar = pbVars? pbVars[v] : Cudd_bddIthVar( dd, v ); else continue; bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube ); @@ -145,7 +100,7 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) /**Function************************************************************* - Synopsis [Removes complemented SOP covers.] + Synopsis [Converts the network from SOP to BDD representation.] Description [] @@ -154,117 +109,45 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) SeeAlso [] ***********************************************************************/ -void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) +int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) { - DdManager * dd; - DdNode * bFunc; - Vec_Str_t * vCube; Abc_Obj_t * pNode; - int nFaninsMax, fFound, i; - - assert( Abc_NtkHasSop(pNtk) ); - - // check if there are nodes with complemented SOPs - fFound = 0; - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( Abc_SopIsComplement((char *)pNode->pData) ) - { - fFound = 1; - break; - } - if ( !fFound ) - return; + DdManager * dd; + int nFaninsMax, i; + + assert( Abc_NtkHasSop(pNtk) ); - // start the BDD package + // start the functionality manager nFaninsMax = Abc_NtkGetFaninMax( pNtk ); if ( nFaninsMax == 0 ) printf( "Warning: The network has only constant nodes.\n" ); - dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - - // change the cover of negated nodes - vCube = Vec_StrAlloc( 100 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( Abc_SopIsComplement((char *)pNode->pData) ) - { - bFunc = Abc_ConvertSopToBdd( dd, (char *)pNode->pData ); Cudd_Ref( bFunc ); - pNode->pData = Abc_ConvertBddToSop( (Extra_MmFlex_t *)pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, 1 ); - Cudd_RecursiveDeref( dd, bFunc ); - assert( !Abc_SopIsComplement((char *)pNode->pData) ); - } - Vec_StrFree( vCube ); - Extra_StopManager( dd ); -} - - - - - -/**Function************************************************************* - - Synopsis [Converts the network from BDD to SOP representation.] - - Description [If the flag is set to 1, forces the direct phase of all covers.] - - SideEffects [] - - SeeAlso [] -***********************************************************************/ -int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) -{ - Abc_Obj_t * pNode; - Extra_MmFlex_t * pManNew; - DdManager * dd = (DdManager *)pNtk->pManFunc; - DdNode * bFunc; - Vec_Str_t * vCube; - int i, fMode; - - if ( fDirect ) - fMode = 1; - else - fMode = -1; - - assert( Abc_NtkHasBdd(pNtk) ); - if ( dd->size > 0 ) - Cudd_zddVarsFromBddVars( dd, 2 ); - // create the new manager - pManNew = Extra_MmFlexStart(); + dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - // go through the objects - vCube = Vec_StrAlloc( 100 ); + // convert each node from SOP to BDD Abc_NtkForEachNode( pNtk, pNode, i ) { assert( pNode->pData ); - bFunc = (DdNode *)pNode->pData; - pNode->pNext = (Abc_Obj_t *)Abc_ConvertBddToSop( pManNew, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, fMode ); - if ( pNode->pNext == NULL ) + pNode->pData = Abc_ConvertSopToBdd( dd, (char *)pNode->pData, NULL ); + if ( pNode->pData == NULL ) { - Extra_MmFlexStop( pManNew ); - Abc_NtkCleanNext( pNtk ); -// printf( "Converting from BDDs to SOPs has failed.\n" ); - Vec_StrFree( vCube ); + printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" ); return 0; } + Cudd_Ref( (DdNode *)pNode->pData ); } - Vec_StrFree( vCube ); - // update the network type - pNtk->ntkFunc = ABC_FUNC_SOP; - // set the new manager - pNtk->pManFunc = pManNew; - // transfer from next to data - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Cudd_RecursiveDeref( dd, (DdNode *)pNode->pData ); - pNode->pData = pNode->pNext; - pNode->pNext = NULL; - } + Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); + pNtk->pManFunc = dd; - // check for remaining references in the package - Extra_StopManager( dd ); + // update the network type + pNtk->ntkFunc = ABC_FUNC_BDD; return 1; } + + + /**Function************************************************************* Synopsis [Converts the node from BDD to SOP representation.] @@ -276,7 +159,7 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) SeeAlso [] ***********************************************************************/ -char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ) +char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ) { int fVerify = 0; char * pSop; @@ -291,7 +174,7 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun Vec_StrFill( vCube, nFanins, '-' ); Vec_StrPush( vCube, '\0' ); if ( pMan ) - pSop = Extra_MmFlexEntryFetch( pMan, nFanins + 4 ); + pSop = Mem_FlexEntryFetch( pMan, nFanins + 4 ); else pSop = ABC_ALLOC( char, nFanins + 4 ); if ( bFuncOn == Cudd_ReadOne(dd) ) @@ -386,7 +269,7 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun // allocate memory for the cover if ( pMan ) - pSop = Extra_MmFlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 ); + pSop = Mem_FlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 ); else pSop = ABC_ALLOC( char, (nFanins + 3) * nCubes + 1 ); pSop[(nFanins + 3) * nCubes] = 0; @@ -399,7 +282,7 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun // verify if ( fVerify ) { - bFuncNew = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFuncNew ); + bFuncNew = Abc_ConvertSopToBdd( dd, pSop, NULL ); Cudd_Ref( bFuncNew ); if ( bFuncOn == bFuncOnDc ) { if ( bFuncNew != bFuncOn ) @@ -417,6 +300,73 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun /**Function************************************************************* + Synopsis [Converts the network from BDD to SOP representation.] + + Description [If the flag is set to 1, forces the direct phase of all covers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) +{ + Abc_Obj_t * pNode; + Mem_Flex_t * pManNew; + DdManager * dd = (DdManager *)pNtk->pManFunc; + DdNode * bFunc; + Vec_Str_t * vCube; + int i, fMode; + + if ( fDirect ) + fMode = 1; + else + fMode = -1; + + assert( Abc_NtkHasBdd(pNtk) ); + if ( dd->size > 0 ) + Cudd_zddVarsFromBddVars( dd, 2 ); + // create the new manager + pManNew = Mem_FlexStart(); + + // go through the objects + vCube = Vec_StrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + assert( pNode->pData ); + bFunc = (DdNode *)pNode->pData; + pNode->pNext = (Abc_Obj_t *)Abc_ConvertBddToSop( pManNew, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, fMode ); + if ( pNode->pNext == NULL ) + { + Mem_FlexStop( pManNew, 0 ); + Abc_NtkCleanNext( pNtk ); +// printf( "Converting from BDDs to SOPs has failed.\n" ); + Vec_StrFree( vCube ); + return 0; + } + } + Vec_StrFree( vCube ); + + // update the network type + pNtk->ntkFunc = ABC_FUNC_SOP; + // set the new manager + pNtk->pManFunc = pManNew; + // transfer from next to data + Abc_NtkForEachNode( pNtk, pNode, i ) + { + Cudd_RecursiveDeref( dd, (DdNode *)pNode->pData ); + pNode->pData = pNode->pNext; + pNode->pNext = NULL; + } + + // check for remaining references in the package + Extra_StopManager( dd ); + return 1; +} + + +/**Function************************************************************* + Synopsis [Derive the SOP from the ZDD representation of the cubes.] Description [] @@ -482,7 +432,7 @@ int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFani SeeAlso [] ***********************************************************************/ -void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ) +void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Mem_Flex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ) { assert( Abc_NtkHasBdd(pNode->pNtk) ); *ppSop0 = Abc_ConvertBddToSop( pMmMan, (DdManager *)pNode->pNtk->pManFunc, (DdNode *)pNode->pData, (DdNode *)pNode->pData, Abc_ObjFaninNum(pNode), fAllPrimes, vCube, 0 ); @@ -490,6 +440,59 @@ void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * v } +/**Function************************************************************* + + Synopsis [Removes complemented SOP covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) +{ + DdManager * dd; + DdNode * bFunc; + Vec_Str_t * vCube; + Abc_Obj_t * pNode; + int nFaninsMax, fFound, i; + + assert( Abc_NtkHasSop(pNtk) ); + + // check if there are nodes with complemented SOPs + fFound = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( Abc_SopIsComplement((char *)pNode->pData) ) + { + fFound = 1; + break; + } + if ( !fFound ) + return; + + // start the BDD package + nFaninsMax = Abc_NtkGetFaninMax( pNtk ); + if ( nFaninsMax == 0 ) + printf( "Warning: The network has only constant nodes.\n" ); + dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + + // change the cover of negated nodes + vCube = Vec_StrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( Abc_SopIsComplement((char *)pNode->pData) ) + { + bFunc = Abc_ConvertSopToBdd( dd, (char *)pNode->pData, NULL ); Cudd_Ref( bFunc ); + pNode->pData = Abc_ConvertBddToSop( (Mem_Flex_t *)pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, 1 ); + Cudd_RecursiveDeref( dd, bFunc ); + assert( !Abc_SopIsComplement((char *)pNode->pData) ); + } + Vec_StrFree( vCube ); + Extra_StopManager( dd ); +} + + /**Function************************************************************* @@ -573,7 +576,7 @@ int Abc_NtkSopToAig( Abc_Ntk_t * pNtk ) return 0; } } - Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); pNtk->pManFunc = pMan; // update the network type @@ -876,14 +879,14 @@ int Abc_NtkMapToSop( Abc_Ntk_t * pNtk ) assert( Abc_NtkHasMapping(pNtk) ); // update the functionality manager assert( pNtk->pManFunc == Abc_FrameReadLibGen() ); - pNtk->pManFunc = Extra_MmFlexStart(); + pNtk->pManFunc = Mem_FlexStart(); pNtk->ntkFunc = ABC_FUNC_SOP; // update the nodes Abc_NtkForEachNode( pNtk, pNode, i ) { pSop = Mio_GateReadSop((Mio_Gate_t *)pNode->pData); assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) ); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, pSop ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, pSop ); } return 1; } diff --git a/src/base/abc/abcHie.c b/src/base/abc/abcHie.c index 1155731e..37359522 100644 --- a/src/base/abc/abcHie.c +++ b/src/base/abc/abcHie.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c index 7528f470..b5fa1f64 100644 --- a/src/base/abc/abcLatch.c +++ b/src/base/abc/abcLatch.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -257,7 +258,7 @@ void Abc_NtkNodeConvertToMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * Abc_ObjAddFanin( pMux, pNode1 ); Abc_ObjAddFanin( pMux, pNode0 ); if ( Abc_NtkHasSop(pNtk) ) - pMux->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, "11- 1\n0-1 1\n" ); + pMux->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "11- 1\n0-1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pMux->pData = Cudd_bddIte((DdManager *)pNtk->pManFunc,Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,1),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,2)), Cudd_Ref( (DdNode *)pMux->pData ); else if ( Abc_NtkHasAig(pNtk) ) @@ -444,7 +445,7 @@ Abc_Ntk_t * Abc_NtkConvertOnehot( Abc_Ntk_t * pNtk ) if ( (k >> i) & 1 ) Abc_ObjAddFanin( pObjNew, Abc_NtkCi(pNtkNew, Abc_NtkPiNum(pNtkNew)+k) ); assert( Abc_ObjFaninNum(pObjNew) == nStates/2 ); - pObjNew->pData = Abc_SopCreateOr( (Extra_MmFlex_t *)pNtkNew->pManFunc, nStates/2, NULL ); + pObjNew->pData = Abc_SopCreateOr( (Mem_Flex_t *)pNtkNew->pManFunc, nStates/2, NULL ); // save the new flop pObj = Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ); pObj->pCopy = pObjNew; @@ -474,7 +475,7 @@ Abc_Ntk_t * Abc_NtkConvertOnehot( Abc_Ntk_t * pNtk ) Abc_ObjAddFanin( pObjNew, Abc_ObjRegular(pObj->pCopy) ); pfCompl[i] = Abc_ObjIsComplement(pObj->pCopy) ^ !((k >> i) & 1); } - pObjNew->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, nFlops, pfCompl ); + pObjNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nFlops, pfCompl ); // connect it to the flop input Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, Abc_NtkPoNum(pNtkNew)+k), pObjNew ); } @@ -585,7 +586,7 @@ void Abc_NtkTransformBack( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, Vec_Ptr_t * Abc_ObjAddFanin( pNodeNew, pCtrl ); Abc_ObjAddFanin( pNodeNew, pDriver ); Abc_ObjAddFanin( pNodeNew, Abc_ObjFanout0(pObj) ); - Abc_ObjSetData( pNodeNew, Abc_SopRegister((Extra_MmFlex_t *)pNtkNew->pManFunc, "0-1 1\n11- 1\n") ); + Abc_ObjSetData( pNodeNew, Abc_SopRegister((Mem_Flex_t *)pNtkNew->pManFunc, "0-1 1\n11- 1\n") ); Abc_ObjPatchFanin( Abc_ObjFanin0(pObj), pDriver, pNodeNew ); } // remove the useless POs diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c index d3e4d735..f376f039 100644 --- a/src/base/abc/abcLib.c +++ b/src/base/abc/abcLib.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -435,7 +436,7 @@ Abc_Ntk_t * Abc_LibDeriveAig( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib ) // deallocate memory manager, which remembers the phase if ( pNtk->pData ) { - Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pData ); + Mem_FlexStop( (Mem_Flex_t *)pNtk->pData, 0 ); pNtk->pData = NULL; } // set the COs diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index ee0085a2..a8dc9249 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c index f8041ec7..0845f3d2 100644 --- a/src/base/abc/abcNames.c +++ b/src/base/abc/abcNames.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index 9077e621..e6911485 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -255,7 +255,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) Abc_NtkForEachNode( pNtk, pObj, i ) { Abc_NtkDupObj(pNtkNew, pObj, 0); - pObj->pCopy->pData = Abc_SopCreateAnd2( (Extra_MmFlex_t *)pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); + pObj->pCopy->pData = Abc_SopCreateAnd2( (Mem_Flex_t *)pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); } // create the choice nodes Abc_NtkForEachNode( pNtk, pObj, i ) @@ -272,7 +272,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); } // create the logic function - pNodeNew->pData = Abc_SopCreateOrMultiCube( (Extra_MmFlex_t *)pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) ); + pNodeNew->pData = Abc_SopCreateOrMultiCube( (Mem_Flex_t *)pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) ); // set the new node pObj->pCopy->pCopy = pNodeNew; Vec_IntFree( vInts ); @@ -349,7 +349,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ) Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) { Abc_NtkDupObj( pNtkNew, pObj, 0 ); - pObj->pCopy->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, 2, NULL ); + pObj->pCopy->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, 2, NULL ); if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); } diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 821cca4c..3ec261a8 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -63,15 +63,15 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan pNtk->vBoxes = Vec_PtrAlloc( 100 ); pNtk->vLtlProperties = Vec_PtrAlloc( 100 ); // start the memory managers - pNtk->pMmObj = fUseMemMan? Extra_MmFixedStart( sizeof(Abc_Obj_t) ) : NULL; - pNtk->pMmStep = fUseMemMan? Extra_MmStepStart( ABC_NUM_STEPS ) : NULL; + pNtk->pMmObj = fUseMemMan? Mem_FixedStart( sizeof(Abc_Obj_t) ) : NULL; + pNtk->pMmStep = fUseMemMan? Mem_StepStart( ABC_NUM_STEPS ) : NULL; // get ready to assign the first Obj ID pNtk->nTravIds = 1; // start the functionality manager if ( Abc_NtkIsStrash(pNtk) ) pNtk->pManFunc = Abc_AigAlloc( pNtk ); else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - pNtk->pManFunc = Extra_MmFlexStart(); + pNtk->pManFunc = Mem_FlexStart(); else if ( Abc_NtkHasBdd(pNtk) ) pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); else if ( Abc_NtkHasAig(pNtk) ) @@ -131,9 +131,7 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ if ( pNtk->vOnehots ) pNtkNew->vOnehots = (Vec_Ptr_t *)Vec_VecDupInt( (Vec_Vec_t *)pNtk->vOnehots ); if ( pNtk->pSeqModel ) - { - pNtkNew->pSeqModel = Gia_ManDupCounterExample( pNtk->pSeqModel, Abc_NtkLatchNum(pNtk) ); - } + pNtkNew->pSeqModel = Abc_CexDup( pNtk->pSeqModel, Abc_NtkLatchNum(pNtk) ); // check that the CI/CO/latches are copied correctly assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) ); assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) ); @@ -908,7 +906,7 @@ Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ) pNode = Abc_NtkCreateNode( pNtkNew ); Abc_NtkForEachPi( pNtkNew, pFanin, i ) Abc_ObjAddFanin( pNode, pFanin ); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtkNew->pManFunc, pSop ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop ); // create the only PO pNodePo = Abc_NtkCreatePo(pNtkNew); Abc_ObjAddFanin( pNodePo, pNode ); @@ -992,14 +990,14 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( pNtk->pSeqModelVec ) Vec_PtrFreeFree( pNtk->pSeqModelVec ); TotalMemory = 0; - TotalMemory += pNtk->pMmObj? Extra_MmFixedReadMemUsage(pNtk->pMmObj) : 0; - TotalMemory += pNtk->pMmStep? Extra_MmStepReadMemUsage(pNtk->pMmStep) : 0; + TotalMemory += pNtk->pMmObj? Mem_FixedReadMemUsage(pNtk->pMmObj) : 0; + TotalMemory += pNtk->pMmStep? Mem_StepReadMemUsage(pNtk->pMmStep) : 0; // fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) ); // free the storage if ( pNtk->pMmObj ) - Extra_MmFixedStop( pNtk->pMmObj ); + Mem_FixedStop( pNtk->pMmObj, 0 ); if ( pNtk->pMmStep ) - Extra_MmStepStop ( pNtk->pMmStep ); + Mem_StepStop ( pNtk->pMmStep, 0 ); // name manager Nm_ManFree( pNtk->pManName ); // free the timing manager @@ -1009,7 +1007,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( Abc_NtkIsStrash(pNtk) ) Abc_AigFree( (Abc_Aig_t *)pNtk->pManFunc ); else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); else if ( Abc_NtkHasBdd(pNtk) ) Extra_StopManager( (DdManager *)pNtk->pManFunc ); else if ( Abc_NtkHasAig(pNtk) ) @@ -1464,9 +1462,10 @@ void Abc_NtkDropOneOutput( Abc_Ntk_t * pNtk, int iOutput ) { Abc_Obj_t * pObj, * pConst0, * pFaninNew; pObj = Abc_NtkPo( pNtk, iOutput ); - if ( Abc_ObjFanin0(pObj) == Abc_AigConst1(pNtk) && !Abc_ObjFaninC0(pObj) ) + if ( Abc_ObjFanin0(pObj) == Abc_AigConst1(pNtk) ) { - Abc_ObjXorFaninC( pObj, 0 ); + if ( !Abc_ObjFaninC0(pObj) ) + Abc_ObjXorFaninC( pObj, 0 ); return; } pConst0 = Abc_ObjNot( Abc_AigConst1(pNtk) ); diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c index 40bbc18b..36fd6397 100644 --- a/src/base/abc/abcObj.c +++ b/src/base/abc/abcObj.c @@ -49,7 +49,7 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) { Abc_Obj_t * pObj; if ( pNtk->pMmObj ) - pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj ); + pObj = (Abc_Obj_t *)Mem_FixedEntryFetch( pNtk->pMmObj ); else pObj = (Abc_Obj_t *)ABC_ALLOC( Abc_Obj_t, 1 ); memset( pObj, 0, sizeof(Abc_Obj_t) ); @@ -86,7 +86,7 @@ void Abc_ObjRecycle( Abc_Obj_t * pObj ) memset( pObj, 0, sizeof(Abc_Obj_t) ); // recycle the object if ( pNtk->pMmObj ) - Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); + Mem_FixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); else ABC_FREE( pObj ); } @@ -120,9 +120,6 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) case ABC_OBJ_CONST1: assert(0); break; - case ABC_OBJ_PIO: - assert(0); - break; case ABC_OBJ_PI: Vec_PtrPush( pNtk->vPis, pObj ); Vec_PtrPush( pNtk->vCis, pObj ); @@ -196,9 +193,6 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) case ABC_OBJ_CONST1: assert(0); break; - case ABC_OBJ_PIO: - assert(0); - break; case ABC_OBJ_PI: Vec_PtrRemove( pNtk->vPis, pObj ); Vec_PtrRemove( pNtk->vCis, pObj ); @@ -345,7 +339,7 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName if ( Abc_NtkIsStrash(pNtkNew) ) {} else if ( Abc_NtkHasSop(pNtkNew) || Abc_NtkHasBlifMv(pNtkNew) ) - pObjNew->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtkNew->pManFunc, (char *)pObj->pData ); + pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, (char *)pObj->pData ); else if ( Abc_NtkHasBdd(pNtkNew) ) pObjNew->pData = Cudd_bddTransfer((DdManager *)pObj->pNtk->pManFunc, (DdManager *)pNtkNew->pManFunc, (DdNode *)pObj->pData), Cudd_Ref((DdNode *)pObjNew->pData); else if ( Abc_NtkHasAig(pNtkNew) ) @@ -581,7 +575,7 @@ Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 0\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_ReadLogicZero((DdManager *)pNtk->pManFunc), Cudd_Ref( (DdNode *)pNode->pData ); else if ( Abc_NtkHasAig(pNtk) ) @@ -610,7 +604,7 @@ Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 1\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_ReadOne((DdManager *)pNtk->pManFunc), Cudd_Ref( (DdNode *)pNode->pData ); else if ( Abc_NtkHasAig(pNtk) ) @@ -640,7 +634,7 @@ Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) pNode = Abc_NtkCreateNode( pNtk ); if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, "0 1\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "0 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_Not(Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0)), Cudd_Ref( (DdNode *)pNode->pData ); else if ( Abc_NtkHasAig(pNtk) ) @@ -670,7 +664,7 @@ Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) pNode = Abc_NtkCreateNode( pNtk ); if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, "1 1\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0), Cudd_Ref( (DdNode *)pNode->pData ); else if ( Abc_NtkHasAig(pNtk) ) @@ -702,7 +696,7 @@ Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) for ( i = 0; i < vFanins->nSize; i++ ) Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); + pNode->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Extra_bddCreateAnd( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData); else if ( Abc_NtkHasAig(pNtk) ) @@ -732,7 +726,7 @@ Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) for ( i = 0; i < vFanins->nSize; i++ ) Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopCreateOr( (Extra_MmFlex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); + pNode->pData = Abc_SopCreateOr( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Extra_bddCreateOr( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData); else if ( Abc_NtkHasAig(pNtk) ) @@ -762,7 +756,7 @@ Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) for ( i = 0; i < vFanins->nSize; i++ ) Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopCreateXorSpecial( (Extra_MmFlex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) ); + pNode->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Extra_bddCreateExor( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData); else if ( Abc_NtkHasAig(pNtk) ) @@ -792,7 +786,7 @@ Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_ Abc_ObjAddFanin( pNode, pNode1 ); Abc_ObjAddFanin( pNode, pNode0 ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, "11- 1\n0-1 1\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "11- 1\n0-1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_bddIte((DdManager *)pNtk->pManFunc,Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,1),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,2)), Cudd_Ref( (DdNode *)pNode->pData ); else if ( Abc_NtkHasAig(pNtk) ) diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index 5be2f8ef..e562a32a 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -53,11 +54,11 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ) +char * Abc_SopRegister( Mem_Flex_t * pMan, char * pName ) { char * pRegName; if ( pName == NULL ) return NULL; - pRegName = Extra_MmFlexEntryFetch( pMan, strlen(pName) + 1 ); + pRegName = Mem_FlexEntryFetch( pMan, strlen(pName) + 1 ); strcpy( pRegName, pName ); return pRegName; } @@ -73,13 +74,13 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ) SeeAlso [] ***********************************************************************/ -char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ) +char * Abc_SopStart( Mem_Flex_t * pMan, int nCubes, int nVars ) { char * pSopCover, * pCube; int i, Length; Length = nCubes * (nVars + 3); - pSopCover = Extra_MmFlexEntryFetch( pMan, Length + 1 ); + pSopCover = Mem_FlexEntryFetch( pMan, Length + 1 ); memset( pSopCover, '-', Length ); pSopCover[Length] = 0; @@ -104,7 +105,7 @@ char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan ) +char * Abc_SopCreateConst1( Mem_Flex_t * pMan ) { return Abc_SopRegister( pMan, " 1\n" ); } @@ -120,7 +121,7 @@ char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan ) +char * Abc_SopCreateConst0( Mem_Flex_t * pMan ) { return Abc_SopRegister( pMan, " 0\n" ); } @@ -136,7 +137,7 @@ char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ) +char * Abc_SopCreateAnd2( Mem_Flex_t * pMan, int fCompl0, int fCompl1 ) { char Buffer[6]; Buffer[0] = '1' - fCompl0; @@ -159,7 +160,7 @@ char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) +char * Abc_SopCreateAnd( Mem_Flex_t * pMan, int nVars, int * pfCompl ) { char * pSop; int i; @@ -181,7 +182,7 @@ char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars ) +char * Abc_SopCreateNand( Mem_Flex_t * pMan, int nVars ) { char * pSop; int i; @@ -203,7 +204,7 @@ char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) +char * Abc_SopCreateOr( Mem_Flex_t * pMan, int nVars, int * pfCompl ) { char * pSop; int i; @@ -225,7 +226,7 @@ char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) +char * Abc_SopCreateOrMultiCube( Mem_Flex_t * pMan, int nVars, int * pfCompl ) { char * pSop, * pCube; int i; @@ -250,7 +251,7 @@ char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars ) +char * Abc_SopCreateNor( Mem_Flex_t * pMan, int nVars ) { char * pSop; int i; @@ -271,7 +272,7 @@ char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars ) +char * Abc_SopCreateXor( Mem_Flex_t * pMan, int nVars ) { assert( nVars == 2 ); return Abc_SopRegister(pMan, "01 1\n10 1\n"); @@ -288,7 +289,7 @@ char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ) +char * Abc_SopCreateXorSpecial( Mem_Flex_t * pMan, int nVars ) { char * pSop; pSop = Abc_SopCreateAnd( pMan, nVars, NULL ); @@ -308,7 +309,7 @@ char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ) +char * Abc_SopCreateNxor( Mem_Flex_t * pMan, int nVars ) { assert( nVars == 2 ); return Abc_SopRegister(pMan, "11 1\n00 1\n"); @@ -326,7 +327,7 @@ char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ) +char * Abc_SopCreateMux( Mem_Flex_t * pMan ) { return Abc_SopRegister(pMan, "11- 1\n0-1 1\n"); } @@ -342,7 +343,7 @@ char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ) +char * Abc_SopCreateInv( Mem_Flex_t * pMan ) { return Abc_SopRegister(pMan, "0 1\n"); } @@ -358,7 +359,7 @@ char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ) +char * Abc_SopCreateBuf( Mem_Flex_t * pMan ) { return Abc_SopRegister(pMan, "1 1\n"); } @@ -374,7 +375,7 @@ char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth ) +char * Abc_SopCreateFromTruth( Mem_Flex_t * pMan, int nVars, unsigned * pTruth ) { char * pSop, * pCube; int nMints, Counter, i, k; @@ -413,7 +414,7 @@ char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTru SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ) +char * Abc_SopCreateFromIsop( Mem_Flex_t * pMan, int nVars, Vec_Int_t * vCover ) { char * pSop, * pCube; int i, k, Entry, Literal; @@ -627,6 +628,31 @@ void Abc_SopComplement( char * pSop ) SeeAlso [] ***********************************************************************/ +void Abc_SopComplementVar( char * pSop, int iVar ) +{ + char * pCube; + int nVars = Abc_SopGetVarNum(pSop); + assert( iVar < nVars ); + Abc_SopForEachCube( pSop, nVars, pCube ) + { + if ( pCube[iVar] == '0' ) + pCube[iVar] = '1'; + else if ( pCube[iVar] == '1' ) + pCube[iVar] = '0'; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_SopIsComplement( char * pSop ) { char * pCur; @@ -1001,7 +1027,7 @@ char * Abc_SopFromTruthHex( char * pTruth ) SeeAlso [] ***********************************************************************/ -char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues ) +char * Abc_SopEncoderPos( Mem_Flex_t * pMan, int iValue, int nValues ) { char Buffer[32]; assert( iValue < nValues ); @@ -1020,7 +1046,7 @@ char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues ) SeeAlso [] ***********************************************************************/ -char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues ) +char * Abc_SopEncoderLog( Mem_Flex_t * pMan, int iBit, int nValues ) { char * pResult; Vec_Str_t * vSop; @@ -1064,7 +1090,7 @@ char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues ) SeeAlso [] ***********************************************************************/ -char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues ) +char * Abc_SopDecoderPos( Mem_Flex_t * pMan, int nValues ) { char * pResult; Vec_Str_t * vSop; @@ -1100,7 +1126,7 @@ char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues ) SeeAlso [] ***********************************************************************/ -char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues ) +char * Abc_SopDecoderLog( Mem_Flex_t * pMan, int nValues ) { char * pResult; Vec_Str_t * vSop; diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 43c53004..e063a238 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -315,6 +315,7 @@ int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk ) ***********************************************************************/ int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk ) { + extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ); Abc_Obj_t * pNode; DdNode * bCover, * zCover, * bFunc; DdManager * dd = (DdManager *)pNtk->pManFunc; @@ -616,7 +617,7 @@ void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies ) void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; - int i = 0; + int i; Abc_NtkForEachObj( pNtk, pObj, i ) pObj->pNext = NULL; } @@ -635,13 +636,89 @@ void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ) void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; - int i = 0; + int i; Abc_NtkForEachObj( pNtk, pObj, i ) pObj->fMarkA = 0; } /**Function************************************************************* + Synopsis [Cleans the copy field of all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCleanMarkB( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkB = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the copy field of all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCleanMarkC( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkC = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the copy field of all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCleanMarkAB( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkA = pObj->fMarkB = 0; +} + +/**Function************************************************************* + + Synopsis [Cleans the copy field of all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCleanMarkABC( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkA = pObj->fMarkB = pObj->fMarkC = 0; +} + +/**Function************************************************************* + Synopsis [Checks if the internal node has CO fanout.] Description [] @@ -927,9 +1004,18 @@ int Abc_NodeIsExorType( Abc_Obj_t * pNode ) // if the children are not ANDs, this is not EXOR if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 ) return 0; - // otherwise, the node is EXOR iff its grand-children are the same - return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1)) && - (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1)); + // this is AIG, which means the fanins should be ordered + assert( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId1(pNode1) || + Abc_ObjFaninId0(pNode1) != Abc_ObjFaninId1(pNode0) ); + // if grand children are not the same, this is not EXOR + if ( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId0(pNode1) || + Abc_ObjFaninId1(pNode0) != Abc_ObjFaninId1(pNode1) ) + return 0; + // finally, if the complemented edges are matched, this is not EXOR + if ( Abc_ObjFaninC0(pNode0) == Abc_ObjFaninC0(pNode1) || + Abc_ObjFaninC1(pNode0) == Abc_ObjFaninC1(pNode1) ) + return 0; + return 1; } /**Function************************************************************* diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7ee6769e..c525cda1 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -354,6 +354,7 @@ static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Srm ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Reduce ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9EquivMark ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Embed ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -474,6 +475,18 @@ void Abc_CommandUpdate9( Abc_Frame_t * pAbc, Gia_Man_t * pNew ) ***********************************************************************/ void Abc_Init( Abc_Frame_t * pAbc ) { +/* + char * pBuff = ABC_ALLOC( char, (1<<29) ); + int i, clk = clock(); + for ( i = 0; i < (1<<29); i++ ) + pBuff[i] = i % 53; + if ( pBuff == NULL ) + printf( "Not allocated. " ); + else + printf( "Allocated %d bytes. ", (1<<29) ); + Abc_PrintTime( 1, "Time", clock() - clk ); +*/ + Cmd_CommandAdd( pAbc, "Printing", "print_stats", Abc_CommandPrintStats, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_exdc", Abc_CommandPrintExdc, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 ); @@ -752,6 +765,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&fraig", Abc_CommandAbc9Fraig, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&srm", Abc_CommandAbc9Srm, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&reduce", Abc_CommandAbc9Reduce, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&equiv_mark", Abc_CommandAbc9EquivMark, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cec", Abc_CommandAbc9Cec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&force", Abc_CommandAbc9Force, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&embed", Abc_CommandAbc9Embed, 0 ); @@ -853,6 +867,10 @@ void Abc_End( Abc_Frame_t * pAbc ) Abc_FrameClearDesign(); { +// extern void Au_TabManPrint(); +// Au_TabManPrint(); + } + { extern void If_LutLibFree( If_Lib_t * pLutLib ); if ( Abc_FrameGetGlobalFrame()->pAbc8Lib ) If_LutLibFree( (If_Lib_t *)Abc_FrameGetGlobalFrame()->pAbc8Lib ); @@ -8425,6 +8443,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Bbl_ManTest( Abc_Ntk_t * pNtk ); extern void Bbl_ManSimpleDemo(); extern Abc_Ntk_t * Abc_NtkCRetime( Abc_Ntk_t * pNtk, int fVerbose ); + extern void Abc_NktMffcTest( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNtk(pAbc); @@ -8487,13 +8506,18 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty network.\n" ); return 1; } +/* if ( Abc_NtkLatchNum(pNtk) == 0 ) { Abc_Print( -1, "Only works for sequential networks.\n" ); return 1; } - - Abc_NtkDarTest( pNtk, nLevels ); +*/ +// if ( fBmc ) +// Abc_NtkBddDec( pNtk, 1 ); +// else +// Abc_NktMffcTest( pNtk ); +// Abc_NtkDarTest( pNtk, nLevels ); // Abc_NtkTestEsop( pNtk ); // Abc_NtkTestSop( pNtk ); @@ -8648,18 +8672,18 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) /* { extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); - extern void Aig_ManFactorAlgebraicTest( Aig_Man_t * p ); + extern void Aig_ManComputeDomsForCofactoring( Aig_Man_t * p ); Aig_Man_t * pAig; pAig = Abc_NtkToDar( pNtk, 0, 0 ); - Aig_ManFactorAlgebraicTest( pAig ); + Aig_ManComputeDomsForCofactoring( pAig ); Aig_ManStop( pAig ); } */ /* -// Bbl_ManSimpleDemo(); -// pNtkRes = Abc_NtkCRetime( pNtk ); - pNtkRes = NULL; +{ + extern Abc_Ntk_t * Au_ManTransformTest( Abc_Ntk_t * pAig ); + pNtkRes = Au_ManTransformTest( pNtk ); if ( pNtkRes == NULL ) { Abc_Print( -1, "Command has failed.\n" ); @@ -8667,10 +8691,25 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); +} +*/ +/* +{ + extern void Au_DsdVecTest( int nVars ); + Au_DsdVecTest( 6 ); +} */ +// Abc_NtkCheckAbsorb( pNtk, 4 ); +/* + if ( fBmc ) + Abc_NktMffcServerTest( pNtk ); + else + Abc_ResPartitionTest( pNtk ); +*/ // Abc_NtkHelloWorld( pNtk ); - +// Abc_NktMffcTest( pNtk ); +// Abc_NktMffcServerTest( pNtk ); return 0; usage: Abc_Print( -2, "usage: test [-h] <file_name>\n" ); @@ -10420,13 +10459,85 @@ int Abc_CommandIProve( Abc_Frame_t * pAbc, int argc, char ** argv ) pParams->fUseRewriting = 1; pParams->fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "rvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFGLIrfbvh" ) ) != EOF ) { switch ( c ) { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nItersMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nItersMax < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nMiteringLimitStart = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nMiteringLimitStart < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nFraigingLimitStart = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nFraigingLimitStart < 0 ) + goto usage; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nFraigingLimitMulti = (float)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nFraigingLimitMulti < 0 ) + goto usage; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nMiteringLimitLast = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nMiteringLimitLast < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nTotalInspectLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nTotalInspectLimit < 0 ) + goto usage; + break; case 'r': pParams->fUseRewriting ^= 1; break; + case 'f': + pParams->fUseFraiging ^= 1; + break; + case 'b': + pParams->fUseBdds ^= 1; + break; case 'v': pParams->fVerbose ^= 1; break; @@ -10488,10 +10599,18 @@ int Abc_CommandIProve( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: iprove [-rvh]\n" ); + Abc_Print( -2, "usage: iprove [-NCFGLI num] [-rfbvh]\n" ); Abc_Print( -2, "\t performs CEC using a new method\n" ); - Abc_Print( -2, "\t-r : toggle AIG rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pParams->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax ); + Abc_Print( -2, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart ); + Abc_Print( -2, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart ); + Abc_Print( -2, "\t-G num : multiplicative coefficient for fraiging [default = %d]\n", (int)pParams->nFraigingLimitMulti ); + Abc_Print( -2, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast ); + Abc_Print( -2, "\t-I num : max number of clause inspections in all SAT calls [default = %d]\n", (int)pParams->nTotalInspectLimit ); + Abc_Print( -2, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle the use of FRAIGing [default = %s]\n", pParams->fUseFraiging? "yes": "no" ); + Abc_Print( -2, "\t-b : toggle the use of BDDs [default = %s]\n", pParams->fUseBdds? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -11007,7 +11126,8 @@ usage: sprintf( Buffer, "%d", pParams->nBTLimit ); Abc_Print( -2, "usage: fraig [-R num] [-D num] [-C num] [-rscpvtah]\n" ); Abc_Print( -2, "\t transforms a logic network into a functionally reduced AIG\n" ); - Abc_Print( -2, "\t (there are also newer fraiging commands, \"ifraig\" and \"dfraig\")\n" ); + Abc_Print( -2, "\t (known bugs: takes an UNSAT miter and returns a SAT one)\n"); + Abc_Print( -2, "\t (there are newer fraiging commands, \"ifraig\" and \"dfraig\")\n" ); Abc_Print( -2, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsRand ); Abc_Print( -2, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsDyna ); Abc_Print( -2, "\t-C num : number of backtracks for one SAT problem [default = %s]\n", pParams->nBTLimit==-1? "infinity" : Buffer ); @@ -16721,7 +16841,7 @@ int Abc_CommandDProve( Abc_Frame_t * pAbc, int argc, char ** argv ) Fra_SecSetDefaultParams( pSecPar ); // pSecPar->TimeLimit = 300; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "cbFCGDVBRTLarmfijkouwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cbFCGDVBRTLarmfijkoupwvh" ) ) != EOF ) { switch ( c ) { @@ -17580,7 +17700,7 @@ int Abc_CommandDSat( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pSimInfo[0] != 1 ) Abc_Print( 1, "ERROR in Abc_NtkMiterSat(): Generated counter example is invalid.\n" ); ABC_FREE( pSimInfo ); - pAbc->pCex = Gia_ManCreateFromComb( 0, Abc_NtkPiNum(pNtk), 0, pNtk->pModel ); + pAbc->pCex = Abc_CexCreate( 0, Abc_NtkPiNum(pNtk), pNtk->pModel, 0, 0, 0 ); } pAbc->Status = RetValue; if ( RetValue == -1 ) @@ -17785,7 +17905,7 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults Prove_ParamsSetDefault( pParams ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLIrfbvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFGLIrfbvh" ) ) != EOF ) { switch ( c ) { @@ -17822,6 +17942,17 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pParams->nFraigingLimitStart < 0 ) goto usage; break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nFraigingLimitMulti = (float)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nFraigingLimitMulti < 0 ) + goto usage; + break; case 'L': if ( globalUtilOptind >= argc ) { @@ -17910,13 +18041,14 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: prove [-N num] [-C num] [-F num] [-L num] [-I num] [-rfbvh]\n" ); + Abc_Print( -2, "usage: prove [-NCFGLI num] [-rfbvh]\n" ); Abc_Print( -2, "\t solves combinational miter by rewriting, FRAIGing, and SAT\n" ); Abc_Print( -2, "\t replaces the current network by the cone modified by rewriting\n" ); - Abc_Print( -2, "\t (there are also newer CEC commands, \"iprove\" and \"dprove\")\n" ); + Abc_Print( -2, "\t (there is also newer CEC command \"iprove\")\n" ); Abc_Print( -2, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax ); Abc_Print( -2, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart ); Abc_Print( -2, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart ); + Abc_Print( -2, "\t-G num : multiplicative coefficient for fraiging [default = %d]\n", (int)pParams->nFraigingLimitMulti ); Abc_Print( -2, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast ); Abc_Print( -2, "\t-I num : max number of clause inspections in all SAT calls [default = %d]\n", (int)pParams->nTotalInspectLimit ); Abc_Print( -2, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" ); @@ -18509,7 +18641,7 @@ int Abc_CommandBmcInter( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults Inter_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CFTNLrtpomcgbkdvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CFTKLrtpomcgbkdvh" ) ) != EOF ) { switch ( c ) { @@ -18546,7 +18678,7 @@ int Abc_CommandBmcInter( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nSecLimit < 0 ) goto usage; break; - case 'N': + case 'K': if ( globalUtilOptind >= argc ) { Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); @@ -18666,12 +18798,13 @@ int Abc_CommandBmcInter( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: int [-CFTN num] [-L file] [-rtpomcgbkdvh]\n" ); + Abc_Print( -2, "usage: int [-CFTK num] [-L file] [-rtpomcgbkdvh]\n" ); Abc_Print( -2, "\t uses interpolation to prove the property\n" ); Abc_Print( -2, "\t-C num : the limit on conflicts for one SAT run [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the limit on number of frames to unroll [default = %d]\n", pPars->nFramesMax ); Abc_Print( -2, "\t-T num : the limit on runtime per output in seconds [default = %d]\n", pPars->nSecLimit ); - Abc_Print( -2, "\t-N num : the number of steps in inductive checking [default = %d]\n", pPars->nFramesK ); + Abc_Print( -2, "\t-K num : the number of steps in inductive checking [default = %d]\n", pPars->nFramesK ); + Abc_Print( -2, "\t (K = 1 works in all cases; K > 1 works without -t and -b)\n" ); Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" ); Abc_Print( -2, "\t-r : toggle rewriting of the unrolled timeframes [default = %s]\n", pPars->fRewrite? "yes": "no" ); Abc_Print( -2, "\t-t : toggle adding transition into the initial state [default = %s]\n", pPars->fTransLoop? "yes": "no" ); @@ -18680,7 +18813,7 @@ usage: Abc_Print( -2, "\t-m : toggle using MiniSat-1.14p (now, Windows-only) [default = %s]\n", pPars->fUseMiniSat? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using inductive containment check [default = %s]\n", pPars->fCheckKstep? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using bias for global variables using SAT [default = %s]\n", pPars->fUseBias? "yes": "no" ); - Abc_Print( -2, "\t-b : toggle using backward interpolation [default = %s]\n", pPars->fUseBackward? "yes": "no" ); + Abc_Print( -2, "\t-b : toggle using backward interpolation (works with -t) [default = %s]\n", pPars->fUseBackward? "yes": "no" ); Abc_Print( -2, "\t-k : toggle solving each output separately [default = %s]\n", pPars->fUseSeparate? "yes": "no" ); Abc_Print( -2, "\t-d : drops (replaces by 0) sat outputs (with -k is used) [default = %s]\n", pPars->fDropSatOuts? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); @@ -18915,7 +19048,7 @@ int Abc_CommandEnlarge( Abc_Frame_t * pAbc, int argc, char ** argv ) } nFrames = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nFrames < 0 ) + if ( nFrames < 1 ) goto usage; break; case 'v': @@ -18954,11 +19087,11 @@ int Abc_CommandEnlarge( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); return 0; usage: - Abc_Print( -2, "usage: enlarge [-F num] [-vh]\n" ); - Abc_Print( -2, "\t performs structural K-step target enlargement\n" ); - Abc_Print( -2, "\t-F num : the number of timeframes for enlargement [default = %d]\n", nFrames ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "usage: enlarge [-F <num>] [-vh]\n" ); + Abc_Print( -2, "\t performs structural K-step target enlargement\n" ); + Abc_Print( -2, "\t-F <num> : the number of timeframes to unroll (<num> > 0) [default = %d]\n", nFrames ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -19840,8 +19973,7 @@ int Abc_CommandTestCex( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); Gia_Man_t * pGia = Gia_ManFromAigSimple( pAig ); - if ( !Gia_ManVerifyCounterExample( pGia, pAbc->pCex, 0 ) ) -// if ( !Ssw_SmlRunCounterExample( pAig, pAbc->pCex ) ) + if ( !Gia_ManVerifyCex( pGia, pAbc->pCex, 0 ) ) Abc_Print( 1, "Main AIG: The cex does not fail any outputs.\n" ); else Abc_Print( 1, "Main AIG: The cex is correct.\n" ); @@ -19860,7 +19992,7 @@ int Abc_CommandTestCex( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "And AIG: The number of POs (%d) is less than the PO index in cex (%d).\n", Gia_ManPoNum(pAbc->pGia), pAbc->pCex->iPo ); else { - if ( !Gia_ManVerifyCounterExample( pAbc->pGia, pAbc->pCex, 0 ) ) + if ( !Gia_ManVerifyCex( pAbc->pGia, pAbc->pCex, 0 ) ) Abc_Print( 1, "And AIG: The cex does not fail any outputs.\n" ); else Abc_Print( 1, "And AIG: The cex is correct.\n" ); @@ -24565,6 +24697,11 @@ int Abc_CommandAbc9Equiv2( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Equiv2(): There is no AIG.\n" ); return 1; } + if ( Gia_ManRegNum(pAbc->pGia) == 0 ) + { + Abc_Print( 0, "Abc_CommandAbc9Equiv2(): There is no flops. Nothing is done.\n" ); + return 0; + } if ( fUseCex ) { if ( pAbc->pCex->nPis != Gia_ManPiNum(pAbc->pGia) ) @@ -25845,23 +25982,30 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv ) { - char * pFileName = "gsrm.aig"; - char * pFileName2 = "gsyn.aig"; + char pFileName[10] = "gsrm.aig", pFileName2[10] = "gsyn.aig"; Gia_Man_t * pTemp, * pAux; int c, fVerbose = 0; int fSynthesis = 0; + int fSpeculate = 1; + int fSkipSome = 0; int fDualOut = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "dsvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "drsfvh" ) ) != EOF ) { switch ( c ) { case 'd': fDualOut ^= 1; break; - case 's': + case 'r': fSynthesis ^= 1; break; + case 's': + fSpeculate ^= 1; + break; + case 'f': + fSkipSome ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -25876,12 +26020,16 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Srm(): There is no AIG.\n" ); return 1; } - pTemp = Gia_ManSpecReduce( pAbc->pGia, fDualOut, fSynthesis, fVerbose ); + sprintf( pFileName, "gsrm%s.aig", fSpeculate? "" : "s" ); + sprintf( pFileName2, "gsyn%s.aig", fSpeculate? "" : "s" ); + pTemp = Gia_ManSpecReduce( pAbc->pGia, fDualOut, fSynthesis, fSpeculate, fSkipSome, fVerbose ); if ( pTemp ) { - pTemp = Gia_ManSeqStructSweep( pAux = pTemp, 1, 1, 0 ); - Gia_ManStop( pAux ); - + if ( fSpeculate ) + { + pTemp = Gia_ManSeqStructSweep( pAux = pTemp, 1, 1, 0 ); + Gia_ManStop( pAux ); + } Gia_WriteAiger( pTemp, pFileName, 0, 0 ); Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", pFileName ); Gia_ManPrintStatsShort( pTemp ); @@ -25904,10 +26052,12 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &srm [-dsvh]\n" ); + Abc_Print( -2, "usage: &srm [-drsfvh]\n" ); Abc_Print( -2, "\t writes speculatively reduced model into file \"%s\"\n", pFileName ); Abc_Print( -2, "\t-d : toggle creating dual output miter [default = %s]\n", fDualOut? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle writing reduced network for synthesis [default = %s]\n", fSynthesis? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle writing reduced network for synthesis [default = %s]\n", fSynthesis? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle using speculation at the internal nodes [default = %s]\n", fSpeculate? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle filtering to remove redundant equivalences [default = %s]\n", fSkipSome? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -25955,13 +26105,15 @@ int Abc_CommandAbc9Reduce( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Reduce(): There is no AIG.\n" ); return 1; } - pTemp = Gia_ManEquivReduce( pAbc->pGia, fUseAll, fDualOut, fVerbose ); - if ( pTemp != NULL ) + if ( fUseAll ) { + pTemp = Gia_ManEquivReduce( pAbc->pGia, fUseAll, fDualOut, fVerbose ); pTemp = Gia_ManSeqStructSweep( pTemp2 = pTemp, 1, 1, 0 ); Gia_ManStop( pTemp2 ); - Abc_CommandUpdate9( pAbc, pTemp ); } + else + pTemp = Gia_ManEquivReduceAndRemap( pAbc->pGia, 1, fDualOut ); + Abc_CommandUpdate9( pAbc, pTemp ); return 0; usage: @@ -25985,6 +26137,71 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9EquivMark( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManEquivMark( Gia_Man_t * p, char * pFileName, int fSkipSome, int fVerbose ); + char * pFileName; + int c, fVerbose = 0; + int fSkipSome = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "fvh" ) ) != EOF ) + { + switch ( c ) + { + case 'f': + fSkipSome ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Reduce(): There is no AIG.\n" ); + return 1; + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + // get the input file name + pFileName = argv[globalUtilOptind]; + // mark equivalences + Gia_ManEquivMark( pAbc->pGia, pFileName, fSkipSome, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: &equiv_mark [-fvh] <miter.aig>\n" ); + Abc_Print( -2, "\t marks equivalences using an external miter\n" ); + Abc_Print( -2, "\t-f : toggle the use of filtered equivalences [default = %s]\n", fSkipSome? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t<miter.aig> : file with the external miter to read\n"); + Abc_Print( -2, "\t \n" ); + Abc_Print( -2, "\t The external miter should be generated by &srm -s\n" ); + Abc_Print( -2, "\t and (partially) solved by any verification engine(s).\n" ); + Abc_Print( -2, "\t The external miter should have as many POs as\n" ); + Abc_Print( -2, "\t the number of POs in the current AIG plus\n" ); + Abc_Print( -2, "\t the number of equivalences in the current AIG.\n" ); + Abc_Print( -2, "\t If some POs are proved, the corresponding equivs\n" ); + Abc_Print( -2, "\t are marked as proved, to be reduced by &reduce.\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParCec_t ParsCec, * pPars = &ParsCec; @@ -27289,13 +27506,23 @@ usage: int Abc_CommandAbc9AbsRefine( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp = NULL; - int c, fVerbose = 0; - extern int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbose ); + int c; + int fTryFour = 1; + int fSensePath = 0; + int fVerbose = 0; + + extern int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fTryFour, int fSensePath, int fVerbose ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "tsvh" ) ) != EOF ) { switch ( c ) { + case 't': + fTryFour ^= 1; + break; + case 's': + fSensePath ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -27320,13 +27547,15 @@ int Abc_CommandAbc9AbsRefine( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9AbsRefine(): There is no counter-example.\n" ); return 1; } - pAbc->Status = Gia_ManCexAbstractionRefine( pAbc->pGia, pAbc->pCex, fVerbose ); + pAbc->Status = Gia_ManCexAbstractionRefine( pAbc->pGia, pAbc->pCex, fTryFour, fSensePath, fVerbose ); Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); return 0; usage: - Abc_Print( -2, "usage: &abs_refine [-vh]\n" ); + Abc_Print( -2, "usage: &abs_refine [-tsvh]\n" ); Abc_Print( -2, "\t refines the pre-computed flop map using the counter-example\n" ); + Abc_Print( -2, "\t-t : toggle trying four abstractions instead of one [default = %s]\n", fTryFour? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle using the path sensitization algorithm [default = %s]\n", fSensePath? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -27764,7 +27993,7 @@ usage: Abc_Print( -2, "\t-F num : max number of reachability iterations [default = %d]\n", pPars->nIterMax ); Abc_Print( -2, "\t-T num : approximate time limit in seconds (0=infinite) [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" ); - Abc_Print( -2, "\t-r : enable dynamic BDD variable reordering [default = %s]\n", pPars->fReorder? "yes": "no" ); + Abc_Print( -2, "\t-r : enable additional BDD var reordering before image [default = %s]\n", pPars->fReorder? "yes": "no" ); Abc_Print( -2, "\t-b : perform backward reachability analysis [default = %s]\n", pPars->fBackward? "yes": "no" ); Abc_Print( -2, "\t-y : skip checking property outputs [default = %s]\n", pPars->fSkipOutCheck? "yes": "no" ); Abc_Print( -2, "\t-z : skip reachability (run preparation phase only) [default = %s]\n", pPars->fSkipReach? "yes": "no" ); @@ -27896,7 +28125,7 @@ usage: Abc_Print( -2, "\t-F num : max number of reachability iterations [default = %d]\n", pPars->nIterMax ); Abc_Print( -2, "\t-T num : approximate time limit in seconds (0=infinite) [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" ); - Abc_Print( -2, "\t-r : enable dynamic BDD variable reordering [default = %s]\n", pPars->fReorder? "yes": "no" ); + Abc_Print( -2, "\t-r : enable additional BDD var reordering before image [default = %s]\n", pPars->fReorder? "yes": "no" ); Abc_Print( -2, "\t-y : skip checking property outputs [default = %s]\n", pPars->fSkipOutCheck? "yes": "no" ); Abc_Print( -2, "\t-z : skip reachability (run preparation phase only) [default = %s]\n", pPars->fSkipReach? "yes": "no" ); Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); diff --git a/src/base/abci/abcAuto.c b/src/base/abci/abcAuto.c index b595a536..02d5fd17 100644 --- a/src/base/abci/abcAuto.c +++ b/src/base/abci/abcAuto.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -63,7 +64,7 @@ void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose ) nInputs = Abc_NtkCiNum(pNtk); nOutputs = Abc_NtkCoNum(pNtk); // dd = pNtk->pManGlob; - dd = Abc_NtkGlobalBddMan( pNtk ); + dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); // complement the global functions vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c index 840fd6f5..f69c80bd 100644 --- a/src/base/abci/abcBalance.c +++ b/src/base/abci/abcBalance.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcBm.c b/src/base/abci/abcBm.c index 8855fd9e..25fba5fd 100644 --- a/src/base/abci/abcBm.c +++ b/src/base/abci/abcBm.c @@ -28,6 +28,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" #include "satSolver.h" diff --git a/src/base/abci/abcCas.c b/src/base/abci/abcCas.c index 76fe5e9f..68c91343 100644 --- a/src/base/abci/abcCas.c +++ b/src/base/abci/abcCas.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -69,16 +70,16 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer if ( fVerbose ) { - DdManager * dd = Abc_NtkGlobalBddMan( pNtk ); + DdManager * dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); printf( "Shared BDD size = %6d nodes. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); ABC_PRT( "BDD construction time", clock() - clk ); } // collect global BDDs - dd = Abc_NtkGlobalBddMan( pNtk ); + dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); ppOutputs = ABC_ALLOC( DdNode *, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) - ppOutputs[i] = Abc_ObjGlobalBdd(pNode); + ppOutputs[i] = (DdNode *)Abc_ObjGlobalBdd(pNode); // call the decomposition pFileGeneric = Extra_FileNameGeneric( pNtk->pSpec ); diff --git a/src/base/abci/abcCascade.c b/src/base/abci/abcCascade.c index a2e6d234..177c806e 100644 --- a/src/base/abci/abcCascade.c +++ b/src/base/abci/abcCascade.c @@ -30,6 +30,7 @@ ABC_NAMESPACE_IMPL_START #define BDD_FUNC_MAX 256 //extern void Abc_NodeShowBddOne( DdManager * dd, DdNode * bFunc ); +extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -37,6 +38,641 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Derive BDD of the characteristic function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_ResBuildBdd( Abc_Ntk_t * pNtk, DdManager * dd ) +{ + Vec_Ptr_t * vNodes, * vBdds, * vLocals; + Abc_Obj_t * pObj, * pFanin; + DdNode * bFunc, * bPart, * bTemp, * bVar; + int i, k; + assert( Abc_NtkIsSopLogic(pNtk) ); + assert( Abc_NtkCoNum(pNtk) <= 3 ); + vBdds = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + Abc_NtkForEachCi( pNtk, pObj, i ) + Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), Cudd_bddIthVar(dd, i) ); + // create internal node BDDs + vNodes = Abc_NtkDfs( pNtk, 0 ); + vLocals = Vec_PtrAlloc( 6 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + if ( Abc_ObjFaninNum(pObj) == 0 ) + { + bFunc = Cudd_NotCond( Cudd_ReadOne(dd), Abc_SopIsConst0((char *)pObj->pData) ); Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc ); + continue; + } + Vec_PtrClear( vLocals ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Vec_PtrPush( vLocals, Vec_PtrEntry(vBdds, Abc_ObjId(pFanin)) ); + bFunc = Abc_ConvertSopToBdd( dd, (char *)pObj->pData, (DdNode **)Vec_PtrArray(vLocals) ); Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc ); + } + Vec_PtrFree( vLocals ); + // create char function + bFunc = Cudd_ReadOne( dd ); Cudd_Ref( bFunc ); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + bVar = Cudd_bddIthVar( dd, i + Abc_NtkCiNum(pNtk) ); + bTemp = (DdNode *)Vec_PtrEntry( vBdds, Abc_ObjFaninId0(pObj) ); + bPart = Cudd_bddXnor( dd, bTemp, bVar ); Cudd_Ref( bPart ); + bFunc = Cudd_bddAnd( dd, bTemp = bFunc, bPart ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bPart ); + } + // dereference + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + Cudd_RecursiveDeref( dd, (DdNode *)Vec_PtrEntry(vBdds, Abc_ObjId(pObj)) ); + Vec_PtrFree( vBdds ); + Vec_PtrFree( vNodes ); + // reorder + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Initializes variable partition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResStartPart( int nInputs, unsigned uParts[], int nParts ) +{ + int i, Group, Left, Shift = 0, Count = 0; + Group = nInputs / nParts; + Left = nInputs % nParts; + for ( i = 0; i < Left; i++ ) + { + uParts[i] = (~((~0) << (Group+1))) << Shift; + Shift += Group+1; + } + for ( ; i < nParts; i++ ) + { + uParts[i] = (~((~0) << Group)) << Shift; + Shift += Group; + } + for ( i = 0; i < nParts; i++ ) + Count += Extra_WordCountOnes( uParts[i] ); + assert( Count == nInputs ); +} + +/**Function************************************************************* + + Synopsis [Initializes variable partition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResStartPart2( int nInputs, unsigned uParts[], int nParts ) +{ + int i, Count = 0; + for ( i = 0; i < nParts; i++ ) + uParts[i] = 0; + for ( i = 0; i < nInputs; i++ ) + uParts[i % nParts] |= (1 << i); + for ( i = 0; i < nParts; i++ ) + Count += Extra_WordCountOnes( uParts[i] ); + assert( Count == nInputs ); +} + +/**Function************************************************************* + + Synopsis [Returns one if unique pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResCheckUnique( char Pats[], int nPats, int pat ) +{ + int i; + for ( i = 0; i < nPats; i++ ) + if ( Pats[i] == pat ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Check if pattern is decomposable with non-strict.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResCheckNonStrict( char Pattern[], int nVars, int nBits ) +{ + static char Pat0[256], Pat1[256]; + int v, m, nPats0, nPats1, nNumber = (1 << (nBits - 1)); + int Result = 0; + for ( v = 0; v < nVars; v++ ) + { + nPats0 = nPats1 = 0; + for ( m = 0; m < (1<<nVars); m++ ) + { + if ( (m & (1 << v)) == 0 ) + { + if ( Abc_ResCheckUnique( Pat0, nPats0, Pattern[m] ) ) + { + Pat0[ nPats0++ ] = Pattern[m]; + if ( nPats0 > nNumber ) + break; + } + } + else + { + if ( Abc_ResCheckUnique( Pat1, nPats1, Pattern[m] ) ) + { + Pat1[ nPats1++ ] = Pattern[m]; + if ( nPats1 > nNumber ) + break; + } + } + } + if ( m == (1<<nVars) ) + Result++; + } + return Result; +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResCofCount( DdManager * dd, DdNode * bFunc, unsigned uMask, int * pCheck ) +{ + static char Pattern[256]; + DdNode * pbVars[32]; + Vec_Ptr_t * vCofs; + DdNode * bCof, * bCube, * bTemp; + int i, k, Result, nVars = 0; + // collect variables + for ( i = 0; i < 32; i++ ) + if ( uMask & (1 << i) ) + pbVars[nVars++] = dd->vars[i]; + assert( nVars <= 8 ); + // compute cofactors + vCofs = Vec_PtrAlloc( 100 ); + for ( i = 0; i < (1 << nVars); i++ ) + { + bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube ); + bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof ); + Cudd_RecursiveDeref( dd, bCube ); + Vec_PtrForEachEntry( DdNode *, vCofs, bTemp, k ) + if ( bTemp == bCof ) + break; + if ( k < Vec_PtrSize(vCofs) ) + Cudd_RecursiveDeref( dd, bCof ); + else + Vec_PtrPush( vCofs, bCof ); + Pattern[i] = k; + } + Result = Vec_PtrSize( vCofs ); + Vec_PtrForEachEntry( DdNode *, vCofs, bCof, i ) + Cudd_RecursiveDeref( dd, bCof ); + Vec_PtrFree( vCofs ); + if ( pCheck ) + { + *pCheck = Abc_ResCheckNonStrict( Pattern, nVars, Extra_Base2Log(Result) ); +/* + if ( *pCheck == 1 && nVars == 4 && Result == 8 ) + { + for ( i = 0; i < (1 << nVars); i++ ) + printf( "%d ", Pattern[i] ); + i = 0; + } +*/ + } + return Result; +} + +/**Function************************************************************* + + Synopsis [Computes cost of the partition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResCost( DdManager * dd, DdNode * bFunc, unsigned uMask, int * pnCofs, int * pCheck ) +{ + int nCofs = Abc_ResCofCount( dd, bFunc, uMask, pCheck ); + int n2Log = Extra_Base2Log( nCofs ); + if ( pnCofs ) *pnCofs = nCofs; + return 10000 * n2Log + (nCofs - (1 << (n2Log-1))) * (nCofs - (1 << (n2Log-1))); +} + +/**Function************************************************************* + + Synopsis [Migrates variables between the two groups.] + + Description [Returns 1 if there is change.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResMigrate( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int iPart1, int iPart2 ) +{ + unsigned uParts2[2] = { uParts[iPart1], uParts[iPart2] }; + int i, k, CostCur, CostBest, fChange = 0; + assert( (uParts[iPart1] & uParts[iPart2]) == 0 ); + CostBest = Abc_ResCost( dd, bFunc, uParts[iPart1], NULL, NULL ) + + Abc_ResCost( dd, bFunc, uParts[iPart2], NULL, NULL ); + for ( i = 0; i < nInputs; i++ ) + if ( uParts[iPart1] & (1 << i) ) + { + for ( k = 0; k < nInputs; k++ ) + if ( uParts[iPart2] & (1 << k) ) + { + if ( i == k ) + continue; + uParts[iPart1] ^= (1 << i) | (1 << k); + uParts[iPart2] ^= (1 << i) | (1 << k); + CostCur = Abc_ResCost( dd, bFunc, uParts[iPart1], NULL, NULL ) + Abc_ResCost( dd, bFunc, uParts[iPart2], NULL, NULL ); + if ( CostCur < CostBest ) + { + CostCur = CostBest; + uParts2[0] = uParts[iPart1]; + uParts2[1] = uParts[iPart2]; + fChange = 1; + } + uParts[iPart1] ^= (1 << i) | (1 << k); + uParts[iPart2] ^= (1 << i) | (1 << k); + } + } + uParts[iPart1] = uParts2[0]; + uParts[iPart2] = uParts2[1]; + return fChange; +} + +/**Function************************************************************* + + Synopsis [Migrates variables between the two groups.] + + Description [Returns 1 if there is change.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResPrint( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int nParts ) +{ + int i, k, nCofs, Cost, CostAll = 0, fCheck; + for ( i = 0; i < nParts; i++ ) + { + Cost = Abc_ResCost( dd, bFunc, uParts[i], &nCofs, &fCheck ); + CostAll += Cost; + for ( k = 0; k < nInputs; k++ ) + printf( "%c", (uParts[i] & (1 << k))? 'a' + k : '-' ); + printf( " %2d %d-%d %6d ", nCofs, Extra_Base2Log(nCofs), fCheck, Cost ); + } + printf( "%4d\n", CostAll ); +} + +/**Function************************************************************* + + Synopsis [PrintCompute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResPrintAllCofs( DdManager * dd, DdNode * bFunc, int nInputs, int nCofMax ) +{ + int i, k, nBits, nCofs, Cost, fCheck; + for ( i = 0; i < (1<<nInputs); i++ ) + { + nBits = Extra_WordCountOnes( i ); + if ( nBits < 3 || nBits > 6 ) + continue; + Cost = Abc_ResCost( dd, bFunc, i, &nCofs, &fCheck ); + if ( nCofs > nCofMax ) + continue; + for ( k = 0; k < nInputs; k++ ) + printf( "%c", (i & (1 << k))? 'a' + k : '-' ); + printf( " n=%2d c=%2d l=%d-%d %6d\n", + Extra_WordCountOnes(i), nCofs, Extra_Base2Log(nCofs), fCheck, Cost ); + } +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResSwapRandom( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int nParts, int nTimes ) +{ + int i, k, n, iPart1, iPart2; + for ( n = 0; n < nTimes; ) + { + // get the vars + i = k = 0; + while ( i == k ) + { + i = rand() % nInputs; + k = rand() % nInputs; + } + // find the groups + for ( iPart1 = 0; iPart1 < nParts; iPart1++ ) + if ( uParts[iPart1] & (1 << i) ) + break; + for ( iPart2 = 0; iPart2 < nParts; iPart2++ ) + if ( uParts[iPart2] & (1 << k) ) + break; + if ( iPart1 == iPart2 ) + continue; + // swap the vars + uParts[iPart1] ^= (1 << i) | (1 << k); + uParts[iPart2] ^= (1 << i) | (1 << k); + n++; +//printf( " " ); +//Abc_ResPrint( dd, bFunc, nInputs, uParts, nParts ); + } +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResPartition( DdManager * dd, DdNode * bFunc, int nInputs ) +{ + int nIters = 5; + unsigned uParts[10]; + int i, fChange = 1; + int nSuppSize = Cudd_SupportSize( dd, bFunc ); + printf( "Ins =%3d. Outs =%2d. Nodes =%3d. Supp =%2d.\n", + nInputs, dd->size-nInputs, Cudd_DagSize(bFunc), nSuppSize ); +//Abc_ResPrintAllCofs( dd, bFunc, nInputs, 4 ); + + if ( nSuppSize <= 6 ) + { + printf( "Support is less or equal than 6\n" ); + return; + } + if ( nInputs <= 12 ) + { + Abc_ResStartPart( nInputs, uParts, 2 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 ); + for ( i = 0; i < nIters; i++ ) + { + if ( i ) + { + printf( "Randomizing... \n" ); + Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 2, 20 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 ); + } + fChange = 1; + while ( fChange ) + { + fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 ); + } + } + } + else if ( nInputs > 12 && nInputs <= 18 ) + { + Abc_ResStartPart( nInputs, uParts, 3 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 ); + for ( i = 0; i < nIters; i++ ) + { + if ( i ) + { + printf( "Randomizing... \n" ); + Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 3, 20 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 ); + } + fChange = 1; + while ( fChange ) + { + fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 2 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 2 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 ); + } + } + } + else if ( nInputs > 18 && nInputs <= 24 ) + { + Abc_ResStartPart( nInputs, uParts, 4 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + for ( i = 0; i < nIters; i++ ) + { + if ( i ) + { + printf( "Randomizing... \n" ); + Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 4, 20 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + } + fChange = 1; + while ( fChange ) + { + fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 2 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 3 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 2 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 3 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 2, 3 ); + Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 ); + } + } + } +// else assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ResPartitionTest( Abc_Ntk_t * pNtk ) +{ + DdManager * dd; + DdNode * bFunc; + dd = Cudd_Init( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + bFunc = Abc_ResBuildBdd( pNtk, dd ); Cudd_Ref( bFunc ); + Abc_ResPartition( dd, bFunc, Abc_NtkCiNum(pNtk) ); + Cudd_RecursiveDeref( dd, bFunc ); + Extra_StopManager( dd ); +} + + + + + + + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkBddCofCount( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nVars ) +{ + Vec_Ptr_t * vCofs; + DdNode * bCof, * bCube; + int i, Result; + vCofs = Vec_PtrAlloc( 100 ); + for ( i = 0; i < (1 << nVars); i++ ) + { + bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube ); + bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof ); + Cudd_RecursiveDeref( dd, bCube ); + if ( Vec_PtrPushUnique( vCofs, bCof ) ) + Cudd_RecursiveDeref( dd, bCof ); + } + Result = Vec_PtrSize( vCofs ); + Vec_PtrForEachEntry( DdNode *, vCofs, bCof, i ) + Cudd_RecursiveDeref( dd, bCof ); + Vec_PtrFree( vCofs ); + return Result; +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkExploreCofs2( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nIns, int nLutSize ) +{ + int i; + printf( "Inputs = %2d. Nodes = %2d. LutSize = %2d.\n", nIns, Cudd_DagSize(bFunc), nLutSize ); + for ( i = 0; i <= nIns - nLutSize; i++ ) + printf( "[%2d %2d] : %3d\n", i, i+nLutSize-1, Abc_NtkBddCofCount(dd, bFunc, dd->vars+i, nLutSize) ); +} + +/**Function************************************************************* + + Synopsis [Compute the number of distinct cofactors in the BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkExploreCofs( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nIns, int nLutSize ) +{ + DdManager * ddNew; + DdNode * bFuncNew; + DdNode * pbVarsNew[32]; + int i, k, c, nCofs, nBits; + + ddNew = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_ShuffleHeap( ddNew, dd->invperm ); + bFuncNew = Cudd_bddTransfer( dd, ddNew, bFunc ); Cudd_Ref( bFuncNew ); + + for ( i = 0; i < (1 << nIns); i++ ) + { + nBits = Extra_WordCountOnes(i); + if ( nBits != nLutSize && nBits != nLutSize -1 && nBits != nLutSize -2 ) + continue; + for ( c = k = 0; k < nIns; k++ ) + { + if ( (i & (1 << k)) == 0 ) + continue; +// pbVarsNew[c++] = pbVars[k]; + pbVarsNew[c++] = ddNew->vars[k]; + } + nCofs = Abc_NtkBddCofCount(ddNew, bFuncNew, pbVarsNew, c); + if ( nCofs > 8 ) + continue; + + for ( c = k = 0; k < nIns; k++ ) + { + if ( (i & (1 << k)) == 0 ) + { + printf( "-" ); + continue; + } + printf( "%c", k + 'a' ); + } + printf( " : %2d\n", nCofs ); + } + + Cudd_RecursiveDeref( ddNew, bFuncNew ); + Extra_StopManager( ddNew ); +} + +/**Function************************************************************* + Synopsis [Find the constant node corresponding to the encoded output value.] Description [] @@ -126,9 +762,9 @@ DdNode * Abc_NtkBddToAdd( DdManager * dd, DdNode * bFunc, int nOuts ) stmm_table * tTable; stmm_generator * gen; tTable = stmm_init_table( st_ptrcmp, st_ptrhash ); - aFunc = Abc_NtkBddToAdd_rec( dd, Cudd_Regular(bFunc), nOuts, tTable, Cudd_IsComplement(bFunc) ); Cudd_Ref(aFunc); + aFunc = Abc_NtkBddToAdd_rec( dd, Cudd_Regular(bFunc), nOuts, tTable, Cudd_IsComplement(bFunc) ); stmm_foreach_item( tTable, gen, (char **)&bTemp, (char **)&aTemp ) - Cudd_RecursiveDeref( dd, aFunc ); + Cudd_RecursiveDeref( dd, aTemp ); stmm_free_table( tTable ); Cudd_Deref( aFunc ); return aFunc; @@ -136,6 +772,64 @@ DdNode * Abc_NtkBddToAdd( DdManager * dd, DdNode * bFunc, int nOuts ) /**Function************************************************************* + Synopsis [Recursively construct ADD for BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkAddToBdd_rec( DdManager * dd, DdNode * aFunc, int nIns, int nOuts, stmm_table * tTable ) +{ + DdNode * bFunc0, * bFunc1, * bFunc; + DdNode ** ppSlot; + assert( !Cudd_IsComplement(aFunc) ); + if ( stmm_find_or_add( tTable, (char *)aFunc, (char ***)&ppSlot ) ) + return *ppSlot; + if ( Cudd_IsConstant(aFunc) ) + { + assert( Cudd_ReadSize(dd) >= nIns + nOuts ); + bFunc = Extra_bddBitsToCube( dd, (int)Cudd_V(aFunc), nOuts, dd->vars + nIns, 1 ); Cudd_Ref( bFunc ); + } + else + { + assert( aFunc->index < nIns ); + bFunc0 = Abc_NtkAddToBdd_rec( dd, cuddE(aFunc), nIns, nOuts, tTable ); + bFunc1 = Abc_NtkAddToBdd_rec( dd, cuddT(aFunc), nIns, nOuts, tTable ); + bFunc = Cudd_bddIte( dd, Cudd_bddIthVar(dd, aFunc->index), bFunc1, bFunc0 ); Cudd_Ref( bFunc ); + } + return (*ppSlot = bFunc); +} + +/**Function************************************************************* + + Synopsis [R] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkAddToBdd( DdManager * dd, DdNode * aFunc, int nIns, int nOuts ) +{ + DdNode * bFunc, * bTemp, * aTemp; + stmm_table * tTable; + stmm_generator * gen; + tTable = stmm_init_table( st_ptrcmp, st_ptrhash ); + bFunc = Abc_NtkAddToBdd_rec( dd, aFunc, nIns, nOuts, tTable ); + stmm_foreach_item( tTable, gen, (char **)&aTemp, (char **)&bTemp ) + Cudd_RecursiveDeref( dd, bTemp ); + stmm_free_table( tTable ); + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + Synopsis [Computes the characteristic function.] Description [] @@ -177,22 +871,37 @@ DdNode * Abc_NtkBddDecCharFunc( DdManager * dd, DdNode ** pFuncs, int nOuts, int SeeAlso [] ***********************************************************************/ -void Abc_NtkBddDecTry( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nOuts, int Mask, int nBits ) +DdNode * Abc_NtkBddDecTry( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nIns, int nOuts, int Mask, int nBits ) { - DdNode * bFunc, * aFunc, * aFuncNew; - // drive the characteristic function + int fReorder = 0; + DdNode * bFunc;//, * aFunc, * aFuncNew; + // derive the characteristic function bFunc = Abc_NtkBddDecCharFunc( dd, pFuncs, nOuts, Mask, nBits ); Cudd_Ref( bFunc ); -//Abc_NodeShowBddOne( dd, bFunc ); +/* // transfer to ADD aFunc = Abc_NtkBddToAdd( dd, bFunc, nOuts ); Cudd_Ref( aFunc ); Cudd_RecursiveDeref( dd, bFunc ); //Abc_NodeShowBddOne( dd, aFunc ); + // perform reordering for BDD width - aFuncNew = Extra_Reorder( pReo, dd, aFunc, NULL ); Cudd_Ref( aFuncNew ); + if ( fReorder ) + { + aFuncNew = Extra_Reorder( pReo, dd, aFunc, NULL ); Cudd_Ref( aFuncNew ); + printf( "Before = %d. After = %d.\n", Cudd_DagSize(aFunc), Cudd_DagSize(aFuncNew) ); + Cudd_RecursiveDeref( dd, aFunc ); + } + else + aFuncNew = aFunc; + + // get back to BDD + bFunc = Abc_NtkAddToBdd( dd, aFuncNew, nIns, nOuts ); Cudd_Ref( bFunc ); Cudd_RecursiveDeref( dd, aFuncNew ); - Cudd_RecursiveDeref( dd, aFunc ); +//Abc_NodeShowBddOne( dd, bFunc ); // print the result - reoProfileWidthPrint( pReo ); +// reoProfileWidthPrint( pReo ); +*/ + Cudd_Deref( bFunc ); + return bFunc; } /**Function************************************************************* @@ -206,7 +915,7 @@ void Abc_NtkBddDecTry( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nOu SeeAlso [] ***********************************************************************/ -void Abc_NtkBddDecInt( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nOuts ) +DdNode * Abc_NtkBddDecInt( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nIns, int nOuts ) { /* int i, k; @@ -221,8 +930,53 @@ void Abc_NtkBddDecInt( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nOu } } */ - Abc_NtkBddDecTry( pReo, dd, pFuncs, nOuts, ~(1<<(32-nOuts)), nOuts ); + return Abc_NtkBddDecTry( pReo, dd, pFuncs, nIns, nOuts, ~(1<<(32-nOuts)), nOuts ); + +} + +/**Function************************************************************* + + Synopsis [Evaluate Sasao's decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreateFromCharFunc( Abc_Ntk_t * pNtk, DdManager * dd, DdNode * bFunc ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode, * pNodeNew, * pNodePo; + int i; + // start the network + pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 ); + pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + // create inputs for CIs + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + Abc_NtkForEachCi( pNtk, pNode, i ) + { + pNode->pCopy = Abc_NtkCreatePi( pNtkNew ); + Abc_ObjAddFanin( pNodeNew, pNode->pCopy ); + Abc_ObjAssignName( pNode->pCopy, Abc_ObjName(pNode), NULL ); + } + // create inputs for COs + Abc_NtkForEachCo( pNtk, pNode, i ) + { + pNode->pCopy = Abc_NtkCreatePi( pNtkNew ); + Abc_ObjAddFanin( pNodeNew, pNode->pCopy ); + Abc_ObjAssignName( pNode->pCopy, Abc_ObjName(pNode), NULL ); + } + // transfer BDD + pNodeNew->pData = Extra_TransferLevelByLevel( dd, (DdManager *)pNtkNew->pManFunc, bFunc ); Cudd_Ref( pNodeNew->pData ); + // transfer BDD into to be the local function + pNodePo = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pNodePo, pNodeNew ); + Abc_ObjAssignName( pNodePo, "out", NULL ); + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateFromCharFunc(): Network check has failed.\n" ); + return pNtkNew; } /**Function************************************************************* @@ -236,43 +990,55 @@ void Abc_NtkBddDecInt( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nOu SeeAlso [] ***********************************************************************/ -void Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose ) +Abc_Ntk_t * Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose ) { int nBddSizeMax = 1000000; int fDropInternal = 0; int fReorder = 1; + Abc_Ntk_t * pNtkNew; reo_man * pReo; DdManager * dd; DdNode * pFuncs[BDD_FUNC_MAX]; + DdNode * bFunc; Abc_Obj_t * pNode; int i; assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkCoNum(pNtk) <= BDD_FUNC_MAX ); - dd = Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, fVerbose ); if ( dd == NULL ) { Abc_Print( -1, "Construction of global BDDs has failed.\n" ); - return; + return NULL; } + // collect global BDDs + Abc_NtkForEachCo( pNtk, pNode, i ) + pFuncs[i] = (DdNode *)Abc_ObjGlobalBdd(pNode); - assert( dd->size == Abc_NtkCiNum(pNtk) ); // create new variables at the bottom + assert( dd->size == Abc_NtkCiNum(pNtk) ); for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ ) Cudd_addNewVarAtLevel( dd, dd->size ); - // create terminals of MTBDD -// for ( i = 0; i < (1 << Abc_NtkCoNum(pNtk)); i++ ) -// Cudd_addConst( dd, i ); - // collect global BDDs - Abc_NtkForEachCo( pNtk, pNode, i ) - pFuncs[i] = Abc_ObjGlobalBdd(pNode); + // prepare reordering engine pReo = Extra_ReorderInit( Abc_NtkCiNum(pNtk), 1000 ); Extra_ReorderSetMinimizationType( pReo, REO_MINIMIZE_WIDTH ); + Extra_ReorderSetVerification( pReo, 1 ); + Extra_ReorderSetVerbosity( pReo, 1 ); - Abc_NtkBddDecInt( pReo, dd, pFuncs, Abc_NtkCoNum(pNtk) ); + // derive characteristic function + bFunc = Abc_NtkBddDecInt( pReo, dd, pFuncs, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk) ); Cudd_Ref( bFunc ); Extra_ReorderQuit( pReo ); +Abc_NtkExploreCofs( dd, bFunc, dd->vars, Abc_NtkCiNum(pNtk), 6 ); + + // create new network +// pNtkNew = Abc_NtkCreateFromCharFunc( pNtk, dd, bFunc ); + pNtkNew = Abc_NtkDup( pNtk ); + + // cleanup + Cudd_RecursiveDeref( dd, bFunc ); Abc_NtkFreeGlobalBdds( pNtk, 1 ); + return pNtkNew; } ABC_NAMESPACE_IMPL_END diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c index 1b7709c5..07996b9a 100644 --- a/src/base/abci/abcCollapse.c +++ b/src/base/abci/abcCollapse.c @@ -19,7 +19,7 @@ ***********************************************************************/ #include "abc.h" -//#include "reo.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -57,7 +57,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i return NULL; if ( fVerbose ) { - DdManager * dd = Abc_NtkGlobalBddMan( pNtk ); + DdManager * dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); printf( "Shared BDD size = %6d nodes. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); ABC_PRT( "BDD construction time", clock() - clk ); } @@ -114,7 +114,7 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) Abc_Ntk_t * pNtkNew; Abc_Obj_t * pNode, * pDriver, * pNodeNew; // DdManager * dd = pNtk->pManGlob; - DdManager * dd = Abc_NtkGlobalBddMan( pNtk ); + DdManager * dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); int i; // pReo = Extra_ReorderInit( Abc_NtkCiNum(pNtk), 1000 ); @@ -136,7 +136,7 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) continue; } // pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, Vec_PtrEntry(pNtk->vFuncsGlob, i) ); - pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, Abc_ObjGlobalBdd(pNode) ); + pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)Abc_ObjGlobalBdd(pNode) ); Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); // Extra_ShuffleTest( pReo, dd, Abc_ObjGlobalBdd(pNode) ); diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index 10cacff1..a08ce490 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -20,6 +20,7 @@ #include "abc.h" #include "cut.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index a6fa9ce6..b28d3de4 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -21,7 +21,6 @@ #include "abc.h" #include "main.h" #include "giaAig.h" -#include "saig.h" #include "dar.h" #include "cnf.h" #include "fra.h" @@ -232,7 +231,6 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) { Vec_Ptr_t * vNodes; Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObjNew; Aig_Obj_t * pObj; int i; assert( pMan->nAsserts == 0 ); @@ -260,13 +258,6 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); } // if there are assertions, add them - if ( pMan->nAsserts > 0 ) - Aig_ManForEachAssert( pMan, pObj, i ) - { - pObjNew = Abc_NtkCreateAssert(pNtkNew); - Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) ); - Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); - } if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" ); return pNtkNew; @@ -387,13 +378,6 @@ Abc_Ntk_t * Abc_NtkFromDarSeqSweep( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) } } // if there are assertions, add them - if ( pMan->nAsserts > 0 ) - Aig_ManForEachAssert( pMan, pObj, i ) - { - pObjNew = Abc_NtkCreateAssert(pNtkNew); - Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) ); - Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); - } if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" ); return pNtkNew; @@ -1147,10 +1131,10 @@ Abc_Ntk_t * Abc_NtkConstructFromCnf( Abc_Ntk_t * pNtk, Cnf_Man_t * p, Vec_Ptr_t { uTruth = 0xFFFF & *Cnf_CutTruth(pCut); Cnf_SopConvertToVector( p->pSops[uTruth], p->pSopSizes[uTruth], vCover ); - pNodeNew->pData = Abc_SopCreateFromIsop( (Extra_MmFlex_t *)pNtkNew->pManFunc, pCut->nFanins, vCover ); + pNodeNew->pData = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, pCut->nFanins, vCover ); } else - pNodeNew->pData = Abc_SopCreateFromIsop( (Extra_MmFlex_t *)pNtkNew->pManFunc, pCut->nFanins, pCut->vIsop[1] ); + pNodeNew->pData = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, pCut->nFanins, pCut->vIsop[1] ); // save the node pObj->pData = pNodeNew; } @@ -1790,7 +1774,7 @@ ABC_PRT( "Time", clock() - clk ); // verify counter-example if ( pNtk->pSeqModel ) { - status = Ssw_SmlRunCounterExample( pMan, pNtk->pSeqModel ); + status = Saig_ManVerifyCex( pMan, pNtk->pSeqModel ); if ( status == 0 ) printf( "Abc_NtkDarBmc(): Counter-example verification has FAILED.\n" ); } @@ -1857,7 +1841,7 @@ int Abc_NtkDarBmc3( Abc_Ntk_t * pNtk, Saig_ParBmc_t * pPars ) ABC_PRT( "Time", clock() - clk ); if ( pNtk->pSeqModel ) { - status = Ssw_SmlRunCounterExample( pMan, pNtk->pSeqModel ); + status = Saig_ManVerifyCex( pMan, pNtk->pSeqModel ); if ( status == 0 ) printf( "Abc_NtkDarBmc3(): Counter-example verification has FAILED.\n" ); } @@ -1902,7 +1886,7 @@ int Abc_NtkDarBmcInter_int( Aig_Man_t * pMan, Inter_ManParams_t * pPars, Aig_Man pTemp->pSeqModel = NULL; RetValue = Fra_FraigSat( pTemp, pPars->nBTLimit, 0, 0, 0, 0 ); if ( pTemp->pData ) - pTemp->pSeqModel = Gia_ManCreateFromComb( Aig_ManRegNum(pMan), Saig_ManPiNum(pMan), i, (int *)pTemp->pData ); + pTemp->pSeqModel = Abc_CexCreate( Aig_ManRegNum(pMan), Saig_ManPiNum(pMan), (int *)pTemp->pData, 0, i, 1 ); // pNtk->pModel = pTemp->pData, pTemp->pData = NULL; } else @@ -2150,7 +2134,7 @@ int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar ) { Abc_Cex_t * pCex = pNtk->pSeqModel; printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", pCex->iPo, pCex->iFrame ); - if ( !Ssw_SmlRunCounterExample( pMan, pNtk->pSeqModel ) ) + if ( !Saig_ManVerifyCex( pMan, pNtk->pSeqModel ) ) printf( "Abc_NtkDarProve(): Counter-example verification has FAILED.\n" ); } } @@ -2274,7 +2258,7 @@ int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars, Abc_Cex_t ** ppCex ) Aig_Man_t * pTemp = Saig_ManDupOrpos( pMan ); RetValue = Pdr_ManSolve( pTemp, pPars, ppCex ); if ( RetValue == 0 ) - (*ppCex)->iPo = Ssw_SmlFindOutputCounterExample( pMan, *ppCex ); + (*ppCex)->iPo = Saig_ManFindFailedPoCex( pMan, *ppCex ); Aig_ManStop( pTemp ); } else @@ -2290,7 +2274,7 @@ int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars, Abc_Cex_t ** ppCex ) assert( 0 ); ABC_PRT( "Time", clock() - clk ); - if ( *ppCex && !Ssw_SmlRunCounterExample( pMan, *ppCex ) ) + if ( *ppCex && !Saig_ManVerifyCex( pMan, *ppCex ) ) printf( "Abc_NtkDarPdr(): Counter-example verification has FAILED.\n" ); Aig_ManStop( pMan ); return RetValue; @@ -2710,7 +2694,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation iterated %d times with %d words asserted output %d in frame %d. ", nFrames, nWords, pCex->iPo, pCex->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } @@ -2737,7 +2721,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation of %d frames with %d words asserted output %d in frame %d. ", nFrames, nWords, pCex->iPo, pCex->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } @@ -2767,7 +2751,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation of %d frames with %d words asserted output %d in frame %d. ", nFrames, nWords, pCex->iPo, pCex->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } @@ -2798,7 +2782,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation of %d frames with %d words asserted output %d in frame %d. ", nFrames, nWords, pGia->pCexSeq->iPo, pGia->pCexSeq->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pGia->pCexSeq ); + status = Saig_ManVerifyCex( pMan, pGia->pCexSeq ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } @@ -2825,7 +2809,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation of %d frames with %d words asserted output %d in frame %d. ", nFrames, nWords, pCex->iPo, pCex->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } @@ -2847,7 +2831,7 @@ int Abc_NtkDarSeqSim( Abc_Ntk_t * pNtk, int nFrames, int nWords, int TimeOut, in { printf( "Simulation of %d frames with %d words asserted output %d in frame %d. ", nFrames, nWords, pCex->iPo, pCex->iFrame ); - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); if ( status == 0 ) printf( "Abc_NtkDarSeqSim(): Counter-example verification has FAILED.\n" ); } diff --git a/src/base/abci/abcDprove2.c b/src/base/abci/abcDprove2.c deleted file mode 100644 index 7d432612..00000000 --- a/src/base/abci/abcDprove2.c +++ /dev/null @@ -1,405 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcDprove2.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Implementation of "dprove2".] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcDprove2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "aig.h" -#include "saig.h" -#include "fra.h" -#include "ssw.h" -#include "gia.h" -#include "giaAig.h" -#include "cec.h" -#include "int.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern int Abc_NtkDarBmcInter_int( Aig_Man_t * pMan, Inter_ManParams_t * pPars ); - -extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); -extern Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ); -extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); -extern int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar ); - -extern void * Abc_FrameReadSave1(); -extern void * Abc_FrameReadSave2(); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Implements model checking based on abstraction and speculation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkDProve2( Abc_Ntk_t * pNtk, int nConfLast, int fSeparate, int fVeryVerbose, int fVerbose ) -{ - Abc_Ntk_t * pNtk2; - Aig_Man_t * pMan, * pTemp; - Aig_Man_t * pSave1 = NULL; - Gia_Man_t * pGia, * pSrm; - int spectried = 0; - int absquit = 0; - int absfail = 0; - int RetValue = -1; - int clkTotal = clock(); - // derive the AIG manager - ABC_FREE( pNtk->pModel ); - ABC_FREE( pNtk->pSeqModel ); - pMan = Abc_NtkToDar( pNtk, 0, 1 ); - if ( pMan == NULL ) - { - printf( "Converting miter into AIG has failed.\n" ); - return RetValue; - } - assert( pMan->nRegs > 0 ); - - if ( fVerbose ) - { - printf( "Starting BMC...\n" ); - Aig_ManPrintStats( pMan ); - } - // bmc2 -C 10000 - { - int nFrames = 2000; - int nNodeDelta = 2000; - int nBTLimit = 10000; // different from default - int nBTLimitAll = 2000000; - Saig_BmcPerform( pMan, 0, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVeryVerbose, 0, NULL ); - pNtk->pSeqModel = pMan->pSeqModel; pMan->pSeqModel = NULL; - if ( pNtk->pSeqModel ) - goto finish; - } - - if ( fVerbose ) - { - printf( "Starting \"dprove\"...\n" ); - Aig_ManPrintStats( pMan ); - } - // dprove -r -F 8 - { - Fra_Sec_t SecPar, * pSecPar = &SecPar; - Fra_SecSetDefaultParams( pSecPar ); - pSecPar->fTryBmc ^= 1; - pSecPar->fRetimeFirst ^= 1; - pSecPar->nFramesMax = 8; - pSecPar->fInterSeparate = 0; //fSeparate; - pSecPar->fVerbose = fVeryVerbose; - RetValue = Abc_NtkDarProve( pNtk, pSecPar ); - // analize the result - if ( RetValue != -1 ) - goto finish; - } - Aig_ManStop( pMan ); - pSave1 = (Aig_Man_t *)Abc_FrameReadSave1(); - pMan = Aig_ManDupSimple( pSave1 ); - - // abstraction - - if ( fVerbose ) - { - printf( "Abstraction...\n" ); - Aig_ManPrintStats( pMan ); - } -abstraction: - { - Gia_ParAbs_t Pars, * pPars = &Pars; - Gia_ManAbsSetDefaultParams( pPars ); - pPars->nConfMaxBmc = 25000; - pPars->nRatio = 2; - pPars->fVerbose = fVeryVerbose; -/* - int nFramesMax = 10; - int nConfMax = 10000; - int fDynamic = 1; - int fExtend = 0; - int fSkipProof = 0; - int nFramesBmc = 2000; - int nConfMaxBmc = 25000; // default 5000; - int nRatio = 2; // default 10; - int fUseBdds = 0; - int fUseDprove = 0; - int fVerbose = fVeryVerbose; - fExtend ^= 1; - fSkipProof ^= 1; -*/ - pMan = Saig_ManCexAbstraction( pTemp = pMan, pPars ); - // if abstractin has solved the problem - if ( pTemp->pSeqModel ) - { - pNtk->pSeqModel = pTemp->pSeqModel; pTemp->pSeqModel = NULL; - Aig_ManStop( pTemp ); - goto finish; - } - Aig_ManStop( pTemp ); - if ( pMan == NULL ) // abstraction quits - { - absquit = 1; - pMan = Aig_ManDupSimple( pSave1 ); - goto speculation; - } - } - if ( fVerbose ) - { - printf( "Problem before trimming...\n" ); - Aig_ManPrintStats( pMan ); - } - // trim off useless primary inputs - pMan = Aig_ManDupTrim( pTemp = pMan ); - Aig_ManStop( pTemp ); - if ( fVerbose ) - { - printf( "\"dprove\" after abstraction...\n" ); - Aig_ManPrintStats( pMan ); - } - // dprove -r -F 8 - { - Fra_Sec_t SecPar, * pSecPar = &SecPar; - Fra_SecSetDefaultParams( pSecPar ); - pSecPar->fTryBmc ^= 1; - pSecPar->fRetimeFirst ^= 1; - pSecPar->nFramesMax = 8; - pSecPar->fInterSeparate = 0; //fSeparate; - pSecPar->fVerbose = fVeryVerbose; - // convert pMan into pNtk - pNtk2 = Abc_NtkFromAigPhase( pMan ); - RetValue = Abc_NtkDarProve( pNtk2, pSecPar ); - Abc_NtkDelete( pNtk2 ); - // analize the result - if ( RetValue == 1 ) - goto finish; - if ( RetValue == 0 ) - { - // transfer the counter-example!!! - goto finish; - } - assert( RetValue == -1 ); - Aig_ManStop( pMan ); - pMan = (Aig_Man_t *)Abc_FrameReadSave1(); // save2 - } - -speculation: - if ( spectried ) - goto finalbmc; - spectried = 1; - - if ( fVerbose ) - { - printf( "Speculation...\n" ); - Aig_ManPrintStats( pMan ); - } - // convert AIG into GIA -// pGia = Gia_ManFromAigSimple( pMan ); // DID NOT WORK! - pGia = Gia_ManFromAig( pMan ); - Aig_ManStop( pMan ); - // &get, eclass, - { - Cec_ParSim_t Pars, * pPars = &Pars; - Cec_ManSimSetDefaultParams( pPars ); - pPars->fSeqSimulate ^= 1; - pPars->nWords = 255; - pPars->nFrames = 1000; - Cec_ManSimulation( pGia, pPars ); - } - // (spech)* where spech = &srm; restore save3; bmc2 -F 100 -C 25000; &resim - while ( 1 ) - { - // perform speculative reduction - pSrm = Gia_ManSpecReduce( pGia, 0, 0, fVeryVerbose ); // save3 -// Gia_ManPrintStats( pGia, 0 ); -// Gia_ManPrintStats( pSrm, 0 ); - // bmc2 -F 100 -C 25000 - { - Abc_Cex_t * pCex; - int nFrames = 100; // different from default - int nNodeDelta = 2000; - int nBTLimit = 25000; // different from default - int nBTLimitAll = 2000000; - pTemp = Gia_ManToAig( pSrm, 0 ); -// Aig_ManPrintStats( pTemp ); - Gia_ManStop( pSrm ); - Saig_BmcPerform( pTemp, 0, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVeryVerbose, 0, NULL ); - pCex = pTemp->pSeqModel; pTemp->pSeqModel = NULL; - Aig_ManStop( pTemp ); - if ( pCex == NULL ) - break; - // perform simulation - { - Cec_ParSim_t Pars, * pPars = &Pars; - Cec_ManSimSetDefaultParams( pPars ); - Cec_ManSeqResimulateCounter( pGia, pPars, pCex ); - ABC_FREE( pCex ); - } - } - } - Gia_ManStop( pGia ); - // speculatively reduced model is available in pTemp - // trim off useless primary inputs - if ( fVerbose ) - { - printf( "Problem before trimming...\n" ); - Aig_ManPrintStats( pTemp ); - } - pMan = Aig_ManDupTrim( pTemp ); - Aig_ManStop( pTemp ); - if ( fVerbose ) - { - printf( "After speculation...\n" ); - Aig_ManPrintStats( pMan ); - } -/* - // solve the speculatively reduced model - // dprove -r -F 8 - { - Fra_Sec_t SecPar, * pSecPar = &SecPar; - Fra_SecSetDefaultParams( pSecPar ); - pSecPar->fTryBmc ^= 1; - pSecPar->fRetimeFirst ^= 1; - pSecPar->nFramesMax = 8; - pSecPar->fVerbose = fVeryVerbose; - pSecPar->fInterSeparate = 0; //fSeparate; - // convert pMan into pNtk - pNtk2 = Abc_NtkFromAigPhase( pMan ); - RetValue = Abc_NtkDarProve( pNtk2, pSecPar ); - Abc_NtkDelete( pNtk2 ); - // analize the result - if ( RetValue == 1 ) - goto finish; - if ( RetValue == 0 ) - goto finalbmc; - // could not solve - Aig_ManStop( pMan ); - pMan = Abc_FrameReadSave1(); // save4 - if ( absquit || absfail ) - goto abstraction; - } -*/ - // scorr; dc2; orpos; int -r -C 25000 - { - Ssw_Pars_t Pars, * pPars = &Pars; - Ssw_ManSetDefaultParams( pPars ); - pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars ); - Aig_ManStop( pTemp ); - if ( fVerbose ) - { - printf( "After \"scorr\"...\n" ); - Aig_ManPrintStats( pMan ); - } - pMan = Dar_ManCompress2( pTemp = pMan, 1, 0, 1, 0, 0 ); - Aig_ManStop( pTemp ); - if ( fVerbose ) - { - printf( "After \"dc2\"...\n" ); - Aig_ManPrintStats( pMan ); - } - } - { - Inter_ManParams_t Pars, * pPars = &Pars; - Inter_ManSetDefaultParams( pPars ); - pPars->fUseSeparate = fSeparate; - pPars->fRewrite = 1; - pPars->nBTLimit = 25000; - if ( Saig_ManPoNum(pMan) > 1 && !fSeparate ) - { - Aig_Man_t * pAux = Aig_ManDupSimple(pMan); - pTemp = Aig_ManDupOrpos( pAux, 1 ); - RetValue = Abc_NtkDarBmcInter_int( pTemp, pPars ); - Aig_ManStop( pTemp ); - Aig_ManStop( pAux ); - } - else - RetValue = Abc_NtkDarBmcInter_int( pMan, pPars ); - // analize the result - if ( RetValue == 1 ) - goto finish; - if ( RetValue == 0 ) - goto finalbmc; - // could not solve -// Aig_ManStop( pMan ); -// pMan = Abc_FrameReadSave1(); // save4 - if ( absquit || absfail ) - goto abstraction; - } - -finalbmc: - Aig_ManStop( pMan ); - pMan = pSave1; pSave1 = NULL; - if ( fVerbose ) - { - printf( "Final BMC...\n" ); - Aig_ManPrintStats( pMan ); - } - // bmc2 unlimited - { - int nFrames = 2000; - int nNodeDelta = 2000; - int nBTLimit = nConfLast; // different from default - int nBTLimitAll = 2000000; - Saig_BmcPerform( pMan, 0, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVeryVerbose, 0, NULL ); - ABC_FREE( pNtk->pModel ); - ABC_FREE( pNtk->pSeqModel ); - pNtk->pSeqModel = pMan->pSeqModel; pMan->pSeqModel = NULL; - if ( pNtk->pSeqModel ) - goto finish; - } - -finish: - if ( RetValue == 1 ) - printf( "Networks are equivalent. " ); - if ( RetValue == 0 ) - printf( "Networks are not equivalent. " ); - if ( RetValue == -1 ) - printf( "Networks are UNDECIDED. " ); - ABC_PRT( "Time", clock() - clkTotal ); - if ( pNtk->pSeqModel ) - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", pNtk->pSeqModel->iPo, pNtk->pSeqModel->iFrame ); - // verify counter-example - if ( pNtk->pSeqModel ) - { - int status = Ssw_SmlRunCounterExample( pMan, pNtk->pSeqModel ); - if ( status == 0 ) - printf( "Abc_NtkDarBmc(): Counter-example verification has FAILED.\n" ); - } - if ( pSave1 ) - Aig_ManStop( pSave1 ); - Aig_ManStop( pMan ); - return RetValue; -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 0bfb4ec0..558d9349 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "dsd.h" ABC_NAMESPACE_IMPL_START @@ -61,7 +62,7 @@ Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int fS DdManager * dd; Abc_Ntk_t * pNtkNew; assert( Abc_NtkIsStrash(pNtk) ); - dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); if ( dd == NULL ) return NULL; if ( fVerbose ) @@ -110,7 +111,7 @@ Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int Vec_PtrPush( vFuncsGlob, Cudd_NotCond(Abc_ObjGlobalBdd(pObj), Abc_ObjFaninC0(pObj)) ); // perform the decomposition - dd = Abc_NtkGlobalBddMan(pNtk); + dd = (DdManager *)Abc_NtkGlobalBddMan(pNtk); pManDsd = Dsd_ManagerStart( dd, Abc_NtkCiNum(pNtk), fVerbose ); Dsd_Decompose( pManDsd, (DdNode **)vFuncsGlob->pArray, Abc_NtkCoNum(pNtk) ); Vec_PtrFree( vFuncsGlob ); diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c index bd030609..dbbcb1b1 100644 --- a/src/base/abci/abcFxu.c +++ b/src/base/abci/abcFxu.c @@ -144,7 +144,7 @@ void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p ) Abc_Obj_t * pNode; int i; // add information to the manager - p->pManSop = (Extra_MmFlex_t *)pNtk->pManFunc; + p->pManSop = (Mem_Flex_t *)pNtk->pManFunc; p->vSops = Vec_PtrAlloc(0); p->vFanins = Vec_PtrAlloc(0); p->vSopsNew = Vec_PtrAlloc(0); diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c index dc376826..a886949f 100644 --- a/src/base/abci/abcGen.c +++ b/src/base/abci/abcGen.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c index 82e968bd..ce1366de 100644 --- a/src/base/abci/abcIf.c +++ b/src/base/abci/abcIf.c @@ -417,13 +417,13 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) ) { assert( RetValue == 0 ); - pNodeNew->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), NULL ); + pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), NULL ); pNodeNew = (Vec_IntSize(vCover) == 0) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew); } else { // derive the AIG for that tree - pNodeNew->pData = Abc_SopCreateFromIsop( (Extra_MmFlex_t *)pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), vCover ); + pNodeNew->pData = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), vCover ); if ( RetValue ) Abc_SopComplement( (char *)pNodeNew->pData ); } diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 979b2a4a..092350ca 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -496,7 +496,6 @@ Abc_Ntk_t * Abc_NtkIvyFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fDoSparse, in ***********************************************************************/ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) { - Prove_Params_t * pParams = (Prove_Params_t *)pPars; Abc_Ntk_t * pNtk = *ppNtk, * pNtkTemp; Abc_Obj_t * pObj, * pFanin; @@ -563,6 +562,8 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) // solve the CEC problem RetValue = Ivy_FraigProve( &pMan, pParams ); +// RetValue = -1; + // convert IVY network into ABC network pNtk = Abc_NtkIvyAfter( pNtkTemp = pNtk, pMan, 0, 0 ); Abc_NtkDelete( pNtkTemp ); @@ -570,7 +571,24 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) pNtk->pModel = (int *)pMan->pData; pMan->pData = NULL; Ivy_ManStop( pMan ); - // try to prove it using brute force SAT + // try to prove it using brute force SAT with good CNF encoding + if ( RetValue < 0 ) + { + pMan2 = Abc_NtkToDar( pNtk, 0, 0 ); + // dump the miter before entering high-effort solving + if ( pParams->fVerbose ) + { + char pFileName[100]; + sprintf( pFileName, "cecmiter.aig" ); + Ioa_WriteAiger( pMan2, pFileName, 0, 0 ); + printf( "Intermediate reduced miter is written into file \"%s\".\n", pFileName ); + } + RetValue = Fra_FraigSat( pMan2, pParams->nMiteringLimitLast, 0, 0, 0, pParams->fVerbose ); + pNtk->pModel = (int *)pMan2->pData, pMan2->pData = NULL; + Aig_ManStop( pMan2 ); + } + + // try to prove it using brute force BDDs if ( RetValue < 0 && pParams->fUseBdds ) { if ( pParams->fVerbose ) diff --git a/src/base/abci/abcLog.c b/src/base/abci/abcLog.c index 615584a1..ecccb36b 100644 --- a/src/base/abci/abcLog.c +++ b/src/base/abci/abcLog.c @@ -29,26 +29,27 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /* - Log file format (Jiang, Mon, 28 Sep 2009) + Log file format (Jiang, Mon, 28 Sep 2009; updated by Alan in Jan 2011) - <result> <cyc> <engine_name> - <TRACE> : default is "NULL" - <INIT_STATE> : default is "NULL" - - <retult> is the following: - snl_SAT - snl_UNSAT - snl_UNK - snl_ABORT - - <cyc> : # of cycles + <result> <bug_free_depth> <engine_name> <0-based_output_num> <0-based_frame> + <INIT_STATE> : default is empty line. + <TRACE> : default is empty line + <result> is one of the following: "snl_SAT", "snl_UNSAT", "snl_UNK", "snl_ABORT". + <bug_free_depth> is the number of timeframes exhaustively explored without counter-examples + <0-based_output_num> only need to be given if the problem is SAT. + <0-based_frame> only need to be given if the problem is SAT and <0-based_frame> is different from <bug_free_depth>. <INIT_STATE> : initial state <TRACE> : input vector - + <INIT_STATE>and <TRACE> are strings of 0/1/- ( - means don't care). The length is equivalent to #input*#<cyc>. */ + + + + + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -84,13 +85,16 @@ void Abc_NtkWriteLogFile( char * pFileName, Abc_Cex_t * pCex, int Status, int nF else printf( "Abc_NtkWriteLogFile(): Cannot recognize solving status.\n" ); fprintf( pFile, " " ); - // write <cyc> - fprintf( pFile, "%d", pCex ? pCex->iFrame + 1 : nFrames ); + // write <bug_free_depth> + fprintf( pFile, "%d", nFrames ); fprintf( pFile, " " ); // write <engine_name> fprintf( pFile, "%s", pCommand ? pCommand : "unknown" ); if ( Status == 0 ) fprintf( pFile, " %d", pCex->iPo ); + // write <cyc> + if ( pCex && pCex->iFrame != nFrames ) + fprintf( pFile, " %d", pCex->iFrame ); fprintf( pFile, "\n" ); // write <INIT_STATE> if ( pCex == NULL ) @@ -131,7 +135,7 @@ int Abc_NtkReadLogFile( char * pFileName, Abc_Cex_t ** ppCex, int * pnFrames ) Abc_Cex_t * pCex; Vec_Int_t * vNums; char Buffer[1000], * pToken; - int c, nRegs = -1, nFrames = -1, iPo = -1, Status = -1; + int c, nRegs = -1, nFrames = -1, iPo = -1, Status = -1, nFrames2 = -1; pFile = fopen( pFileName, "r" ); if ( pFile == NULL ) { @@ -153,6 +157,9 @@ int Abc_NtkReadLogFile( char * pFileName, Abc_Cex_t ** ppCex, int * pnFrames ) pToken = strtok( NULL, " \t\n" ); pToken = strtok( NULL, " \t\n" ); iPo = atoi( pToken ); + pToken = strtok( NULL, " \t\n" ); + if ( pToken ) + nFrames2 = atoi( pToken ); } else if ( !strncmp( Buffer, "snl_UNK", strlen("snl_UNK") ) ) { @@ -182,7 +189,8 @@ int Abc_NtkReadLogFile( char * pFileName, Abc_Cex_t ** ppCex, int * pnFrames ) fclose( pFile ); if ( Vec_IntSize(vNums) ) { - if ( nRegs == 0 ) + int iFrameCex = (nFrames2 == -1) ? nFrames : nFrames2; + if ( nRegs < 0 ) { printf( "Cannot read register number.\n" ); return -1; @@ -192,14 +200,14 @@ int Abc_NtkReadLogFile( char * pFileName, Abc_Cex_t ** ppCex, int * pnFrames ) printf( "Cannot read counter example.\n" ); return -1; } - if ( (Vec_IntSize(vNums)-nRegs) % nFrames != 0 ) + if ( (Vec_IntSize(vNums)-nRegs) % (iFrameCex + 1) != 0 ) { printf( "Incorrect number of bits.\n" ); return -1; } - pCex = Gia_ManAllocCounterExample( nRegs, (Vec_IntSize(vNums)-nRegs)/nFrames, nFrames ); + pCex = Abc_CexAlloc( nRegs, (Vec_IntSize(vNums)-nRegs)/(iFrameCex + 1), iFrameCex + 1 ); pCex->iPo = iPo; - pCex->iFrame = nFrames - 1; + pCex->iFrame = iFrameCex; assert( Vec_IntSize(vNums) == pCex->nBits ); for ( c = 0; c < pCex->nBits; c++ ) if ( Vec_IntEntry(vNums, c) ) diff --git a/src/base/abci/abcLut.c b/src/base/abci/abcLut.c index a33cc7db..98991e25 100644 --- a/src/base/abci/abcLut.c +++ b/src/base/abci/abcLut.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "cut.h" ABC_NAMESPACE_IMPL_START @@ -582,7 +583,7 @@ Abc_Obj_t * Abc_NodeSuperChoiceLut( Abc_ManScl_t * p, Abc_Obj_t * pObj ) Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pFanin, i ) Abc_ObjAddFanin( pObjNew, pFanin ); // create the function - pObjNew->pData = Abc_SopCreateFromTruth( (Extra_MmFlex_t *)pObj->pNtk->pManFunc, Vec_PtrSize(p->vLeaves), p->uTruth ); // need ISOP + pObjNew->pData = Abc_SopCreateFromTruth( (Mem_Flex_t *)pObj->pNtk->pManFunc, Vec_PtrSize(p->vLeaves), p->uTruth ); // need ISOP pObjNew->Level = Abc_NodeGetLevel( pObjNew ); return pObjNew; } @@ -763,7 +764,7 @@ int Abc_NodeDecomposeStep( Abc_ManScl_t * p ) Abc_ObjAddFanin( pObjNew, pFanin ); } // create the function - pObjNew->pData = Abc_SopCreateFromTruth( (Extra_MmFlex_t *)pNtk->pManFunc, p->nLutSize, pTruth ); // need ISOP + pObjNew->pData = Abc_SopCreateFromTruth( (Mem_Flex_t *)pNtk->pManFunc, p->nLutSize, pTruth ); // need ISOP pObjNew->Level = Abc_NodeGetLevel( pObjNew ); pNodesNew[v] = pObjNew; } diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c index 71dea2e1..6d62f330 100644 --- a/src/base/abci/abcLutmin.c +++ b/src/base/abci/abcLutmin.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -39,6 +40,76 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Check if a LUT can absort a fanin.] + + Description [The fanins are (c, d0, d1).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjCheckAbsorb( Abc_Obj_t * pObj, Abc_Obj_t * pPivot, int nLutSize, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pFanin; + int i; + assert( Abc_ObjIsNode(pObj) && Abc_ObjIsNode(pPivot) ); + // add fanins of the node + Vec_PtrClear( vFanins ); + Abc_ObjForEachFanin( pObj, pFanin, i ) + if ( pFanin != pPivot ) + Vec_PtrPush( vFanins, pFanin ); + // add fanins of the fanin + Abc_ObjForEachFanin( pPivot, pFanin, i ) + { + Vec_PtrPushUnique( vFanins, pFanin ); + if ( Vec_PtrSize(vFanins) > nLutSize ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Check how many times a LUT can absorb a fanin.] + + Description [The fanins are (c, d0, d1).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCheckAbsorb( Abc_Ntk_t * pNtk, int nLutSize ) +{ + Vec_Int_t * vCounts; + Vec_Ptr_t * vFanins; + Abc_Obj_t * pObj, * pFanin; + int i, k, Counter = 0, Counter2 = 0, clk = clock(); + vCounts = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + vFanins = Vec_PtrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + if ( Abc_ObjIsNode(pFanin) && Abc_ObjCheckAbsorb( pObj, pFanin, nLutSize, vFanins ) ) + { + Vec_IntAddToEntry( vCounts, Abc_ObjId(pFanin), 1 ); + Counter++; + } + Vec_PtrFree( vFanins ); + Abc_NtkForEachNode( pNtk, pObj, i ) + if ( Vec_IntEntry(vCounts, Abc_ObjId(pObj)) == Abc_ObjFanoutNum(pObj) ) + { +// printf( "%d ", Abc_ObjId(pObj) ); + Counter2++; + } + printf( "Absorted = %6d. (%6.2f %%) Fully = %6d. (%6.2f %%) ", + Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk), + Counter2, 100.0 * Counter2 / Abc_NtkNodeNum(pNtk) ); + Abc_PrintTime( 1, "Time", clock() - clk ); +} + +/**Function************************************************************* + Synopsis [Implements 2:1 MUX using one 3-LUT.] Description [The fanins are (c, d0, d1).] diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index 543df7b0..33707b15 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -657,7 +657,7 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis ); Abc_ObjAddFanin( pNodeNew, pNodeFanin ); } - pNodeNew->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtkNew->pManFunc, Mio_GateReadSop(pRoot) ); + pNodeNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, Mio_GateReadSop(pRoot) ); return pNodeNew; } diff --git a/src/base/abci/abcMffc.c b/src/base/abci/abcMffc.c new file mode 100644 index 00000000..0ffc6f1d --- /dev/null +++ b/src/base/abci/abcMffc.c @@ -0,0 +1,1264 @@ +/**CFile**************************************************************** + + FileName [abcMffc.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computing multi-output maximum fanout-free cones.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcMffc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Dereferences and collects the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MffcDeref_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) +{ + Abc_Obj_t * pFanin; + int i; + if ( Abc_ObjIsCi(pNode) ) + return; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( pFanin->vFanouts.nSize > 0 ); + if ( --pFanin->vFanouts.nSize == 0 ) + Abc_MffcDeref_rec( pFanin, vNodes ); + } + if ( vNodes ) + Vec_PtrPush( vNodes, pNode ); +} + +/**Function************************************************************* + + Synopsis [References the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MffcRef_rec( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pFanin; + int i; + if ( Abc_ObjIsCi(pNode) ) + return; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + if ( pFanin->vFanouts.nSize++ == 0 ) + Abc_MffcRef_rec( pFanin ); + } +} + +/**Function************************************************************* + + Synopsis [Collects nodes belonging to the MFFC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MffcCollectNodes( Abc_Obj_t ** pNodes, int nNodes, Vec_Ptr_t * vNodes ) +{ + int i; + Vec_PtrClear( vNodes ); + for ( i = 0; i < nNodes; i++ ) + Abc_MffcDeref_rec( pNodes[i], vNodes ); + for ( i = 0; i < nNodes; i++ ) + Abc_MffcRef_rec( pNodes[i] ); +} + +/**Function************************************************************* + + Synopsis [Collects leaves of the MFFC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MffcCollectLeaves( Vec_Ptr_t * vNodes, Vec_Ptr_t * vLeaves ) +{ + Abc_Obj_t * pNode, * pFanin; + int i, k; + assert( Vec_PtrSize(vNodes) > 0 ); + pNode = (Abc_Obj_t *)Vec_PtrEntry( vNodes, 0 ); + // label them + Abc_NtkIncrementTravId( pNode->pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Abc_NodeSetTravIdCurrent( pNode ); + // collect non-labeled fanins + Vec_PtrClear( vLeaves ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Abc_ObjForEachFanin( pNode, pFanin, k ) + { + if ( Abc_NodeIsTravIdCurrent(pFanin) ) + continue; + Abc_NodeSetTravIdCurrent( pFanin ); + Vec_PtrPush( vLeaves, pFanin ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vec_IntPrint( Vec_Int_t * vVec ) +{ + int i, Entry; + Vec_IntForEachEntry( vVec, Entry, i ) + printf( "%d ", Entry ); + printf( "\n" ); +} + + +/**Function************************************************************* + + Synopsis [Collects internal nodes that are roots of MFFCs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NktMffcMarkRoots( Abc_Ntk_t * pNtk, int fSkipPis ) +{ + Vec_Ptr_t * vRoots, * vNodes, * vLeaves; + Abc_Obj_t * pObj, * pLeaf; + int i, k; + Abc_NtkCleanMarkA( pNtk ); + // mark the drivers of combinational outputs + vRoots = Vec_PtrAlloc( 1000 ); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pObj = Abc_ObjFanin0( pObj ); +// if ( Abc_ObjIsCi(pObj) || Abc_ObjFaninNum(pObj) == 0 || pObj->fMarkA ) + if ( Abc_ObjIsCi(pObj) || pObj->fMarkA ) + continue; + pObj->fMarkA = 1; + Vec_PtrPush( vRoots, pObj ); + } + // explore starting from the drivers + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + if ( Abc_ObjIsCi(pObj) ) + continue; + // collect internal nodes + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + // collect leaves + Abc_MffcCollectLeaves( vNodes, vLeaves ); + // add non-PI leaves + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pLeaf, k ) + { + if ( (fSkipPis && Abc_ObjIsCi(pLeaf)) || pLeaf->fMarkA ) + continue; + pLeaf->fMarkA = 1; + Vec_PtrPush( vRoots, pLeaf ); + } + } + Vec_PtrFree( vLeaves ); + Vec_PtrFree( vNodes ); + Abc_NtkCleanMarkA( pNtk ); + return vRoots; +} + +/**Function************************************************************* + + Synopsis [Collect fanout reachable root nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcCollectFanout_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vFanouts ) +{ + Abc_Obj_t * pFanout; + int i; + if ( Abc_ObjIsCo(pObj) ) + return; + if ( Abc_ObjFanoutNum(pObj) > 64 ) + return; + if ( Abc_NodeIsTravIdCurrent(pObj) ) + return; + Abc_NodeSetTravIdCurrent(pObj); + if ( pObj->fMarkA ) + { + if ( pObj->vFanouts.nSize > 0 ) + Vec_PtrPush( vFanouts, pObj ); + return; + } + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_NktMffcCollectFanout_rec( pFanout, vFanouts ); +} + +/**Function************************************************************* + + Synopsis [Collect fanout reachable root nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcCollectFanout( Abc_Obj_t ** pNodes, int nNodes, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vFanouts ) +{ + Abc_Obj_t * pFanin, * pFanout; + int i, k; + // dereference nodes + for ( i = 0; i < nNodes; i++ ) + Abc_MffcDeref_rec( pNodes[i], NULL ); + // collect fanouts + Vec_PtrClear( vFanouts ); + pFanin = (Abc_Obj_t *)Vec_PtrEntry( vLeaves, 0 ); + Abc_NtkIncrementTravId( pFanin->pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pFanin, i ) + Abc_ObjForEachFanout( pFanin, pFanout, k ) + Abc_NktMffcCollectFanout_rec( pFanout, vFanouts ); + // reference nodes + for ( i = 0; i < nNodes; i++ ) + Abc_MffcRef_rec( pNodes[i] ); +} + +/**Function************************************************************* + + Synopsis [Grow one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NktMffcGrowOne( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppObjs, int nObjs, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vFanouts ) +{ + Abc_Obj_t * pFanout, * pFanoutBest = NULL; + double CostBest = 0.0; + int i, k; + Abc_MffcCollectNodes( ppObjs, nObjs, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + // collect fanouts of all fanins + Abc_NktMffcCollectFanout( ppObjs, nObjs, vLeaves, vFanouts ); + // try different fanouts + Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i ) + { + for ( k = 0; k < nObjs; k++ ) + if ( pFanout == ppObjs[k] ) + break; + if ( k < nObjs ) + continue; + ppObjs[nObjs] = pFanout; + Abc_MffcCollectNodes( ppObjs, nObjs+1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + if ( pFanoutBest == NULL || CostBest < 1.0 * Vec_PtrSize(vNodes)/Vec_PtrSize(vLeaves) ) + { + CostBest = 1.0 * Vec_PtrSize(vNodes)/Vec_PtrSize(vLeaves); + pFanoutBest = pFanout; + } + } + return pFanoutBest; +} + +/**Function************************************************************* + + Synopsis [Procedure to increase MFF size by pairing nodes.] + + Description [For each node in the array vRoots, find a matching node, + so that the ratio of nodes inside to the leaf nodes is maximized.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NktMffcGrowRoots( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vRoots1, * vNodes, * vLeaves, * vFanouts; + Abc_Obj_t * pObj, * pRoot2, * pNodes[2]; + int i; + Abc_NtkCleanMarkA( pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + pObj->fMarkA = 1; + vRoots1 = Vec_PtrAlloc( 100 ); + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + vFanouts = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + pNodes[0] = pObj; + pRoot2 = Abc_NktMffcGrowOne( pNtk, pNodes, 1, vNodes, vLeaves, vFanouts ); + Vec_PtrPush( vRoots1, pRoot2 ); + } + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + Vec_PtrFree( vFanouts ); + Abc_NtkCleanMarkA( pNtk ); + return vRoots1; +} + +/**Function************************************************************* + + Synopsis [Procedure to increase MFF size by pairing nodes.] + + Description [For each node in the array vRoots, find a matching node, + so that the ratio of nodes inside to the leaf nodes is maximized.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NktMffcGrowRootsAgain( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Ptr_t * vRoots1 ) +{ + Vec_Ptr_t * vRoots2, * vNodes, * vLeaves, * vFanouts; + Abc_Obj_t * pObj, * pRoot2, * ppObjs[3]; + int i; + Abc_NtkCleanMarkA( pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + pObj->fMarkA = 1; + vRoots2 = Vec_PtrAlloc( 100 ); + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + vFanouts = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + ppObjs[0] = pObj; + ppObjs[1] = (Abc_Obj_t *)Vec_PtrEntry( vRoots1, i ); + if ( ppObjs[1] == NULL ) + { + Vec_PtrPush( vRoots2, NULL ); + continue; + } + pRoot2 = Abc_NktMffcGrowOne( pNtk, ppObjs, 2, vNodes, vLeaves, vFanouts ); + Vec_PtrPush( vRoots2, pRoot2 ); + } + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + Vec_PtrFree( vFanouts ); + Abc_NtkCleanMarkA( pNtk ); + assert( Vec_PtrSize(vRoots) == Vec_PtrSize(vRoots2) ); + return vRoots2; +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcPrint( char * pFileName, Abc_Obj_t ** pNodes, int nNodes, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLeaves ) +{ + FILE * pFile; + Abc_Obj_t * pObj, * pFanin; + int i, k; + // convert the network + Abc_NtkToSop( pNodes[0]->pNtk, 0 ); + // write the file + pFile = fopen( pFileName, "wb" ); + fprintf( pFile, ".model %s_part\n", pNodes[0]->pNtk->pName ); + fprintf( pFile, ".inputs" ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs" ); + for ( i = 0; i < nNodes; i++ ) + fprintf( pFile, " %s", Abc_ObjName(pNodes[i]) ); + fprintf( pFile, "\n" ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + fprintf( pFile, ".names" ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + fprintf( pFile, " %s", Abc_ObjName(pFanin) ); + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n%s", (char *)pObj->pData ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcPrintInt( char * pFileName, Abc_Ntk_t * pNtk, Vec_Int_t * vRoots, Vec_Int_t * vNodes, Vec_Int_t * vLeaves ) +{ + FILE * pFile; + Abc_Obj_t * pObj, * pFanin; + int i, k; + // convert the network + Abc_NtkToSop( pNtk, 0 ); + // write the file + pFile = fopen( pFileName, "wb" ); + fprintf( pFile, ".model %s_part\n", pNtk->pName ); + fprintf( pFile, ".inputs" ); + Abc_NtkForEachObjVec( pNtk, vLeaves, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs" ); + Abc_NtkForEachObjVec( pNtk, vRoots, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); + Abc_NtkForEachObjVec( pNtk, vNodes, pObj, i ) + { + fprintf( pFile, ".names" ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + fprintf( pFile, " %s", Abc_ObjName(pFanin) ); + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n%s", (char *)pObj->pData ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcTest( Abc_Ntk_t * pNtk ) +{ + char pFileName[1000]; + Vec_Ptr_t * vRoots, * vRoots1, * vRoots2, * vNodes, * vLeaves; + Abc_Obj_t * pNodes[3], * pObj; + int i, nNodes = 0, nNodes2 = 0; + vRoots = Abc_NktMffcMarkRoots( pNtk, 1 ); + vRoots1 = Abc_NktMffcGrowRoots( pNtk, vRoots ); + vRoots2 = Abc_NktMffcGrowRootsAgain( pNtk, vRoots, vRoots1 ); + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + printf( "%6d : ", i ); + + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + nNodes += Vec_PtrSize(vNodes); + printf( "%6d ", Abc_ObjId(pObj) ); + printf( "Vol =%3d ", Vec_PtrSize(vNodes) ); + printf( "Cut =%3d ", Vec_PtrSize(vLeaves) ); + if ( Vec_PtrSize(vLeaves) < 2 ) + { + printf( "\n" ); + continue; + } + + pNodes[0] = pObj; + pNodes[1] = (Abc_Obj_t *)Vec_PtrEntry( vRoots1, i ); + pNodes[2] = (Abc_Obj_t *)Vec_PtrEntry( vRoots2, i ); + if ( pNodes[1] == NULL || pNodes[2] == NULL ) + { + printf( "\n" ); + continue; + } + Abc_MffcCollectNodes( pNodes, 3, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + nNodes2 += Vec_PtrSize(vNodes); + printf( "%6d ", Abc_ObjId(pNodes[1]) ); + printf( "%6d ", Abc_ObjId(pNodes[2]) ); + printf( "Vol =%3d ", Vec_PtrSize(vNodes) ); + printf( "Cut =%3d ", Vec_PtrSize(vLeaves) ); + + printf( "%4.2f ", 1.0 * Vec_PtrSize(vNodes)/Vec_PtrSize(vLeaves) ); + printf( "\n" ); + + // generate file + if ( Vec_PtrSize(vNodes) < 10 ) + continue; + sprintf( pFileName, "%s_mffc%04d_%02d.blif", Abc_NtkName(pNtk), Abc_ObjId(pObj), Vec_PtrSize(vNodes) ); + Abc_NktMffcPrint( pFileName, pNodes, 3, vNodes, vLeaves ); + } + printf( "Total nodes = %d. Root nodes = %d. Mffc nodes = %d. Mffc nodes2 = %d.\n", + Abc_NtkNodeNum(pNtk), Vec_PtrSize(vRoots), nNodes, nNodes2 ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + Vec_PtrFree( vRoots ); + Vec_PtrFree( vRoots1 ); + Vec_PtrFree( vRoots2 ); +} + + + +/**Function************************************************************* + + Synopsis [Create the network of supernodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcTestSuper( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vRoots, * vFanins, * vFanouts, * vNodes, * vLeaves; + Abc_Obj_t * pObj, * pFanin; + Vec_Int_t * vCounts, * vNumbers, * vSizes, * vMarks; + Vec_Int_t * vNode1, * vNode2; + int i, k, Entry, nSizes, clk = clock(); + vRoots = Abc_NktMffcMarkRoots( pNtk, 1 ); + vFanins = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + vFanouts = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + vCounts = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + vNode1 = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + vNode2 = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + vSizes = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + vMarks = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + + // create fanins/fanouts + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Vec_PtrWriteEntry( vFanins, Abc_ObjId(pObj), Vec_IntAlloc(8) ); + Vec_PtrWriteEntry( vFanouts, Abc_ObjId(pObj), Vec_IntAlloc(8) ); + } + // add fanins/fanouts + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pFanin, k ) + { + if ( !Abc_ObjIsNode(pFanin) ) + continue; + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vFanins, Abc_ObjId(pObj)), Abc_ObjId(pFanin) ); + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vFanouts, Abc_ObjId(pFanin)), Abc_ObjId(pObj) ); + // count how many times each object is a fanin + Vec_IntAddToEntry( vCounts, Abc_ObjId(pFanin), 1 ); + } + Vec_IntWriteEntry( vSizes, Abc_ObjId(pObj), Vec_PtrSize(vNodes) ); + } + + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pFanin, k ) + { + if ( !Abc_ObjIsNode(pFanin) ) + continue; + if ( Vec_IntEntry(vCounts, Abc_ObjId(pFanin)) != 2 ) + continue; + if ( Vec_IntEntry(vNode1, Abc_ObjId(pFanin)) == 0 ) + Vec_IntWriteEntry( vNode1, Abc_ObjId(pFanin), Abc_ObjId(pObj) ); + else //if ( Vec_IntEntry(vNode2, Abc_ObjId(pFanin)) == 0 ) + Vec_IntWriteEntry( vNode2, Abc_ObjId(pFanin), Abc_ObjId(pObj) ); + + Vec_IntWriteEntry( vMarks, Abc_ObjId(pFanin), 1 ); + Vec_IntWriteEntry( vMarks, Abc_ObjId(pObj), 1 ); + } + } + + // count sizes + nSizes = 0; + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + if ( Vec_IntEntry( vMarks, Abc_ObjId(pObj) ) ) + nSizes += Vec_IntEntry( vSizes, Abc_ObjId(pObj) ); + } + printf( "Included = %6d. Total = %6d. (%6.2f %%)\n", + nSizes, Abc_NtkNodeNum(pNtk), 100.0 * nSizes / Abc_NtkNodeNum(pNtk) ); + + + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + if ( Vec_IntEntry(vCounts, Abc_ObjId(pObj)) != 2 ) + continue; + printf( "%d ", Vec_IntEntry( vSizes, Abc_ObjId(pObj) ) + + Vec_IntEntry( vSizes, Vec_IntEntry(vNode1, Abc_ObjId(pObj)) ) + + Vec_IntEntry( vSizes, Vec_IntEntry(vNode2, Abc_ObjId(pObj)) ) ); + } + printf( "\n" ); + + // print how many times they appear + vNumbers = Vec_IntStart( 32 ); + Vec_IntForEachEntry( vCounts, Entry, i ) + { +/* +if ( Entry == 2 ) +{ + pObj = Abc_NtkObj( pNtk, i ); + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + printf( "%d(%d) ", Vec_PtrSize(vNodes), Vec_PtrSize(vLeaves) ); +} +*/ + if ( Entry == 0 ) + continue; + if ( Entry <= 10 ) + Vec_IntAddToEntry( vNumbers, Entry, 1 ); + else if ( Entry <= 100 ) + Vec_IntAddToEntry( vNumbers, 10 + Entry/10, 1 ); + else if ( Entry < 1000 ) + Vec_IntAddToEntry( vNumbers, 20 + Entry/100, 1 ); + else + Vec_IntAddToEntry( vNumbers, 30, 1 ); + } + for ( i = 1; i <= 10; i++ ) + if ( Vec_IntEntry(vNumbers,i) ) + printf( " n = %4d %6d\n", i, Vec_IntEntry(vNumbers,i) ); + for ( i = 11; i <= 20; i++ ) + if ( Vec_IntEntry(vNumbers,i) ) + printf( "%4d < n <= %4d %6d\n", 10*(i-10), 10*(i-9), Vec_IntEntry(vNumbers,i) ); + for ( i = 21; i < 30; i++ ) + if ( Vec_IntEntry(vNumbers,i) ) + printf( "%4d < n <= %4d %6d\n", 100*(i-20), 100*(i-19), Vec_IntEntry(vNumbers,i) ); + if ( Vec_IntEntry(vNumbers,31) ) + printf( " n > 1000 %6d\n", Vec_IntEntry(vNumbers,30) ); + printf( "Total MFFCs = %d. ", Vec_PtrSize(vRoots) ); + Abc_PrintTime( 1, "Time", clock() - clk ); + Vec_IntFree( vNumbers ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + + // delete fanins/fanouts + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vFanins, Abc_ObjId(pObj)) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vFanouts, Abc_ObjId(pObj)) ); + } + + Vec_IntFree( vCounts ); + Vec_PtrFree( vFanouts ); + Vec_PtrFree( vFanins ); + Vec_PtrFree( vRoots ); +} + + +/**Function************************************************************* + + Synopsis [Collects the leaves and the roots of the window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffCollectLeafRoot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots ) +{ + Abc_Obj_t * pObj, * pNext; + int i, k; + // mark + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + pObj->fMarkA = 1; + // collect leaves + Vec_PtrClear( vLeaves ); + Abc_NtkIncrementTravId( pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + Abc_ObjForEachFanin( pObj, pNext, k ) + { + if ( pNext->fMarkA || Abc_NodeIsTravIdCurrent(pNext) ) + continue; + Abc_NodeSetTravIdCurrent(pNext); + Vec_PtrPush( vLeaves, pNext ); + } + // collect roots + Vec_PtrClear( vRoots ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + Abc_ObjForEachFanout( pObj, pNext, k ) + if ( !pNext->fMarkA ) + { + Vec_PtrPush( vRoots, pObj ); + break; + } + } + // unmark + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + pObj->fMarkA = 0; +} + +/**Function************************************************************* + + Synopsis [Collects the leaves and the roots of the window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffCollectLeafRootInt( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vRoots ) +{ + Abc_Obj_t * pObj, * pNext; + int i, k; + // mark + Abc_NtkForEachObjVec( pNtk, vNodes, pObj, i ) + pObj->fMarkA = 1; + // collect leaves + Vec_IntClear( vLeaves ); + Abc_NtkIncrementTravId( pNtk ); + Abc_NtkForEachObjVec( pNtk, vNodes, pObj, i ) + Abc_ObjForEachFanin( pObj, pNext, k ) + { + if ( pNext->fMarkA || Abc_NodeIsTravIdCurrent(pNext) ) + continue; + Abc_NodeSetTravIdCurrent(pNext); + Vec_IntPush( vLeaves, Abc_ObjId(pNext) ); + } + // collect roots + if ( vRoots ) + { + Vec_IntClear( vRoots ); + Abc_NtkForEachObjVec( pNtk, vNodes, pObj, i ) + { + Abc_ObjForEachFanout( pObj, pNext, k ) + if ( !pNext->fMarkA ) + { + Vec_IntPush( vRoots, Abc_ObjId(pObj) ); + break; + } + } + } + // unmark + Abc_NtkForEachObjVec( pNtk, vNodes, pObj, i ) + pObj->fMarkA = 0; +} + + +/**Function************************************************************* + + Synopsis [Create the network of supernodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcTestIdeaOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) +{ + Vec_Ptr_t * vNodes, * vLeaves, * vRoots, * vVolume; + Vec_Ptr_t * vLeaves2, * vRoots2, * vVolume2; + Abc_Obj_t * pNode, * pNodeBest = pObj; + double Cost, CostBest = 0.0; + int i, k; + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + vRoots = Vec_PtrAlloc( 100 ); + vVolume = Vec_PtrAlloc( 100 ); + vLeaves2 = Vec_PtrAlloc( 100 ); + vRoots2 = Vec_PtrAlloc( 100 ); + vVolume2 = Vec_PtrAlloc( 100 ); +printf( "\n" ); + for ( i = 1; i <= 16; i++ ) + { + Vec_PtrPush( vNodes, pNodeBest ); + Abc_NktMffCollectLeafRoot( pNtk, vNodes, vLeaves, vRoots ); + Abc_MffcCollectNodes( (Abc_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots), vVolume ); + + printf( "%2d : Node =%6d (%2d%3d) Cost =%6.2f ", i, Abc_ObjId(pNodeBest), + Abc_ObjFaninNum(pNodeBest), Abc_ObjFanoutNum(pNodeBest), CostBest ); + printf( "Leaf =%2d Root =%2d Vol =%2d\n", Vec_PtrSize(vLeaves), Vec_PtrSize(vRoots), Vec_PtrSize(vVolume) ); + + // try including different nodes + pNodeBest = NULL; + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, k ) + { + if ( !Abc_ObjIsNode(pNode) ) + continue; + Vec_PtrPush( vNodes, pNode ); + Abc_NktMffCollectLeafRoot( pNtk, vNodes, vLeaves2, vRoots2 ); + Abc_MffcCollectNodes( (Abc_Obj_t **)Vec_PtrArray(vRoots2), Vec_PtrSize(vRoots2), vVolume2 ); + Cost = 1.0 * Vec_PtrSize(vVolume2) / (Vec_PtrSize(vLeaves2) + 3 * Vec_PtrSize(vRoots2)); + if ( pNodeBest == NULL || CostBest < Cost ) + { + pNodeBest = pNode; + CostBest = Cost; + } + Vec_PtrPop( vNodes ); + } + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pNode, k ) + { + if ( Vec_PtrFind(vNodes, pNode) >= 0 ) + continue; + if ( !Abc_ObjIsNode(pNode) ) + continue; + Vec_PtrPush( vNodes, pNode ); + Abc_NktMffCollectLeafRoot( pNtk, vNodes, vLeaves2, vRoots2 ); + Abc_MffcCollectNodes( (Abc_Obj_t **)Vec_PtrArray(vRoots2), Vec_PtrSize(vRoots2), vVolume2 ); + Cost = 1.0 * Vec_PtrSize(vVolume2) / (Vec_PtrSize(vLeaves2) + 3 * Vec_PtrSize(vRoots2)); + if ( pNodeBest == NULL || CostBest < Cost ) + { + pNodeBest = pNode; + CostBest = Cost; + } + Vec_PtrPop( vNodes ); + } + if ( pNodeBest == NULL ) + break; + } + + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + Vec_PtrFree( vRoots ); + Vec_PtrFree( vVolume ); + Vec_PtrFree( vLeaves2 ); + Vec_PtrFree( vRoots2 ); + Vec_PtrFree( vVolume2 ); +} + +/**Function************************************************************* + + Synopsis [Create the network of supernodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcTestIdea( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachNode( pNtk, pObj, i ) + if ( Abc_ObjIsNode(pObj) && Abc_ObjId(pObj) % 100 == 0 ) + Abc_NktMffcTestIdeaOne( pNtk, pObj ); +} + + + + + +/**Function************************************************************* + + Synopsis [Creates MFFCs and their fanins/fanouts/volumes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NktMffcDerive( Abc_Ntk_t * pNtk, Vec_Ptr_t ** pvFanins, Vec_Ptr_t ** pvFanouts, Vec_Ptr_t ** pvVolumes ) +{ + Vec_Ptr_t * vRoots, * vFanins, * vFanouts, * vVolumes, * vNodes, * vLeaves; + Abc_Obj_t * pObj, * pFanin; + int i, k, clk = clock(); + // create roots + vRoots = Abc_NktMffcMarkRoots( pNtk, 0 ); + // create fanins/fanouts/volumes + vFanins = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + vFanouts = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + vVolumes = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Vec_PtrWriteEntry( vFanins, Abc_ObjId(pObj), Vec_IntAlloc(8) ); + Vec_PtrWriteEntry( vFanouts, Abc_ObjId(pObj), Vec_IntAlloc(8) ); + Vec_PtrWriteEntry( vVolumes, Abc_ObjId(pObj), Vec_IntAlloc(8) ); + } + // add fanins/fanouts + vNodes = Vec_PtrAlloc( 100 ); + vLeaves = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + if ( Abc_ObjIsCi(pObj) ) + continue; + Abc_MffcCollectNodes( &pObj, 1, vNodes ); + Abc_MffcCollectLeaves( vNodes, vLeaves ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pFanin, k ) + { + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vFanins, Abc_ObjId(pObj)), Abc_ObjId(pFanin) ); + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vFanouts, Abc_ObjId(pFanin)), Abc_ObjId(pObj) ); + } + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pFanin, k ) + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pObj)), Abc_ObjId(pFanin) ); + } + + Vec_PtrFree( vNodes ); + Vec_PtrFree( vLeaves ); + // sort + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Vec_IntSort( (Vec_Int_t *)Vec_PtrEntry(vFanins, Abc_ObjId(pObj)), 0 ); + Vec_IntSort( (Vec_Int_t *)Vec_PtrEntry(vFanouts, Abc_ObjId(pObj)), 0 ); + } + // return + *pvFanins = vFanins; + *pvFanouts = vFanouts; + *pvVolumes = vVolumes; + return vRoots; +} + +/**Function************************************************************* + + Synopsis [Frees MFFCs and their fanins/fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcFree( Vec_Ptr_t * vRoots, Vec_Ptr_t * vFanins, Vec_Ptr_t * vFanouts, Vec_Ptr_t * vVolumes ) +{ + Abc_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i ) + { + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vFanins, Abc_ObjId(pObj)) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vFanouts, Abc_ObjId(pObj)) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pObj)) ); + } + Vec_PtrFree( vVolumes ); + Vec_PtrFree( vFanouts ); + Vec_PtrFree( vFanins ); + Vec_PtrFree( vRoots ); +} + + +/**Function************************************************************* + + Synopsis [Returns the cost of two supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Abc_NktMffcCostTwo( Vec_Int_t * vSupp1, Vec_Int_t * vSupp2, int Volume, int Limit ) +{ + int nCommon = Vec_IntTwoCountCommon( vSupp1, vSupp2 ); +//printf( "s1=%2d s2=%2d c=%2d v=%2d ", Vec_IntSize(vSupp1), Vec_IntSize(vSupp2), nCommon, Volume ); + if ( Vec_IntSize(vSupp1) + Vec_IntSize(vSupp2) - nCommon > Limit ) + return (double)-ABC_INFINITY; + return 0.6 * nCommon - 1.2 * Vec_IntSize(vSupp2) + 0.8 * Volume; +} + +/**Function************************************************************* + + Synopsis [Returns support of the group.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NktMffcSupport( Vec_Ptr_t * vThis, Vec_Ptr_t * vFanins ) +{ + Vec_Int_t * vIns, * vIns2, * vTemp; + Abc_Obj_t * pObj; + int i; + vIns = Vec_IntAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vThis, pObj, i ) + { + vIns2 = (Vec_Int_t *)Vec_PtrEntry( vFanins, Abc_ObjId(pObj) ); + vIns = Vec_IntTwoMerge( vTemp = vIns, vIns2 ); + Vec_IntFree( vTemp ); + } + return vIns; +} + +/**Function************************************************************* + + Synopsis [Returns the best merger for the cluster of given node (pPivot).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NktMffcFindBest( Abc_Ntk_t * pNtk, Vec_Int_t * vMarks, Vec_Int_t * vIns, Vec_Ptr_t * vFanins, Vec_Ptr_t * vFanouts, Vec_Ptr_t * vVolumes, int Limit ) +{ + Vec_Int_t * vIns2, * vOuts, * vOuts2, * vTemp; + Abc_Obj_t * pPivot2, * pObj, * pObjBest = NULL; + double Cost, CostBest = (double)-ABC_INFINITY; + int i, Volume; + // collect the fanouts of the fanins + vOuts = Vec_IntAlloc( 100 ); + Abc_NtkForEachObjVec( pNtk, vIns, pObj, i ) + { + vOuts2 = (Vec_Int_t *)Vec_PtrEntry( vFanouts, Abc_ObjId(pObj) ); + if ( Vec_IntSize(vOuts2) > 16 ) + continue; + vOuts = Vec_IntTwoMerge( vTemp = vOuts, vOuts2 ); + Vec_IntFree( vTemp ); + } + // check the pairs + Abc_NtkForEachObjVec( pNtk, vOuts, pPivot2, i ) + { + if ( Vec_IntEntry(vMarks, Abc_ObjId(pPivot2)) == 0 ) + continue; + vIns2 = (Vec_Int_t *)Vec_PtrEntry( vFanins, Abc_ObjId(pPivot2) ); + Volume = Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pPivot2))); + Cost = Abc_NktMffcCostTwo( vIns, vIns2, Volume, Limit ); +//printf( "%5d %2d\n", Abc_ObjId(pPivot2), Cost ); + if ( Cost == (double)-ABC_INFINITY ) + continue; + if ( pObjBest == NULL || CostBest < Cost ) + { + pObjBest = pPivot2; + CostBest = Cost; + } + } +//printf( "Choosing %d\n", pObjBest->Id ); + Vec_IntFree( vOuts ); + return pObjBest; +} + +/**Function************************************************************* + + Synopsis [Processes one cluster.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NktMffcSaveOne( Vec_Ptr_t * vThis, Vec_Ptr_t * vVolumes ) +{ + Vec_Int_t * vVolume, * vResult; + Abc_Obj_t * pObj; + int i, k, Entry; + vResult = Vec_IntAlloc( 100 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vThis, pObj, i ) + { + vVolume = (Vec_Int_t *)Vec_PtrEntry( vVolumes, Abc_ObjId(pObj) ); + Vec_IntForEachEntry( vVolume, Entry, k ) + Vec_IntPush( vResult, Entry ); + } + return vResult; +} + +/**Function************************************************************* + + Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeCompareVolumeDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) +{ + int Diff = Abc_ObjRegular(*pp1)->iTemp - Abc_ObjRegular(*pp2)->iTemp; + if ( Diff > 0 ) + return -1; + if ( Diff < 0 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Create the network of supernodes.] + + Description [Returns array of interger arrays of IDs of nodes + included in a disjoint structural decomposition of the network.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NktMffcServer( Abc_Ntk_t * pNtk, int nInMax, int nOutMax ) +{ + Vec_Ptr_t * vResult, * vThis; + Vec_Ptr_t * vPivots, * vFanins, * vFanouts, * vVolumes; + Vec_Int_t * vLeaves, * vMarks; + Abc_Obj_t * pObj, * pObj2; + int i, k; + assert( nOutMax >= 1 && nOutMax <= 32 ); + vResult = Vec_PtrAlloc( 100 ); + // create fanins/fanouts + vPivots = Abc_NktMffcDerive( pNtk, &vFanins, &vFanouts, &vVolumes ); + // sort by their MFFC size + Vec_PtrForEachEntry( Abc_Obj_t *, vPivots, pObj, i ) + pObj->iTemp = Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pObj))); + Vec_PtrSort( vPivots, (int (*)(void))Abc_NodeCompareVolumeDecrease ); + // create marks + vMarks = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + Vec_PtrForEachEntry( Abc_Obj_t *, vPivots, pObj, i ) + if ( Abc_ObjIsNode(pObj) && Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pObj))) > 1 ) + Vec_IntWriteEntry( vMarks, Abc_ObjId(pObj), 1 ); + // consider nodes in the order of the marks + vThis = Vec_PtrAlloc( 10 ); +// while ( 1 ) + Vec_PtrForEachEntry( Abc_Obj_t *, vPivots, pObj, i ) + { +// pObj = Abc_NtkObj( pNtk, 589 ); + if ( Vec_IntEntry(vMarks, Abc_ObjId(pObj)) == 0 ) + continue; + // start the set + Vec_PtrClear( vThis ); + Vec_PtrPush( vThis, pObj ); + Vec_IntWriteEntry( vMarks, Abc_ObjId(pObj), 0 ); + // quit if exceeded the limit + vLeaves = (Vec_Int_t *)Vec_PtrEntry( vFanins, Abc_ObjId(pObj) ); + if ( Vec_IntSize(vLeaves) > nInMax ) + { + Vec_PtrPush( vResult, Abc_NktMffcSaveOne(vThis, vVolumes) ); + continue; + } + // try adding one node at a time + for ( k = 1; k < nOutMax; k++ ) + { + // quit if exceeded the limit + vLeaves = Abc_NktMffcSupport( vThis, vFanins ); + assert( Vec_IntSize(vLeaves) <= nInMax ); + pObj2 = Abc_NktMffcFindBest( pNtk, vMarks, vLeaves, vFanins, vFanouts, vVolumes, nInMax ); + Vec_IntFree( vLeaves ); + // quit if there is no extension + if ( pObj2 == NULL ) + break; + Vec_PtrPush( vThis, pObj2 ); + Vec_IntWriteEntry( vMarks, Abc_ObjId(pObj2), 0 ); + } + Vec_PtrPush( vResult, Abc_NktMffcSaveOne(vThis, vVolumes) ); +// break; + } + Vec_PtrFree( vThis ); + Vec_IntFree( vMarks ); + // delele fanins/outputs + Abc_NktMffcFree( vPivots, vFanins, vFanouts, vVolumes ); + return vResult; +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NktMffcServerTest( Abc_Ntk_t * pNtk ) +{ + char pFileName[1000]; + Vec_Ptr_t * vGlobs; + Vec_Int_t * vGlob, * vLeaves, * vRoots; + double Cost, CostAll = 0.0; + int i, k, Entry, nNodes = 0, clk = clock(); + vGlobs = Abc_NktMffcServer( pNtk, 18, 3 ); + vLeaves = Vec_IntAlloc( 100 ); + vRoots = Vec_IntAlloc( 100 ); + Vec_PtrForEachEntry( Vec_Int_t *, vGlobs, vGlob, i ) + { + nNodes += Vec_IntSize(vGlob); + Abc_NktMffCollectLeafRootInt( pNtk, vGlob, vLeaves, vRoots ); + if ( Vec_IntSize(vGlob) <= Vec_IntSize(vRoots) ) + continue; + Cost = 1.0 * Vec_IntSize(vGlob)/(Vec_IntSize(vLeaves) + Vec_IntSize(vRoots)); + CostAll += Cost; + if ( Cost < 0.5 ) + continue; + + printf( "%6d : Root =%3d. Leaf =%3d. Node =%4d. ", + i, Vec_IntSize(vRoots), Vec_IntSize(vLeaves), Vec_IntSize(vGlob) ); + printf( "Cost =%6.2f ", Cost ); + Vec_IntForEachEntry( vRoots, Entry, k ) + printf( "%d ", Entry ); + printf( "\n" ); + + sprintf( pFileName, "%sc%04di%02dn%02d.blif", Abc_NtkName(pNtk), i, Vec_IntSize(vLeaves), Vec_IntSize(vGlob) ); + Abc_NktMffcPrintInt( pFileName, pNtk, vRoots, vGlob, vLeaves ); + } + Vec_IntFree( vLeaves ); + Vec_IntFree( vRoots ); + Vec_PtrForEachEntry( Vec_Int_t *, vGlobs, vGlob, i ) + Vec_IntFree( vGlob ); + Vec_PtrFree( vGlobs ); + printf( "Total = %6d. Nodes = %6d. ", Abc_NtkNodeNum(pNtk), nNodes ); + printf( "Cost = %6.2f ", CostAll ); + Abc_PrintTime( 1, "Time", clock() - clk ); +} + +ABC_NAMESPACE_IMPL_END + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index 0c75919c..5397f167 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcMulti.c b/src/base/abci/abcMulti.c index 4e962cff..299e22d5 100644 --- a/src/base/abci/abcMulti.c +++ b/src/base/abci/abcMulti.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcMv.c b/src/base/abci/abcMv.c index 4bfb1a02..98d27a19 100644 --- a/src/base/abci/abcMv.c +++ b/src/base/abci/abcMv.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcNpnSave.c b/src/base/abci/abcNpnSave.c index 381409de..568a3e28 100644 --- a/src/base/abci/abcNpnSave.c +++ b/src/base/abci/abcNpnSave.c @@ -20,6 +20,7 @@ #include "abc.h" #include "aig.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index d27eab82..e3df605e 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -52,8 +53,9 @@ static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, in SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) +Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) { + DdManager * dd = (DdManager *)dd0; Abc_Ntk_t * pNtk; Vec_Ptr_t * vNamesPiFake = NULL; Abc_Obj_t * pNode, * pNodePi, * pNodePo; @@ -72,7 +74,7 @@ Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo // make sure BDD depends on the variables whose index // does not exceed the size of the array with PI names - bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp ); + bSupp = Cudd_Support( dd, (DdNode *)bFunc ); Cudd_Ref( bSupp ); for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) ) break; @@ -90,7 +92,7 @@ Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), pName, NULL ); // create the node pNode = Abc_NtkCreateNode( pNtk ); - pNode->pData = (DdNode *)Cudd_bddTransfer( dd, (DdManager *)pNtk->pManFunc, bFunc ); Cudd_Ref((DdNode *)pNode->pData); + pNode->pData = (DdNode *)Cudd_bddTransfer( dd, (DdManager *)pNtk->pManFunc, (DdNode *)bFunc ); Cudd_Ref((DdNode *)pNode->pData); Abc_NtkForEachPi( pNtk, pNodePi, i ) Abc_ObjAddFanin( pNode, pNodePi ); // create the only PO @@ -246,7 +248,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * SeeAlso [] ***********************************************************************/ -DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ) +void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ) { ProgressBar * pProgress; Abc_Obj_t * pObj, * pFanin; @@ -450,7 +452,7 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize Extra_ProgressBarUpdate( pProgress, *pCounter, NULL ); } // prepare the return value - bFunc = Abc_ObjGlobalBdd(pNode); + bFunc = (DdNode *)Abc_ObjGlobalBdd(pNode); // dereference BDD at the node if ( --pNode->vFanouts.nSize == 0 && fDropInternal ) { @@ -471,9 +473,9 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize SeeAlso [] ***********************************************************************/ -DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ) +void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ) { - return (DdManager *)Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, fFreeMan ); + return Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, fFreeMan ); } /**Function************************************************************* diff --git a/src/base/abci/abcOdc.c b/src/base/abci/abcOdc.c index 5db556b8..50694832 100644 --- a/src/base/abci/abcOdc.c +++ b/src/base/abci/abcOdc.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 9f52d71f..bd5f986f 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -693,7 +693,8 @@ void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk ) int i; extern void Abc_NodeMffcConeSuppPrint( Abc_Obj_t * pNode ); Abc_NtkForEachNode( pNtk, pNode, i ) - Abc_NodeMffcConeSuppPrint( pNode ); + if ( Abc_ObjFanoutNum(pNode) > 1 ) + Abc_NodeMffcConeSuppPrint( pNode ); } /**Function************************************************************* @@ -1147,9 +1148,6 @@ void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj ) case ABC_OBJ_CONST1: fprintf( pFile, "Const1 " ); break; - case ABC_OBJ_PIO: - fprintf( pFile, "PIO " ); - break; case ABC_OBJ_PI: fprintf( pFile, "PI " ); break; @@ -1162,9 +1160,6 @@ void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj ) case ABC_OBJ_BO: fprintf( pFile, "BO " ); break; - case ABC_OBJ_ASSERT: - fprintf( pFile, "Assert " ); - break; case ABC_OBJ_NET: fprintf( pFile, "Net " ); break; diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c index 35c1ee29..154c5e1c 100644 --- a/src/base/abci/abcProve.c +++ b/src/base/abci/abcProve.c @@ -21,6 +21,7 @@ #include "abc.h" #include "fraig.h" #include "math.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcQuant.c b/src/base/abci/abcQuant.c index 957d99b5..262797d2 100644 --- a/src/base/abci/abcQuant.c +++ b/src/base/abci/abcQuant.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcReach.c b/src/base/abci/abcReach.c index 6eb7fb06..f7bc5186 100644 --- a/src/base/abci/abcReach.c +++ b/src/base/abci/abcReach.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -103,7 +104,7 @@ DdNode ** Abc_NtkCreatePartitions( DdManager * dd, Abc_Ntk_t * pNtk, int fReorde Abc_NtkForEachLatch( pNtk, pNode, i ) { bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); - pbParts[i] = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( pbParts[i] ); + pbParts[i] = Cudd_bddXnor( dd, bVar, (DdNode *)Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( pbParts[i] ); } // free the global BDDs Abc_NtkFreeGlobalBdds( pNtk, 0 ); @@ -264,7 +265,7 @@ void Abc_NtkVerifyUsingBdds( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fP assert( Abc_ObjFanoutNum(Abc_NtkPo(pNtk,0)) == 0 ); // PO should go first // compute the global BDDs of the latches - dd = Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, fVerbose ); if ( dd == NULL ) { printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax ); @@ -274,7 +275,7 @@ void Abc_NtkVerifyUsingBdds( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fP printf( "Shared BDD size is %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); // save the output BDD - bOutput = Abc_ObjGlobalBdd(Abc_NtkPo(pNtk,0)); Cudd_Ref( bOutput ); + bOutput = (DdNode *)Abc_ObjGlobalBdd(Abc_NtkPo(pNtk,0)); Cudd_Ref( bOutput ); // create partitions pbParts = Abc_NtkCreatePartitions( dd, pNtk, fReorder, fVerbose ); diff --git a/src/base/abci/abcReconv.c b/src/base/abci/abcReconv.c index 434577ec..e0cec5cd 100644 --- a/src/base/abci/abcReconv.c +++ b/src/base/abci/abcReconv.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c index 4e922ebd..3ba171b7 100644 --- a/src/base/abci/abcRefactor.c +++ b/src/base/abci/abcRefactor.c @@ -20,6 +20,7 @@ #include "abc.h" #include "dec.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -187,7 +188,10 @@ pManRef->timeTotal = clock() - clkStart; ***********************************************************************/ Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose ) { - extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); + extern DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited ); + extern DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited ); + extern char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ); + extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); int fVeryVerbose = 0; Abc_Obj_t * pFanin; Dec_Graph_t * pFForm; diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c index 4a63db67..719d722e 100644 --- a/src/base/abci/abcRestruct.c +++ b/src/base/abci/abcRestruct.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "dec.h" #include "dsd.h" #include "cut.h" @@ -317,6 +318,7 @@ Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_ ***********************************************************************/ Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut ) { + extern DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited ); Dec_Graph_t * pGraph; Dsd_Node_t * pNodeDsd; Abc_Obj_t * pLeaf; diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c index a0a1af91..aab4d1ce 100644 --- a/src/base/abci/abcResub.c +++ b/src/base/abci/abcResub.c @@ -20,6 +20,7 @@ #include "abc.h" #include "dec.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index f36600fa..54e19f50 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "rwr.h" #include "dec.h" diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c index 12e94478..3e60ebf9 100644 --- a/src/base/abci/abcRr.c +++ b/src/base/abci/abcRr.c @@ -20,6 +20,7 @@ #include "abc.h" #include "fraig.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index 30c77e59..b0c5024a 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -834,7 +834,7 @@ int Abc_NodeAddClausesTop( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVa sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes ) { sat_solver * pSat; - Extra_MmFlex_t * pMmFlex; + Mem_Flex_t * pMmFlex; Abc_Obj_t * pNode; Vec_Str_t * vCube; Vec_Int_t * vVars; @@ -850,7 +850,7 @@ sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes ) // start the data structures pSat = sat_solver_new(); sat_solver_store_alloc( pSat ); - pMmFlex = Extra_MmFlexStart(); + pMmFlex = Mem_FlexStart(); vCube = Vec_StrAlloc( 100 ); vVars = Vec_IntAlloc( 100 ); @@ -883,7 +883,7 @@ finish: // delete Vec_StrFree( vCube ); Vec_IntFree( vVars ); - Extra_MmFlexStop( pMmFlex ); + Mem_FlexStop( pMmFlex, 0 ); return pSat; } diff --git a/src/base/abci/abcScorr.c b/src/base/abci/abcScorr.c index 07e52fa4..9687003b 100644 --- a/src/base/abci/abcScorr.c +++ b/src/base/abci/abcScorr.c @@ -67,7 +67,7 @@ Vec_Int_t * Abc_NtkMapGiaIntoNameId( Abc_Ntk_t * pNetlist, Aig_Man_t * pAig, Gia Abc_Obj_t * pNet, * pNode, * pAnd; Aig_Obj_t * pObjAig; int i; - vId2Name = Vec_IntStart( 0 ); + vId2Name = Vec_IntAlloc( 0 ); Vec_IntFill( vId2Name, pGia ? Gia_ManObjNum(pGia) : Aig_ManObjNumMax(pAig), ~0 ); // copy all names Abc_NtkForEachNet( pNetlist, pNet, i ) diff --git a/src/base/abci/abcSense.c b/src/base/abci/abcSense.c index cfecfaf3..8a477c4e 100644 --- a/src/base/abci/abcSense.c +++ b/src/base/abci/abcSense.c @@ -20,6 +20,7 @@ #include "abc.h" #include "fraig.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c index 4e0a7373..41abc4db 100644 --- a/src/base/abci/abcSymm.c +++ b/src/base/abci/abcSymm.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START @@ -93,7 +94,7 @@ void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int // compute the global functions clk = clock(); - dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose ); printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) ); Cudd_AutodynDisable( dd ); if ( !fGarbCollect ) @@ -138,7 +139,7 @@ void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVer Abc_NtkForEachCo( pNtk, pNode, i ) { // bFunc = pNtk->vFuncsGlob->pArray[i]; - bFunc = Abc_ObjGlobalBdd( pNode ); + bFunc = (DdNode *)Abc_ObjGlobalBdd( pNode ); nSupps += Cudd_SupportSize( dd, bFunc ); if ( Cudd_IsConstant(bFunc) ) continue; diff --git a/src/base/abci/abcUnate.c b/src/base/abci/abcUnate.c index b77eec63..829a83bd 100644 --- a/src/base/abci/abcUnate.c +++ b/src/base/abci/abcUnate.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -76,14 +77,14 @@ void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose ) int clkBdd, clkUnate; // compute the global BDDs - dd = Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose); + dd = (DdManager *)Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose); if ( dd == NULL ) return; clkBdd = clock() - clk; // get information about the network // dd = pNtk->pManGlob; -// dd = Abc_NtkGlobalBddMan( pNtk ); +// dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk ); // pbGlobal = (DdNode **)Vec_PtrArray( pNtk->vFuncsGlob ); // print the size of the BDDs @@ -95,7 +96,7 @@ clkBdd = clock() - clk; Abc_NtkForEachCo( pNtk, pNode, i ) { // p = Extra_UnateComputeSlow( dd, pbGlobal[i] ); - p = Extra_UnateComputeSlow( dd, Abc_ObjGlobalBdd(pNode) ); + p = Extra_UnateComputeSlow( dd, (DdNode *)Abc_ObjGlobalBdd(pNode) ); if ( fVerbose ) Extra_UnateInfoPrint( p ); TotalSupps += p->nVars; @@ -111,7 +112,7 @@ clkBdd = clock() - clk; Abc_NtkForEachCo( pNtk, pNode, i ) { // p = Extra_UnateComputeFast( dd, pbGlobal[i] ); - p = Extra_UnateComputeFast( dd, Abc_ObjGlobalBdd(pNode) ); + p = Extra_UnateComputeFast( dd, (DdNode *)Abc_ObjGlobalBdd(pNode) ); if ( fVerbose ) Extra_UnateInfoPrint( p ); TotalSupps += p->nVars; diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c index ae7fbd02..f62ec7fc 100644 --- a/src/base/abci/abcUnreach.c +++ b/src/base/abci/abcUnreach.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -61,7 +62,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose ) } // compute the global BDDs of the latches - dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); if ( dd == NULL ) return 0; if ( fVerbose ) @@ -141,7 +142,7 @@ DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbo { bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); // bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); - bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd ); + bProd = Cudd_bddXnor( dd, bVar, (DdNode *)Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd ); bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bProd ); diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index 58b8fbb8..acdfcd93 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -24,6 +24,7 @@ #include "fraig.h" #include "sim.h" #include "aig.h" +#include "saig.h" #include "gia.h" #include "ssw.h" @@ -1029,7 +1030,6 @@ void Abc_NtkSimulteBuggyMiter( Abc_Ntk_t * pNtk ) int Abc_NtkIsTrueCex( Abc_Ntk_t * pNtk, Abc_Cex_t * pCex ) { extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); -// extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); Aig_Man_t * pMan; int status, fStrashed = 0; if ( !Abc_NtkIsStrash(pNtk) ) @@ -1040,7 +1040,7 @@ int Abc_NtkIsTrueCex( Abc_Ntk_t * pNtk, Abc_Cex_t * pCex ) pMan = Abc_NtkToDar( pNtk, 0, 1 ); if ( pMan ) { - status = Ssw_SmlRunCounterExample( pMan, pCex ); + status = Saig_ManVerifyCex( pMan, pCex ); Aig_ManStop( pMan ); } if ( fStrashed ) diff --git a/src/base/cmd/cmd.h b/src/base/cmd/cmd.h index 787e52b9..740cf758 100644 --- a/src/base/cmd/cmd.h +++ b/src/base/cmd/cmd.h @@ -60,6 +60,8 @@ extern void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, const char * key ); extern void Cmd_FlagUpdateValue( Abc_Frame_t * pAbc, const char * key, char * value ); /*=== cmdHist.c ========================================================*/ extern void Cmd_HistoryAddCommand( Abc_Frame_t * pAbc, const char * command ); +/*=== cmdLoad.c ========================================================*/ +extern int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ); diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index 8ff03282..b96737c6 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int CmdCommandLoad ( Abc_Frame_t * pAbc, int argc, char ** argv ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/cmd/cmdPlugin.c b/src/base/cmd/cmdPlugin.c index 116687c7..1e2b7712 100644 --- a/src/base/cmd/cmdPlugin.c +++ b/src/base/cmd/cmdPlugin.c @@ -484,20 +484,18 @@ int Cmd_CommandAbcPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Counter example has a wrong length.\n" ); else { - extern int Gia_ManVerifyCounterExampleAllOuts( Gia_Man_t * pAig, Abc_Cex_t * p ); - Abc_Print( 1, "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 ); Abc_PrintTime( 1, "Time", clk ); ABC_FREE( pAbc->pCex ); - pAbc->pCex = Gia_ManDeriveCexFromArray( pAbc->pGia, vCex, 0, nFrames-1 ); + pAbc->pCex = Abc_CexCreate( Gia_ManRegNum(pAbc->pGia), Gia_ManPiNum(pAbc->pGia), Vec_IntArray(vCex), nFrames-1, 0, 0 ); -// Gia_ManPrintCex( pAbc->pCex ); +// Abc_CexPrint( pAbc->pCex ); -// if ( !Gia_ManVerifyCounterExample( pAbc->pGia, pAbc->pCex, 0 ) ) +// if ( !Gia_ManVerifyCex( pAbc->pGia, pAbc->pCex, 0 ) ) // Abc_Print( 1, "Generated counter-example is INVALID.\n" ); // remporary work-around to detect the output number - October 18, 2010 - pAbc->pCex->iPo = Gia_ManVerifyCounterExampleAllOuts( pAbc->pGia, pAbc->pCex ); + pAbc->pCex->iPo = Gia_ManFindFailedPoCex( pAbc->pGia, pAbc->pCex ); if ( pAbc->pCex->iPo == -1 ) { Abc_Print( 1, "Generated counter-example is INVALID.\n" ); diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index b1835dbf..d5415384 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -27,6 +27,7 @@ //////////////////////////////////////////////////////////////////////// #include "abc.h" +#include "extra.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -137,7 +138,6 @@ extern void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileT extern void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName ); extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO ); extern Abc_Obj_t * Io_ReadCreateResetLatch( Abc_Ntk_t * pNtk, int fBlifMv ); extern Abc_Obj_t * Io_ReadCreateResetMux( Abc_Ntk_t * pNtk, char * pResetLO, char * pDataLI, int fBlifMv ); diff --git a/src/base/io/ioReadBblif.c b/src/base/io/ioReadBblif.c index e2fcca43..5b15c9d4 100644 --- a/src/base/io/ioReadBblif.c +++ b/src/base/io/ioReadBblif.c @@ -73,7 +73,7 @@ Abc_Ntk_t * Bbl_ManToAbc( Bbl_Man_t * p ) pObjNew = Abc_NtkCreateNode( pNtk ); else assert( 0 ); if ( Bbl_ObjIsLut(pObj) ) - pObjNew->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, Bbl_ObjSop(p, pObj) ); + pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, Bbl_ObjSop(p, pObj) ); Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew ); } // connect objects diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c index 681a4e36..0f60bb7f 100644 --- a/src/base/io/ioReadBench.c +++ b/src/base/io/ioReadBench.c @@ -176,12 +176,12 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) if ( Extra_TruthIsConst0(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); - Abc_ObjSetData( pNode, Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 0\n" ) ); + Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); } else if ( Extra_TruthIsConst1(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); - Abc_ObjSetData( pNode, Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 1\n" ) ); + Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); } else { @@ -189,11 +189,11 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); assert( nNames > 0 ); if ( nNames > 1 ) - Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Extra_MmFlex_t *)pNtk->pManFunc, nNames, uTruth) ); + Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Mem_Flex_t *)pNtk->pManFunc, nNames, uTruth) ); else if ( pString[0] == '2' ) - Abc_ObjSetData( pNode, Abc_SopCreateBuf((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( pString[0] == '1' ) - Abc_ObjSetData( pNode, Abc_SopCreateInv((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else { printf( "%s: Reading truth table (%s) of single-input node has failed.\n", Extra_FileReaderGetFileName(p), pString ); @@ -211,28 +211,28 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); // assign the cover if ( strcmp(pType, "AND") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateAnd((Extra_MmFlex_t *)pNtk->pManFunc, nNames, NULL) ); + Abc_ObjSetData( pNode, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "OR") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateOr((Extra_MmFlex_t *)pNtk->pManFunc, nNames, NULL) ); + Abc_ObjSetData( pNode, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "NAND") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateNand((Extra_MmFlex_t *)pNtk->pManFunc, nNames) ); + Abc_ObjSetData( pNode, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NOR") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateNor((Extra_MmFlex_t *)pNtk->pManFunc, nNames) ); + Abc_ObjSetData( pNode, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "XOR") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateXor((Extra_MmFlex_t *)pNtk->pManFunc, nNames) ); + Abc_ObjSetData( pNode, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateNxor((Extra_MmFlex_t *)pNtk->pManFunc, nNames) ); + Abc_ObjSetData( pNode, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strncmp(pType, "BUF", 3) == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateBuf((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strcmp(pType, "NOT") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateInv((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strncmp(pType, "MUX", 3) == 0 ) // Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") ); - Abc_ObjSetData( pNode, Abc_SopRegister((Extra_MmFlex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") ); + Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") ); else if ( strncmp(pType, "gnd", 3) == 0 ) - Abc_ObjSetData( pNode, Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 0\n" ) ); + Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); else if ( strncmp(pType, "vdd", 3) == 0 ) - Abc_ObjSetData( pNode, Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 1\n" ) ); + Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); else { printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) ); diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index 06920afe..a1241354 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -59,7 +59,6 @@ static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ); static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ); static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); -static int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ); static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); @@ -266,8 +265,6 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens ); else if ( !strcmp( pDirective, ".outputs" ) ) fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens ); - else if ( !strcmp( pDirective, ".asserts" ) ) - fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens ); else if ( !strcmp( pDirective, ".input_arrival" ) ) fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens ); else if ( !strcmp( pDirective, ".default_input_arrival" ) ) @@ -285,7 +282,7 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) { pNtk->ntkType = ABC_NTK_NETLIST; pNtk->ntkFunc = ABC_FUNC_BLACKBOX; - Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); pNtk->pManFunc = NULL; } else @@ -354,25 +351,6 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) SeeAlso [] ***********************************************************************/ -int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) -{ - int i; - for ( i = 1; i < vTokens->nSize; i++ ) - Io_ReadCreateAssert( p->pNtkCur, (char *)vTokens->pArray[i] ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { Abc_Ntk_t * pNtk = p->pNtkCur; @@ -510,7 +488,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) Vec_StrPush( p->vCubes, 0 ); // set the pointer to the functionality of the node - Abc_ObjSetData( pNode, Abc_SopRegister((Extra_MmFlex_t *)pNtk->pManFunc, p->vCubes->pArray) ); + Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, p->vCubes->pArray) ); // check the size if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum((char *)Abc_ObjData(pNode)) ) @@ -645,7 +623,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP ); p->pNtkCur->ntkFunc = ABC_FUNC_MAP; - Extra_MmFlexStop( (Extra_MmFlex_t *)p->pNtkCur->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)p->pNtkCur->pManFunc, 0 ); p->pNtkCur->pManFunc = pGenlib; } diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index cc8bff17..0e121b47 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -813,7 +813,7 @@ static Abc_Lib_t * Io_MvParse( Io_MvMan_t * p ) { if ( pMod->pNtk->ntkFunc == ABC_FUNC_SOP ) { - Extra_MmFlexStop( (Extra_MmFlex_t *)pMod->pNtk->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)pMod->pNtk->pManFunc, 0 ); pMod->pNtk->pManFunc = NULL; pMod->pNtk->ntkFunc = ABC_FUNC_BLACKBOX; } @@ -1248,7 +1248,7 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine ) if ( k == nEquals ) { Abc_Obj_t * pNode = Abc_NtkCreateNode( p->pNtk ); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)p->pNtk->pManFunc, " 0\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, " 0\n" ); pNet = Abc_NtkFindOrCreateNet( p->pNtk, Abc_ObjNameSuffix(pNode, "abc") ); Abc_ObjAddFanin( pNet, pNode ); pTerm = Abc_NtkCreateBi( p->pNtk ); @@ -1362,7 +1362,7 @@ static int Io_MvParseLineMv( Io_MvMod_t * p, char * pLine ) Vec_Ptr_t * vTokens = p->pMan->vTokens; Abc_Obj_t * pObj; Io_MvVar_t * pVar = NULL; - Extra_MmFlex_t * pFlex; + Mem_Flex_t * pFlex; char * pName; int nCommas, nValues, i, k; // count commas and get the tokens @@ -1393,22 +1393,22 @@ static int Io_MvParseLineMv( Io_MvMod_t * p, char * pLine ) return 0; } // go through variables - pFlex = (Extra_MmFlex_t *)Abc_NtkMvVarMan( p->pNtk ); + pFlex = (Mem_Flex_t *)Abc_NtkMvVarMan( p->pNtk ); for ( i = 0; i <= nCommas; i++ ) { pName = (char *)Vec_PtrEntry( vTokens, i+1 ); pObj = Abc_NtkFindOrCreateNet( p->pNtk, pName ); // allocate variable - pVar = (Io_MvVar_t *)Extra_MmFlexEntryFetch( pFlex, sizeof(Io_MvVar_t) ); + pVar = (Io_MvVar_t *)Mem_FlexEntryFetch( pFlex, sizeof(Io_MvVar_t) ); pVar->nValues = nValues; pVar->pNames = NULL; // create names if ( Vec_PtrSize(vTokens) > nCommas + 3 ) { - pVar->pNames = (char **)Extra_MmFlexEntryFetch( pFlex, sizeof(char *) * nValues ); + pVar->pNames = (char **)Mem_FlexEntryFetch( pFlex, sizeof(char *) * nValues ); Vec_PtrForEachEntryStart( char *, vTokens, pName, k, nCommas + 3 ) { - pVar->pNames[k-(nCommas + 3)] = (char *)Extra_MmFlexEntryFetch( pFlex, strlen(pName) + 1 ); + pVar->pNames[k-(nCommas + 3)] = (char *)Mem_FlexEntryFetch( pFlex, strlen(pName) + 1 ); strcpy( pVar->pNames[k-(nCommas + 3)], pName ); } } @@ -1640,10 +1640,10 @@ static Abc_Obj_t * Io_MvParseAddResetCircuit( Io_MvMod_t * p, char * pName ) // int nValues = Abc_ObjMvVarNum(pOutNet); // sprintf( Buffer, "2 %d %d %d\n1 - - =1\n0 - - =2\n", nValues, nValues, nValues ); sprintf( Buffer, "1 - - =1\n0 - - =2\n" ); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)p->pNtk->pManFunc, Buffer ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, Buffer ); } else - pNode->pData = Abc_SopCreateMux( (Extra_MmFlex_t *)p->pNtk->pManFunc ); + pNode->pData = Abc_SopCreateMux( (Mem_Flex_t *)p->pNtk->pManFunc ); // add nets Abc_ObjAddFanin( pNode, pResetLONet ); Abc_ObjAddFanin( pNode, pData1Net ); @@ -1704,7 +1704,7 @@ static int Io_MvParseLineNamesMvOne( Io_MvMod_t * p, Vec_Ptr_t * vTokens, Vec_Pt pNode->pData = Io_MvParseTableMv( p, pNode, vTokens2, nInputs, nOutputs, iOut ); if ( pNode->pData == NULL ) return 0; - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)p->pNtk->pManFunc, (char *)pNode->pData ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, (char *)pNode->pData ); //printf( "Finished parsing node \"%s\" with table:\n%s\n", pName, pNode->pData ); return 1; } @@ -1826,7 +1826,7 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins ) // get the tokens Io_MvSplitIntoTokens( vTokens, pTable, '.' ); if ( Vec_PtrSize(vTokens) == 0 ) - return Abc_SopCreateConst0( (Extra_MmFlex_t *)p->pNtk->pManFunc ); + return Abc_SopCreateConst0( (Mem_Flex_t *)p->pNtk->pManFunc ); if ( Vec_PtrSize(vTokens) == 1 ) { pOutput = (char *)Vec_PtrEntry( vTokens, 0 ); @@ -1836,7 +1836,7 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins ) sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Io_MvGetLine(p->pMan, pOutput), pOutput ); return NULL; } - return pOutput[0] == '0' ? Abc_SopCreateConst0((Extra_MmFlex_t *)p->pNtk->pManFunc) : Abc_SopCreateConst1((Extra_MmFlex_t *)p->pNtk->pManFunc); + return pOutput[0] == '0' ? Abc_SopCreateConst0((Mem_Flex_t *)p->pNtk->pManFunc) : Abc_SopCreateConst1((Mem_Flex_t *)p->pNtk->pManFunc); } pProduct = (char *)Vec_PtrEntry( vTokens, 0 ); if ( Vec_PtrSize(vTokens) % 2 == 1 ) @@ -1914,7 +1914,7 @@ static int Io_MvParseLineNamesBlif( Io_MvMod_t * p, char * pLine ) pNode->pData = Io_MvParseTableBlif( p, pName + strlen(pName), Abc_ObjFaninNum(pNode) ); if ( pNode->pData == NULL ) return 0; - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)p->pNtk->pManFunc, (char *)pNode->pData ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, (char *)pNode->pData ); return 1; } @@ -1953,7 +1953,7 @@ static int Io_MvParseLineShortBlif( Io_MvMod_t * p, char * pLine ) // create fanins pNode = Io_ReadCreateNode( p->pNtk, pName, (char **)(vTokens->pArray + 1), 1 ); // parse the table of this node - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)p->pNtk->pManFunc, "1 1\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, "1 1\n" ); return 1; } @@ -1970,22 +1970,22 @@ static int Io_MvParseLineShortBlif( Io_MvMod_t * p, char * pLine ) ***********************************************************************/ Io_MvVar_t * Abc_NtkMvVarDup( Abc_Ntk_t * pNtk, Io_MvVar_t * pVar ) { - Extra_MmFlex_t * pFlex; + Mem_Flex_t * pFlex; Io_MvVar_t * pVarDup; int i; if ( pVar == NULL ) return NULL; - pFlex = (Extra_MmFlex_t *)Abc_NtkMvVarMan( pNtk ); + pFlex = (Mem_Flex_t *)Abc_NtkMvVarMan( pNtk ); assert( pFlex != NULL ); - pVarDup = (Io_MvVar_t *)Extra_MmFlexEntryFetch( pFlex, sizeof(Io_MvVar_t) ); + pVarDup = (Io_MvVar_t *)Mem_FlexEntryFetch( pFlex, sizeof(Io_MvVar_t) ); pVarDup->nValues = pVar->nValues; pVarDup->pNames = NULL; if ( pVar->pNames == NULL ) return pVarDup; - pVarDup->pNames = (char **)Extra_MmFlexEntryFetch( pFlex, sizeof(char *) * pVar->nValues ); + pVarDup->pNames = (char **)Mem_FlexEntryFetch( pFlex, sizeof(char *) * pVar->nValues ); for ( i = 0; i < pVar->nValues; i++ ) { - pVarDup->pNames[i] = (char *)Extra_MmFlexEntryFetch( pFlex, strlen(pVar->pNames[i]) + 1 ); + pVarDup->pNames[i] = (char *)Mem_FlexEntryFetch( pFlex, strlen(pVar->pNames[i]) + 1 ); strcpy( pVarDup->pNames[i], pVar->pNames[i] ); } return pVarDup; @@ -2070,7 +2070,7 @@ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) { assert( p->pNtk->ntkFunc == ABC_FUNC_SOP ); p->pNtk->ntkFunc = ABC_FUNC_MAP; - Extra_MmFlexStop( (Extra_MmFlex_t *)p->pNtk->pManFunc ); + Mem_FlexStop( (Mem_Flex_t *)p->pNtk->pManFunc, 0 ); p->pNtk->pManFunc = pGenlib; } diff --git a/src/base/io/ioReadDsd.c b/src/base/io/ioReadDsd.c index 35bc6aaa..3608507b 100644 --- a/src/base/io/ioReadDsd.c +++ b/src/base/io/ioReadDsd.c @@ -186,11 +186,11 @@ Abc_Obj_t * Io_ReadDsd_rec( Abc_Ntk_t * pNtk, char * pCur, char * pSop ) } } if ( pSop ) - pObj->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, pSop ); + pObj->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, pSop ); else if ( TypeExor ) - pObj->pData = Abc_SopCreateXorSpecial( (Extra_MmFlex_t *)pNtk->pManFunc, nParts ); + pObj->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtk->pManFunc, nParts ); else - pObj->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtk->pManFunc, nParts, NULL ); + pObj->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtk->pManFunc, nParts, NULL ); return pObj; } if ( *pCur >= 'a' && *pCur <= 'z' ) diff --git a/src/base/io/ioReadEdif.c b/src/base/io/ioReadEdif.c index 8c739e61..5590ec80 100644 --- a/src/base/io/ioReadEdif.c +++ b/src/base/io/ioReadEdif.c @@ -198,21 +198,21 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p ) Abc_NtkForEachNode( pNtk, pObj, i ) { if ( strncmp( (char *)pObj->pData, "And", 3 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateAnd((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); + Abc_ObjSetData( pObj, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( (char *)pObj->pData, "Or", 2 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateOr((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); + Abc_ObjSetData( pObj, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( (char *)pObj->pData, "Nand", 4 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateNand((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); + Abc_ObjSetData( pObj, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Nor", 3 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateNor((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); + Abc_ObjSetData( pObj, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Exor", 4 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateXor((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); + Abc_ObjSetData( pObj, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Exnor", 5 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateNxor((Extra_MmFlex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); + Abc_ObjSetData( pObj, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); else if ( strncmp( (char *)pObj->pData, "Inv", 3 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateInv((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pObj, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strncmp( (char *)pObj->pData, "Buf", 3 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateBuf((Extra_MmFlex_t *)pNtk->pManFunc) ); + Abc_ObjSetData( pObj, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else { printf( "%s: Unknown gate type \"%s\".\n", Extra_FileReaderGetFileName(p), (char*)pObj->pData ); diff --git a/src/base/io/ioReadPla.c b/src/base/io/ioReadPla.c index 63ffa296..36d44c68 100644 --- a/src/base/io/ioReadPla.c +++ b/src/base/io/ioReadPla.c @@ -254,12 +254,12 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p, int fZeros ) if ( ppSops[i]->nSize == 0 ) { Abc_ObjRemoveFanins(pNode); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, " 0\n" ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ); Vec_StrFree( ppSops[i] ); continue; } Vec_StrPush( ppSops[i], 0 ); - pNode->pData = Abc_SopRegister( (Extra_MmFlex_t *)pNtk->pManFunc, ppSops[i]->pArray ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, ppSops[i]->pArray ); Vec_StrFree( ppSops[i] ); } ABC_FREE( ppSops ); diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index a4dbf949..9a50c0c8 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -599,31 +599,6 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName ) /**Function************************************************************* - Synopsis [Creates PO terminal and net.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pNet, * pTerm; - // get the PO net - pNet = Abc_NtkFindNet( pNtk, pName ); - if ( pNet && Abc_ObjFaninNum(pNet) == 0 ) - printf( "Warning: Assert \"%s\" appears twice in the list.\n", pName ); - pNet = Abc_NtkFindOrCreateNet( pNtk, pName ); - // add the PO node - pTerm = Abc_NtkCreateAssert( pNtk ); - Abc_ObjAddFanin( pTerm, pNet ); - return pTerm; -} - -/**Function************************************************************* - Synopsis [Create a latch with the given input/output.] Description [By default, the latch value is unknown (ABC_INIT_NONE).] diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index 7233161b..cade2ea9 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -362,8 +362,6 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) { Abc_NtkForEachCo( pNtk, pTerm, i ) { - if ( Abc_ObjIsAssert(pTerm) ) - continue; pNet = Abc_ObjFanin0(pTerm); // get the line length after this name is written AddedLength = strlen(Abc_ObjName(pNet)) + 1; diff --git a/src/base/main/main.h b/src/base/main/main.h index 41593498..f8d6c1ab 100644 --- a/src/base/main/main.h +++ b/src/base/main/main.h @@ -108,7 +108,7 @@ extern ABC_DLL int Abc_FrameIsFlagEnabled( char * pFlag ); extern ABC_DLL int Abc_FrameReadBmcFrames( Abc_Frame_t * p ); extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * p ); -extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * p ); +extern ABC_DLL Abc_Cex_t * Abc_FrameReadCex( Abc_Frame_t * p ); extern ABC_DLL int Abc_FrameReadCexPiNum( Abc_Frame_t * p ); extern ABC_DLL int Abc_FrameReadCexRegNum( Abc_Frame_t * p ); @@ -123,6 +123,8 @@ extern ABC_DLL void Abc_FrameSetLibGen2( void * pLib ); extern ABC_DLL void Abc_FrameSetLibSuper( void * pLib ); extern ABC_DLL void Abc_FrameSetLibVer( void * pLib ); extern ABC_DLL void Abc_FrameSetFlag( char * pFlag, char * pValue ); +extern ABC_DLL void Abc_FrameSetCex( Abc_Cex_t * pCex ); + diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index bd3cf4d2..cd743977 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -60,7 +60,7 @@ char * Abc_FrameReadFlag( char * pFlag ) { return Cmd_FlagRe int Abc_FrameReadBmcFrames( Abc_Frame_t * p ) { return s_GlobalFrame->nFrames; } int Abc_FrameReadProbStatus( Abc_Frame_t * p ) { return s_GlobalFrame->Status; } -void * Abc_FrameReadCex( Abc_Frame_t * p ) { return s_GlobalFrame->pCex; } +Abc_Cex_t * Abc_FrameReadCex( Abc_Frame_t * p ) { return s_GlobalFrame->pCex; } int Abc_FrameReadCexPiNum( Abc_Frame_t * p ) { return s_GlobalFrame->pCex->nPis; } int Abc_FrameReadCexRegNum( Abc_Frame_t * p ) { return s_GlobalFrame->pCex->nRegs; } @@ -72,7 +72,8 @@ void Abc_FrameSetLibGen( void * pLib ) { s_GlobalFrame->pL void Abc_FrameSetLibGen2( void * pLib ) { s_GlobalFrame->pLibGen2 = pLib; } void Abc_FrameSetLibSuper( void * pLib ) { s_GlobalFrame->pLibSuper = pLib; } void Abc_FrameSetLibVer( void * pLib ) { s_GlobalFrame->pLibVer = pLib; } -void Abc_FrameSetFlag( char * pFlag, char * pValue ) { Cmd_FlagUpdateValue( s_GlobalFrame, pFlag, pValue ); } +void Abc_FrameSetFlag( char * pFlag, char * pValue ) { Cmd_FlagUpdateValue( s_GlobalFrame, pFlag, pValue ); } +void Abc_FrameSetCex( Abc_Cex_t * pCex ) { ABC_FREE( s_GlobalFrame->pCex ); s_GlobalFrame->pCex = pCex; } /**Function************************************************************* diff --git a/src/base/ver/ver.h b/src/base/ver/ver.h index ab679664..e421ff95 100644 --- a/src/base/ver/ver.h +++ b/src/base/ver/ver.h @@ -28,6 +28,7 @@ #include <stdio.h> #include "abc.h" +#include "extra.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// diff --git a/src/bdd/cudd/Makefile b/src/bdd/cudd/Makefile new file mode 100644 index 00000000..d7695474 --- /dev/null +++ b/src/bdd/cudd/Makefile @@ -0,0 +1,124 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +XCFLAGS = -DDD_STATS +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +#DDDEBUG = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \ + $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \ + $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = cudd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \ + cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \ + cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c \ + cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +PHDR = cudd.h cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/src/bdd/cudd/cudd.h b/src/bdd/cudd/cudd.h index 658e4eaf..c72edbb0 100644 --- a/src/bdd/cudd/cudd.h +++ b/src/bdd/cudd/cudd.h @@ -7,23 +7,50 @@ Synopsis [The University of Colorado decision diagram package.] Description [External functions and data strucures of the CUDD package. - <ul> - <li> To turn on the gathering of statistics, define DD_STATS. - <li> To link with mis, define DD_MIS. - </ul> - Modified by Abelardo Pardo to interface it to VIS. + <ul> + <li> To turn on the gathering of statistics, define DD_STATS. + <li> To link with mis, define DD_MIS. + </ul> + Modified by Abelardo Pardo to interface it to VIS. ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - Revision [$Id: cudd.h,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $] + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cudd.h,v 1.174 2009/02/21 05:55:18 fabio Exp $] ******************************************************************************/ @@ -45,7 +72,7 @@ ABC_NAMESPACE_HEADER_START /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define CUDD_VERSION "2.3.1" +#define CUDD_VERSION "2.4.2" #ifndef SIZEOF_VOID_P #define SIZEOF_VOID_P 4 @@ -64,40 +91,46 @@ ABC_NAMESPACE_HEADER_START #define FALSE 0 #endif -#define CUDD_VALUE_TYPE double -#define CUDD_OUT_OF_MEM -1 +#define CUDD_VALUE_TYPE double +#define CUDD_OUT_OF_MEM -1 /* The sizes of the subtables and the cache must be powers of two. */ -#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ -#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ +#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ +#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ /* Constants for residue functions. */ #define CUDD_RESIDUE_DEFAULT 0 -#define CUDD_RESIDUE_MSB 1 -#define CUDD_RESIDUE_TC 2 +#define CUDD_RESIDUE_MSB 1 +#define CUDD_RESIDUE_TC 2 /* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit ** machines one can cast an index to (int) without generating a negative ** number. */ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 -#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) +#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) #else -#define CUDD_MAXINDEX ((DdHalfWord) ~0) +#define CUDD_MAXINDEX ((DdHalfWord) ~0) #endif /* CUDD_CONST_INDEX is the index of constant nodes. Currently this ** is a synonim for CUDD_MAXINDEX. */ -#define CUDD_CONST_INDEX CUDD_MAXINDEX +#define CUDD_CONST_INDEX CUDD_MAXINDEX /* These constants define the digits used in the representation of -** arbitrary precision integers. The two configurations tested use 8 -** and 16 bits for each digit. The typedefs should be in agreement +** arbitrary precision integers. The configurations tested use 8, 16, +** and 32 bits for each digit. The typedefs should be in agreement ** with these definitions. */ -#define DD_APA_BITS 16 -#define DD_APA_BASE (1 << DD_APA_BITS) -#define DD_APA_MASK (DD_APA_BASE - 1) -#define DD_APA_HEXPRINT "%04x" +#if SIZEOF_LONG == 8 +#define DD_APA_BITS 32 +#define DD_APA_BASE (1L << DD_APA_BITS) +#define DD_APA_HEXPRINT "%08x" +#else +#define DD_APA_BITS 16 +#define DD_APA_BASE (1 << DD_APA_BITS) +#define DD_APA_HEXPRINT "%04x" +#endif +#define DD_APA_MASK (DD_APA_BASE - 1) /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -244,11 +277,11 @@ typedef struct DdChildren { /* The DdNode structure is the only one exported out of the package */ struct DdNode { DdHalfWord index; - DdHalfWord ref; /* reference count */ - DdNode *next; /* next pointer for unique table */ + DdHalfWord ref; /* reference count */ + DdNode *next; /* next pointer for unique table */ union { - CUDD_VALUE_TYPE value; /* for constant nodes */ - DdChildren kids; /* for internal nodes */ + CUDD_VALUE_TYPE value; /* for constant nodes */ + DdChildren kids; /* for internal nodes */ } type; }; @@ -262,10 +295,35 @@ typedef struct DdGen DdGen; /* These typedefs for arbitrary precision arithmetic should agree with ** the corresponding constant definitions above. */ -typedef unsigned short int DdApaDigit; +#if SIZEOF_LONG == 8 +typedef unsigned int DdApaDigit; typedef unsigned long int DdApaDoubleDigit; +#else +typedef unsigned short int DdApaDigit; +typedef unsigned int DdApaDoubleDigit; +#endif typedef DdApaDigit * DdApaNumber; +/* Return type for function computing two-literal clauses. */ +typedef struct DdTlcInfo DdTlcInfo; + +/* Type of hook function. */ +typedef int (*DD_HFP)(DdManager *, const char *, void *); +/* Type of priority function */ +typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **, + DdNode **); +/* Type of apply operator. */ +typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **); +/* Type of monadic apply operator. */ +typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *); +/* Types of cache tag functions. */ +typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *); +typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *); +/* Type of memory-out function. */ +typedef void (*DD_OOMFP)(long); +/* Type of comparison function for qsort. */ +typedef int (*DD_QSFP)(const void *, const void *); + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ @@ -363,7 +421,7 @@ typedef DdApaDigit * DdApaNumber; SeeAlso [Cudd_Regular Cudd_Complement] ******************************************************************************/ -#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) +#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) /**Macro*********************************************************************** @@ -459,8 +517,40 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_ForeachCube(manager, f, gen, cube, value)\ for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_NextCube(gen, &cube, &value)) + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextCube(gen, &cube, &value)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the primes of a Boolean function.] + + Description [Iterates over the primes of a Boolean function producing + a prime and irredundant cover. + <ul> + <li> DdManager *manager; + <li> DdNode *l; + <li> DdNode *u; + <li> DdGen *gen; + <li> int *cube; + </ul> + The Boolean function is described by an upper bound and a lower bound. If + the function is completely specified, the two bounds coincide. + Cudd_ForeachPrime allocates and frees the generator. Therefore the + application should not try to do that. Also, the cube is freed at the + end of Cudd_ForeachPrime and hence is not available outside of the loop.<p> + CAUTION: It is a mistake to change a diagram on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +#define Cudd_ForeachPrime(manager, l, u, gen, cube)\ + for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextPrime(gen, &cube)) /**Macro*********************************************************************** @@ -493,8 +583,8 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_ForeachNode(manager, f, gen, node)\ for((gen) = Cudd_FirstNode(manager, f, &node);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_NextNode(gen, &node)) + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextNode(gen, &node)) /**Macro*********************************************************************** @@ -527,26 +617,10 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_zddForeachPath(manager, f, gen, path)\ for((gen) = Cudd_zddFirstPath(manager, f, &path);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_zddNextPath(gen, &path)) - - -/* These are potential duplicates. */ -#ifndef EXTERN -# ifdef __cplusplus -# ifdef ABC_NAMESPACE -# define EXTERN extern -# else -# define EXTERN extern "C" -# endif -# else -# define EXTERN extern -# endif -#endif + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_zddNextPath(gen, &path)) + -#ifndef ARGS -#define ARGS(protos) protos -#endif /**AutomaticStart*************************************************************/ @@ -554,410 +628,421 @@ typedef DdApaDigit * DdApaNumber; /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EXTERN DdNode * Cudd_addNewVar ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_addNewVarAtLevel ARGS((DdManager *dd, int level)); -EXTERN DdNode * Cudd_bddNewVar ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_bddNewVarAtLevel ARGS((DdManager *dd, int level)); -EXTERN DdNode * Cudd_addIthVar ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_bddIthVar ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_zddIthVar ARGS((DdManager *dd, int i)); -EXTERN int Cudd_zddVarsFromBddVars ARGS((DdManager *dd, int multiplicity)); -EXTERN DdNode * Cudd_addConst ARGS((DdManager *dd, CUDD_VALUE_TYPE c)); -EXTERN int Cudd_IsNonConstant ARGS((DdNode *f)); -EXTERN void Cudd_AutodynEnable ARGS((DdManager *unique, Cudd_ReorderingType method)); -EXTERN void Cudd_AutodynDisable ARGS((DdManager *unique)); -EXTERN int Cudd_ReorderingStatus ARGS((DdManager *unique, Cudd_ReorderingType *method)); -EXTERN void Cudd_AutodynEnableZdd ARGS((DdManager *unique, Cudd_ReorderingType method)); -EXTERN void Cudd_AutodynDisableZdd ARGS((DdManager *unique)); -EXTERN int Cudd_ReorderingStatusZdd ARGS((DdManager *unique, Cudd_ReorderingType *method)); -EXTERN int Cudd_zddRealignmentEnabled ARGS((DdManager *unique)); -EXTERN void Cudd_zddRealignEnable ARGS((DdManager *unique)); -EXTERN void Cudd_zddRealignDisable ARGS((DdManager *unique)); -EXTERN int Cudd_bddRealignmentEnabled ARGS((DdManager *unique)); -EXTERN void Cudd_bddRealignEnable ARGS((DdManager *unique)); -EXTERN void Cudd_bddRealignDisable ARGS((DdManager *unique)); -EXTERN DdNode * Cudd_ReadOne ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadZddOne ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_ReadZero ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadLogicZero ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadPlusInfinity ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadMinusInfinity ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadBackground ARGS((DdManager *dd)); -EXTERN void Cudd_SetBackground ARGS((DdManager *dd, DdNode *bck)); -EXTERN unsigned int Cudd_ReadCacheSlots ARGS((DdManager *dd)); -EXTERN double Cudd_ReadCacheUsedSlots ARGS((DdManager * dd)); -EXTERN double Cudd_ReadCacheLookUps ARGS((DdManager *dd)); -EXTERN double Cudd_ReadCacheHits ARGS((DdManager *dd)); -EXTERN double Cudd_ReadRecursiveCalls ARGS ((DdManager * dd)); -EXTERN unsigned int Cudd_ReadMinHit ARGS((DdManager *dd)); -EXTERN void Cudd_SetMinHit ARGS((DdManager *dd, unsigned int hr)); -EXTERN unsigned int Cudd_ReadLooseUpTo ARGS((DdManager *dd)); -EXTERN void Cudd_SetLooseUpTo ARGS((DdManager *dd, unsigned int lut)); -EXTERN unsigned int Cudd_ReadMaxCache ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMaxCacheHard ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxCacheHard ARGS((DdManager *dd, unsigned int mc)); -EXTERN int Cudd_ReadSize ARGS((DdManager *dd)); -EXTERN int Cudd_ReadZddSize ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadSlots ARGS((DdManager *dd)); -EXTERN double Cudd_ReadUsedSlots ARGS((DdManager * dd)); -EXTERN double Cudd_ExpectedUsedSlots ARGS((DdManager * dd)); -EXTERN unsigned int Cudd_ReadKeys ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadDead ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMinDead ARGS((DdManager *dd)); -EXTERN int Cudd_ReadReorderings ARGS((DdManager *dd)); -EXTERN long Cudd_ReadReorderingTime ARGS((DdManager * dd)); -EXTERN int Cudd_ReadGarbageCollections ARGS((DdManager * dd)); -EXTERN long Cudd_ReadGarbageCollectionTime ARGS((DdManager * dd)); -EXTERN double Cudd_ReadNodesFreed ARGS((DdManager * dd)); -EXTERN double Cudd_ReadNodesDropped ARGS((DdManager * dd)); -EXTERN double Cudd_ReadUniqueLookUps ARGS((DdManager * dd)); -EXTERN double Cudd_ReadUniqueLinks ARGS((DdManager * dd)); -EXTERN int Cudd_ReadSiftMaxVar ARGS((DdManager *dd)); -EXTERN void Cudd_SetSiftMaxVar ARGS((DdManager *dd, int smv)); -EXTERN int Cudd_ReadSiftMaxSwap ARGS((DdManager *dd)); -EXTERN void Cudd_SetSiftMaxSwap ARGS((DdManager *dd, int sms)); -EXTERN double Cudd_ReadMaxGrowth ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxGrowth ARGS((DdManager *dd, double mg)); -EXTERN double Cudd_ReadMaxGrowthAlternate ARGS((DdManager * dd)); -EXTERN void Cudd_SetMaxGrowthAlternate ARGS((DdManager * dd, double mg)); -EXTERN int Cudd_ReadReorderingCycle ARGS((DdManager * dd)); -EXTERN void Cudd_SetReorderingCycle ARGS((DdManager * dd, int cycle)); -EXTERN MtrNode * Cudd_ReadTree ARGS((DdManager *dd)); -EXTERN void Cudd_SetTree ARGS((DdManager *dd, MtrNode *tree)); -EXTERN void Cudd_FreeTree ARGS((DdManager *dd)); -EXTERN MtrNode * Cudd_ReadZddTree ARGS((DdManager *dd)); -EXTERN void Cudd_SetZddTree ARGS((DdManager *dd, MtrNode *tree)); -EXTERN void Cudd_FreeZddTree ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_NodeReadIndex ARGS((DdNode *node)); -EXTERN int Cudd_ReadPerm ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadPermZdd ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadInvPerm ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadInvPermZdd ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_ReadVars ARGS((DdManager *dd, int i)); -EXTERN CUDD_VALUE_TYPE Cudd_ReadEpsilon ARGS((DdManager *dd)); -EXTERN void Cudd_SetEpsilon ARGS((DdManager *dd, CUDD_VALUE_TYPE ep)); -EXTERN Cudd_AggregationType Cudd_ReadGroupcheck ARGS((DdManager *dd)); -EXTERN void Cudd_SetGroupcheck ARGS((DdManager *dd, Cudd_AggregationType gc)); -EXTERN int Cudd_GarbageCollectionEnabled ARGS((DdManager *dd)); -EXTERN void Cudd_EnableGarbageCollection ARGS((DdManager *dd)); -EXTERN void Cudd_DisableGarbageCollection ARGS((DdManager *dd)); -EXTERN int Cudd_DeadAreCounted ARGS((DdManager *dd)); -EXTERN void Cudd_TurnOnCountDead ARGS((DdManager *dd)); -EXTERN void Cudd_TurnOffCountDead ARGS((DdManager *dd)); -EXTERN int Cudd_ReadRecomb ARGS((DdManager *dd)); -EXTERN void Cudd_SetRecomb ARGS((DdManager *dd, int recomb)); -EXTERN int Cudd_ReadSymmviolation ARGS((DdManager *dd)); -EXTERN void Cudd_SetSymmviolation ARGS((DdManager *dd, int symmviolation)); -EXTERN int Cudd_ReadArcviolation ARGS((DdManager *dd)); -EXTERN void Cudd_SetArcviolation ARGS((DdManager *dd, int arcviolation)); -EXTERN int Cudd_ReadPopulationSize ARGS((DdManager *dd)); -EXTERN void Cudd_SetPopulationSize ARGS((DdManager *dd, int populationSize)); -EXTERN int Cudd_ReadNumberXovers ARGS((DdManager *dd)); -EXTERN void Cudd_SetNumberXovers ARGS((DdManager *dd, int numberXovers)); -EXTERN long Cudd_ReadMemoryInUse ARGS((DdManager *dd)); -EXTERN int Cudd_PrintInfo ARGS((DdManager *dd, FILE *fp)); -EXTERN long Cudd_ReadPeakNodeCount ARGS((DdManager *dd)); -EXTERN int Cudd_ReadPeakLiveNodeCount ARGS((DdManager * dd)); -EXTERN long Cudd_ReadNodeCount ARGS((DdManager *dd)); -EXTERN long Cudd_zddReadNodeCount ARGS((DdManager *dd)); -EXTERN int Cudd_AddHook ARGS((DdManager *dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_RemoveHook ARGS((DdManager *dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_IsInHook ARGS((DdManager * dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_StdPreReordHook ARGS((DdManager *dd, char *str, void *data)); -EXTERN int Cudd_StdPostReordHook ARGS((DdManager *dd, char *str, void *data)); -EXTERN int Cudd_EnableReorderingReporting ARGS((DdManager *dd)); -EXTERN int Cudd_DisableReorderingReporting ARGS((DdManager *dd)); -EXTERN int Cudd_ReorderingReporting ARGS((DdManager *dd)); -EXTERN Cudd_ErrorType Cudd_ReadErrorCode ARGS((DdManager *dd)); -EXTERN void Cudd_ClearErrorCode ARGS((DdManager *dd)); -EXTERN FILE * Cudd_ReadStdout ARGS((DdManager *dd)); -EXTERN void Cudd_SetStdout ARGS((DdManager *dd, FILE *fp)); -EXTERN FILE * Cudd_ReadStderr ARGS((DdManager *dd)); -EXTERN void Cudd_SetStderr ARGS((DdManager *dd, FILE *fp)); -EXTERN unsigned int Cudd_ReadNextReordering ARGS((DdManager *dd)); -EXTERN void Cudd_SetNextReordering ARGS((DdManager *dd, unsigned int next)); -EXTERN double Cudd_ReadSwapSteps ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMaxLive ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxLive ARGS((DdManager *dd, unsigned int maxLive)); -EXTERN long Cudd_ReadMaxMemory ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxMemory ARGS((DdManager *dd, long maxMemory)); -EXTERN int Cudd_bddBindVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddUnbindVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddVarIsBound ARGS((DdManager *dd, int index)); -EXTERN DdNode * Cudd_addExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addUnivAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addOrAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addApply ARGS((DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addPlus ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addTimes ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addThreshold ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addSetNZ ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addDivide ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMinus ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMinimum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMaximum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addOneZeroMaximum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addDiff ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addAgreement ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addOr ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addNand ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addNor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addXor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addXnor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMonadicApply ARGS((DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f)); -EXTERN DdNode * Cudd_addLog ARGS((DdManager * dd, DdNode * f)); -EXTERN DdNode * Cudd_addFindMax ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addFindMin ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addIthBit ARGS((DdManager *dd, DdNode *f, int bit)); -EXTERN DdNode * Cudd_addScalarInverse ARGS((DdManager *dd, DdNode *f, DdNode *epsilon)); -EXTERN DdNode * Cudd_addIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_addIteConstant ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_addEvalConst ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int Cudd_addLeq ARGS((DdManager * dd, DdNode * f, DdNode * g)); -EXTERN DdNode * Cudd_addCmpl ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addNegate ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addRoundOff ARGS((DdManager *dd, DdNode *f, int N)); -EXTERN DdNode * Cudd_addWalsh ARGS((DdManager *dd, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_addResidue ARGS((DdManager *dd, int n, int m, int options, int top)); -EXTERN DdNode * Cudd_bddAndAbstract ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * Cudd_bddAndAbstractLimit ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit)); -EXTERN int Cudd_ApaNumberOfDigits ARGS((int binaryDigits)); -EXTERN DdApaNumber Cudd_NewApaNumber ARGS((int digits)); -EXTERN void Cudd_ApaCopy ARGS((int digits, DdApaNumber source, DdApaNumber dest)); -EXTERN DdApaDigit Cudd_ApaAdd ARGS((int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum)); -EXTERN DdApaDigit Cudd_ApaSubtract ARGS((int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff)); -EXTERN DdApaDigit Cudd_ApaShortDivision ARGS((int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient)); -EXTERN unsigned int Cudd_ApaIntDivision ARGS((int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient)); -EXTERN void Cudd_ApaShiftRight ARGS((int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b)); -EXTERN void Cudd_ApaSetToLiteral ARGS((int digits, DdApaNumber number, DdApaDigit literal)); -EXTERN void Cudd_ApaPowerOfTwo ARGS((int digits, DdApaNumber number, int power)); -EXTERN int Cudd_ApaCompare ARGS((int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second)); -EXTERN int Cudd_ApaCompareRatios ARGS ((int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen)); -EXTERN int Cudd_ApaPrintHex ARGS((FILE *fp, int digits, DdApaNumber number)); -EXTERN int Cudd_ApaPrintDecimal ARGS((FILE *fp, int digits, DdApaNumber number)); -EXTERN int Cudd_ApaPrintExponential ARGS((FILE * fp, int digits, DdApaNumber number, int precision)); -EXTERN DdApaNumber Cudd_ApaCountMinterm ARGS((DdManager *manager, DdNode *node, int nvars, int *digits)); -EXTERN int Cudd_ApaPrintMinterm ARGS((FILE *fp, DdManager *dd, DdNode *node, int nvars)); -EXTERN int Cudd_ApaPrintMintermExp ARGS((FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision)); -EXTERN int Cudd_ApaPrintDensity ARGS((FILE * fp, DdManager * dd, DdNode * node, int nvars)); -EXTERN DdNode * Cudd_UnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * Cudd_OverApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * Cudd_RemapUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * Cudd_RemapOverApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * Cudd_BiasedUnderApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * Cudd_BiasedOverApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * Cudd_bddExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_bddXorExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * Cudd_bddUnivAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_bddBooleanDiff ARGS((DdManager *manager, DdNode *f, int x)); -EXTERN int Cudd_bddVarIsDependent ARGS((DdManager *dd, DdNode *f, DdNode *var)); -EXTERN double Cudd_bddCorrelation ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN double Cudd_bddCorrelationWeights ARGS((DdManager *manager, DdNode *f, DdNode *g, double *prob)); -EXTERN DdNode * Cudd_bddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_bddIteConstant ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_bddIntersect ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddAnd ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddOr ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddNand ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddNor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddXor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddXnor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int Cudd_bddLeq ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addBddThreshold ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)); -EXTERN DdNode * Cudd_addBddStrictThreshold ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)); -EXTERN DdNode * Cudd_addBddInterval ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper)); -EXTERN DdNode * Cudd_addBddIthBit ARGS((DdManager *dd, DdNode *f, int bit)); -EXTERN DdNode * Cudd_BddToAdd ARGS((DdManager *dd, DdNode *B)); -EXTERN DdNode * Cudd_addBddPattern ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_bddTransfer ARGS((DdManager *ddSource, DdManager *ddDestination, DdNode *f)); -EXTERN int Cudd_DebugCheck ARGS((DdManager *table)); -EXTERN int Cudd_CheckKeys ARGS((DdManager *table)); -EXTERN DdNode * Cudd_bddClippingAnd ARGS((DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)); -EXTERN DdNode * Cudd_bddClippingAndAbstract ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)); -EXTERN DdNode * Cudd_Cofactor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddCompose ARGS((DdManager *dd, DdNode *f, DdNode *g, int v)); -EXTERN DdNode * Cudd_addCompose ARGS((DdManager *dd, DdNode *f, DdNode *g, int v)); -EXTERN DdNode * Cudd_addPermute ARGS((DdManager *manager, DdNode *node, int *permut)); -EXTERN DdNode * Cudd_addSwapVariables ARGS((DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddPermute ARGS((DdManager *manager, DdNode *node, int *permut)); -EXTERN DdNode * Cudd_bddVarMap ARGS((DdManager *manager, DdNode *f)); -EXTERN int Cudd_SetVarMap ARGS((DdManager *manager, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddSwapVariables ARGS((DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddAdjPermuteX ARGS((DdManager *dd, DdNode *B, DdNode **x, int n)); -EXTERN DdNode * Cudd_addVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN DdNode * Cudd_addGeneralVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff)); -EXTERN DdNode * Cudd_addNonSimCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN DdNode * Cudd_bddVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN int Cudd_bddApproxConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddApproxDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddIterConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddIterDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddGenConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddGenDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddVarConjDecomp ARGS((DdManager *dd, DdNode * f, DdNode ***conjuncts)); -EXTERN int Cudd_bddVarDisjDecomp ARGS((DdManager *dd, DdNode * f, DdNode ***disjuncts)); -EXTERN DdNode * Cudd_FindEssential ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_bddIsVarEssential ARGS((DdManager *manager, DdNode *f, int id, int phase)); -EXTERN int Cudd_DumpBlif ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp)); -EXTERN int Cudd_DumpBlifBody ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDot ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDaVinci ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDDcal ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpFactoredForm ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN DdNode * Cudd_bddConstrain ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_bddRestrict ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_addConstrain ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode ** Cudd_bddConstrainDecomp ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addRestrict ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode ** Cudd_bddCharToVect ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_bddLICompaction ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_bddSqueeze ARGS((DdManager *dd, DdNode *l, DdNode *u)); -EXTERN DdNode * Cudd_bddMinimize ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_SubsetCompress ARGS((DdManager *dd, DdNode *f, int nvars, int threshold)); -EXTERN DdNode * Cudd_SupersetCompress ARGS((DdManager *dd, DdNode *f, int nvars, int threshold)); -EXTERN MtrNode * Cudd_MakeTreeNode ARGS((DdManager *dd, unsigned int low, unsigned int size, unsigned int type)); -EXTERN int Cudd_addHarwell ARGS((FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr)); -EXTERN DdManager * Cudd_Init ARGS((unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)); -EXTERN void Cudd_Quit ARGS((DdManager *unique)); -EXTERN int Cudd_PrintLinear ARGS((DdManager *table)); -EXTERN int Cudd_ReadLinear ARGS((DdManager *table, int x, int y)); -EXTERN DdNode * Cudd_bddLiteralSetIntersection ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addMatrixMultiply ARGS((DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addTimesPlus ARGS((DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addTriangle ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addOuterSum ARGS((DdManager *dd, DdNode *M, DdNode *r, DdNode *c)); -EXTERN DdNode * Cudd_PrioritySelect ARGS((DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **))); -EXTERN DdNode * Cudd_Xgty ARGS((DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_Xeqy ARGS((DdManager *dd, int N, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_addXeqy ARGS((DdManager *dd, int N, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_Dxygtdxz ARGS((DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)); -EXTERN DdNode * Cudd_Dxygtdyz ARGS((DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)); -EXTERN DdNode * Cudd_CProjection ARGS((DdManager *dd, DdNode *R, DdNode *Y)); -EXTERN DdNode * Cudd_addHamming ARGS((DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars)); -EXTERN int Cudd_MinHammingDist ARGS((DdManager *dd, DdNode *f, int *minterm, int upperBound)); -EXTERN DdNode * Cudd_bddClosestCube ARGS((DdManager *dd, DdNode * f, DdNode *g, int *distance)); -EXTERN int Cudd_addRead ARGS((FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy)); -EXTERN int Cudd_bddRead ARGS((FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy)); -EXTERN void Cudd_Ref ARGS((DdNode *n)); -EXTERN void Cudd_RecursiveDeref ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_IterDerefBdd ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_DelayedDerefBdd ARGS((DdManager * table, DdNode * n)); -EXTERN void Cudd_RecursiveDerefZdd ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_Deref ARGS((DdNode *node)); -EXTERN int Cudd_CheckZeroRef ARGS((DdManager *manager)); -EXTERN int Cudd_ReduceHeap ARGS((DdManager *table, Cudd_ReorderingType heuristic, int minsize)); -EXTERN int Cudd_ShuffleHeap ARGS((DdManager *table, int *permutation)); -EXTERN DdNode * Cudd_Eval ARGS((DdManager *dd, DdNode *f, int *inputs)); -EXTERN DdNode * Cudd_ShortestPath ARGS((DdManager *manager, DdNode *f, int *weight, int *support, int *length)); -EXTERN DdNode * Cudd_LargestCube ARGS((DdManager *manager, DdNode *f, int *length)); -EXTERN int Cudd_ShortestLength ARGS((DdManager *manager, DdNode *f, int *weight)); -EXTERN DdNode * Cudd_Decreasing ARGS((DdManager *dd, DdNode *f, int i)); -EXTERN DdNode * Cudd_Increasing ARGS((DdManager *dd, DdNode *f, int i)); -EXTERN int Cudd_EquivDC ARGS((DdManager *dd, DdNode *F, DdNode *G, DdNode *D)); -EXTERN int Cudd_bddLeqUnless ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *D)); -EXTERN int Cudd_EqualSupNorm ARGS((DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)); -EXTERN DdNode * Cudd_bddMakePrime ARGS ((DdManager *dd, DdNode *cube, DdNode *f)); -EXTERN double * Cudd_CofMinterm ARGS((DdManager *dd, DdNode *node)); -EXTERN DdNode * Cudd_SolveEqn ARGS((DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n)); -EXTERN DdNode * Cudd_VerifySol ARGS((DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n)); -EXTERN DdNode * Cudd_SplitSet ARGS((DdManager *manager, DdNode *S, DdNode **xVars, int n, double m)); -EXTERN DdNode * Cudd_SubsetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * Cudd_SupersetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * Cudd_SubsetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN DdNode * Cudd_SupersetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN void Cudd_SymmProfile ARGS((DdManager *table, int lower, int upper)); -EXTERN unsigned int Cudd_Prime ARGS((unsigned int p)); -EXTERN int Cudd_PrintMinterm ARGS((DdManager *manager, DdNode *node)); -EXTERN int Cudd_bddPrintCover ARGS((DdManager *dd, DdNode *l, DdNode *u)); -EXTERN int Cudd_PrintDebug ARGS((DdManager *dd, DdNode *f, int n, int pr)); -EXTERN int Cudd_DagSize ARGS((DdNode *node)); -EXTERN int Cudd_EstimateCofactor ARGS((DdManager *dd, DdNode * node, int i, int phase)); -EXTERN int Cudd_EstimateCofactorSimple ARGS((DdNode * node, int i)); -EXTERN int Cudd_SharingSize ARGS((DdNode **nodeArray, int n)); -EXTERN double Cudd_CountMinterm ARGS((DdManager *manager, DdNode *node, int nvars)); -EXTERN int Cudd_EpdCountMinterm ARGS((DdManager *manager, DdNode *node, int nvars, EpDouble *epd)); -EXTERN double Cudd_CountPath ARGS((DdNode *node)); -EXTERN double Cudd_CountPathsToNonZero ARGS((DdNode *node)); -EXTERN DdNode * Cudd_Support ARGS((DdManager *dd, DdNode *f)); -EXTERN int * Cudd_SupportIndex ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_SupportSize ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_VectorSupport ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int * Cudd_VectorSupportIndex ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int Cudd_VectorSupportSize ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int Cudd_ClassifySupport ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)); -EXTERN int Cudd_CountLeaves ARGS((DdNode *node)); -EXTERN int Cudd_bddPickOneCube ARGS((DdManager *ddm, DdNode *node, char *string)); -EXTERN DdNode * Cudd_bddPickOneMinterm ARGS((DdManager *dd, DdNode *f, DdNode **vars, int n)); -EXTERN DdNode ** Cudd_bddPickArbitraryMinterms ARGS((DdManager *dd, DdNode *f, DdNode **vars, int n, int k)); -EXTERN DdNode * Cudd_SubsetWithMaskVars ARGS((DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)); -EXTERN DdGen * Cudd_FirstCube ARGS((DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)); -EXTERN int Cudd_NextCube ARGS((DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)); -EXTERN DdNode * Cudd_bddComputeCube ARGS((DdManager *dd, DdNode **vars, int *phase, int n)); -EXTERN DdNode * Cudd_addComputeCube ARGS((DdManager *dd, DdNode **vars, int *phase, int n)); -EXTERN DdNode * Cudd_CubeArrayToBdd ARGS((DdManager *dd, int *array)); -EXTERN int Cudd_BddToCubeArray ARGS((DdManager *dd, DdNode *cube, int *array)); -EXTERN DdGen * Cudd_FirstNode ARGS((DdManager *dd, DdNode *f, DdNode **node)); -EXTERN int Cudd_NextNode ARGS((DdGen *gen, DdNode **node)); -EXTERN int Cudd_GenFree ARGS((DdGen *gen)); -EXTERN int Cudd_IsGenEmpty ARGS((DdGen *gen)); -EXTERN DdNode * Cudd_IndicesToCube ARGS((DdManager *dd, int *array, int n)); -EXTERN void Cudd_PrintVersion ARGS((FILE *fp)); -EXTERN double Cudd_AverageDistance ARGS((DdManager *dd)); -EXTERN long Cudd_Random ARGS(()); -EXTERN void Cudd_Srandom ARGS((long seed)); -EXTERN double Cudd_Density ARGS((DdManager *dd, DdNode *f, int nvars)); -EXTERN void Cudd_OutOfMem ARGS((long size)); -EXTERN int Cudd_zddCount ARGS((DdManager *zdd, DdNode *P)); -EXTERN double Cudd_zddCountDouble ARGS((DdManager *zdd, DdNode *P)); -EXTERN DdNode * Cudd_zddProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddUnateProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddWeakDiv ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddDivide ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddWeakDivF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddDivideF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddComplement ARGS((DdManager *dd, DdNode *node)); -EXTERN MtrNode * Cudd_MakeZddTreeNode ARGS((DdManager *dd, unsigned int low, unsigned int size, unsigned int type)); -EXTERN DdNode * Cudd_zddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)); -EXTERN DdNode * Cudd_bddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U)); -EXTERN DdNode * Cudd_MakeBddFromZddCover ARGS((DdManager *dd, DdNode *node)); -EXTERN int Cudd_zddDagSize ARGS((DdNode *p_node)); -EXTERN double Cudd_zddCountMinterm ARGS((DdManager *zdd, DdNode *node, int path)); -EXTERN void Cudd_zddPrintSubtable ARGS((DdManager *table)); -EXTERN DdNode * Cudd_zddPortFromBdd ARGS((DdManager *dd, DdNode *B)); -EXTERN DdNode * Cudd_zddPortToBdd ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_zddReduceHeap ARGS((DdManager *table, Cudd_ReorderingType heuristic, int minsize)); -EXTERN int Cudd_zddShuffleHeap ARGS((DdManager *table, int *permutation)); -EXTERN DdNode * Cudd_zddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_zddUnion ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddIntersect ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddDiff ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddDiffConst ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddSubset1 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * Cudd_zddSubset0 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * Cudd_zddChange ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN void Cudd_zddSymmProfile ARGS((DdManager *table, int lower, int upper)); -EXTERN int Cudd_zddPrintMinterm ARGS((DdManager *zdd, DdNode *node)); -EXTERN int Cudd_zddPrintCover ARGS((DdManager *zdd, DdNode *node)); -EXTERN int Cudd_zddPrintDebug ARGS((DdManager *zdd, DdNode *f, int n, int pr)); -EXTERN DdGen * Cudd_zddFirstPath ARGS((DdManager *zdd, DdNode *f, int **path)); -EXTERN int Cudd_zddNextPath ARGS((DdGen *gen, int **path)); -EXTERN char * Cudd_zddCoverPathToString ARGS((DdManager *zdd, int *path, char *str)); -EXTERN int Cudd_zddDumpDot ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_bddSetPiVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetPsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetNsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsPiVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsPsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsNsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetPairIndex ARGS((DdManager *dd, int index, int pairIndex)); -EXTERN int Cudd_bddReadPairIndex ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarHardGroup ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddResetVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarToBeUngrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarToBeUngrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarHardGroup ARGS((DdManager *dd, int index)); +extern DdNode * Cudd_addNewVar( DdManager * dd ); +extern DdNode * Cudd_addNewVarAtLevel( DdManager * dd, int level ); +extern DdNode * Cudd_bddNewVar( DdManager * dd ); +extern DdNode * Cudd_bddNewVarAtLevel( DdManager * dd, int level ); +extern DdNode * Cudd_addIthVar( DdManager * dd, int i ); +extern DdNode * Cudd_bddIthVar( DdManager * dd, int i ); +extern DdNode * Cudd_zddIthVar( DdManager * dd, int i ); +extern int Cudd_zddVarsFromBddVars( DdManager * dd, int multiplicity ); +extern DdNode * Cudd_addConst( DdManager * dd, CUDD_VALUE_TYPE c ); +extern int Cudd_IsNonConstant( DdNode * f ); +extern void Cudd_AutodynEnable( DdManager * unique, Cudd_ReorderingType method ); +extern void Cudd_AutodynDisable( DdManager * unique ); +extern int Cudd_ReorderingStatus( DdManager * unique, Cudd_ReorderingType * method ); +extern void Cudd_AutodynEnableZdd( DdManager * unique, Cudd_ReorderingType method ); +extern void Cudd_AutodynDisableZdd( DdManager * unique ); +extern int Cudd_ReorderingStatusZdd( DdManager * unique, Cudd_ReorderingType * method ); +extern int Cudd_zddRealignmentEnabled( DdManager * unique ); +extern void Cudd_zddRealignEnable( DdManager * unique ); +extern void Cudd_zddRealignDisable( DdManager * unique ); +extern int Cudd_bddRealignmentEnabled( DdManager * unique ); +extern void Cudd_bddRealignEnable( DdManager * unique ); +extern void Cudd_bddRealignDisable( DdManager * unique ); +extern DdNode * Cudd_ReadOne( DdManager * dd ); +extern DdNode * Cudd_ReadZddOne( DdManager * dd, int i ); +extern DdNode * Cudd_ReadZero( DdManager * dd ); +extern DdNode * Cudd_ReadLogicZero( DdManager * dd ); +extern DdNode * Cudd_ReadPlusInfinity( DdManager * dd ); +extern DdNode * Cudd_ReadMinusInfinity( DdManager * dd ); +extern DdNode * Cudd_ReadBackground( DdManager * dd ); +extern void Cudd_SetBackground( DdManager * dd, DdNode * bck ); +extern unsigned int Cudd_ReadCacheSlots( DdManager * dd ); +extern double Cudd_ReadCacheUsedSlots( DdManager * dd ); +extern double Cudd_ReadCacheLookUps( DdManager * dd ); +extern double Cudd_ReadCacheHits( DdManager * dd ); +extern double Cudd_ReadRecursiveCalls( DdManager * dd ); +extern unsigned int Cudd_ReadMinHit( DdManager * dd ); +extern void Cudd_SetMinHit( DdManager * dd, unsigned int hr ); +extern unsigned int Cudd_ReadLooseUpTo( DdManager * dd ); +extern void Cudd_SetLooseUpTo( DdManager * dd, unsigned int lut ); +extern unsigned int Cudd_ReadMaxCache( DdManager * dd ); +extern unsigned int Cudd_ReadMaxCacheHard( DdManager * dd ); +extern void Cudd_SetMaxCacheHard( DdManager * dd, unsigned int mc ); +extern int Cudd_ReadSize( DdManager * dd ); +extern int Cudd_ReadZddSize( DdManager * dd ); +extern unsigned int Cudd_ReadSlots( DdManager * dd ); +extern double Cudd_ReadUsedSlots( DdManager * dd ); +extern double Cudd_ExpectedUsedSlots( DdManager * dd ); +extern unsigned int Cudd_ReadKeys( DdManager * dd ); +extern unsigned int Cudd_ReadDead( DdManager * dd ); +extern unsigned int Cudd_ReadMinDead( DdManager * dd ); +extern int Cudd_ReadReorderings( DdManager * dd ); +extern long Cudd_ReadReorderingTime( DdManager * dd ); +extern int Cudd_ReadGarbageCollections( DdManager * dd ); +extern long Cudd_ReadGarbageCollectionTime( DdManager * dd ); +extern double Cudd_ReadNodesFreed( DdManager * dd ); +extern double Cudd_ReadNodesDropped( DdManager * dd ); +extern double Cudd_ReadUniqueLookUps( DdManager * dd ); +extern double Cudd_ReadUniqueLinks( DdManager * dd ); +extern int Cudd_ReadSiftMaxVar( DdManager * dd ); +extern void Cudd_SetSiftMaxVar( DdManager * dd, int smv ); +extern int Cudd_ReadSiftMaxSwap( DdManager * dd ); +extern void Cudd_SetSiftMaxSwap( DdManager * dd, int sms ); +extern double Cudd_ReadMaxGrowth( DdManager * dd ); +extern void Cudd_SetMaxGrowth( DdManager * dd, double mg ); +extern double Cudd_ReadMaxGrowthAlternate( DdManager * dd ); +extern void Cudd_SetMaxGrowthAlternate( DdManager * dd, double mg ); +extern int Cudd_ReadReorderingCycle( DdManager * dd ); +extern void Cudd_SetReorderingCycle( DdManager * dd, int cycle ); +extern MtrNode * Cudd_ReadTree( DdManager * dd ); +extern void Cudd_SetTree( DdManager * dd, MtrNode * tree ); +extern void Cudd_FreeTree( DdManager * dd ); +extern MtrNode * Cudd_ReadZddTree( DdManager * dd ); +extern void Cudd_SetZddTree( DdManager * dd, MtrNode * tree ); +extern void Cudd_FreeZddTree( DdManager * dd ); +extern unsigned int Cudd_NodeReadIndex( DdNode * node ); +extern int Cudd_ReadPerm( DdManager * dd, int i ); +extern int Cudd_ReadPermZdd( DdManager * dd, int i ); +extern int Cudd_ReadInvPerm( DdManager * dd, int i ); +extern int Cudd_ReadInvPermZdd( DdManager * dd, int i ); +extern DdNode * Cudd_ReadVars( DdManager * dd, int i ); +extern CUDD_VALUE_TYPE Cudd_ReadEpsilon( DdManager * dd ); +extern void Cudd_SetEpsilon( DdManager * dd, CUDD_VALUE_TYPE ep ); +extern Cudd_AggregationType Cudd_ReadGroupcheck( DdManager * dd ); +extern void Cudd_SetGroupcheck( DdManager * dd, Cudd_AggregationType gc ); +extern int Cudd_GarbageCollectionEnabled( DdManager * dd ); +extern void Cudd_EnableGarbageCollection( DdManager * dd ); +extern void Cudd_DisableGarbageCollection( DdManager * dd ); +extern int Cudd_DeadAreCounted( DdManager * dd ); +extern void Cudd_TurnOnCountDead( DdManager * dd ); +extern void Cudd_TurnOffCountDead( DdManager * dd ); +extern int Cudd_ReadRecomb( DdManager * dd ); +extern void Cudd_SetRecomb( DdManager * dd, int recomb ); +extern int Cudd_ReadSymmviolation( DdManager * dd ); +extern void Cudd_SetSymmviolation( DdManager * dd, int symmviolation ); +extern int Cudd_ReadArcviolation( DdManager * dd ); +extern void Cudd_SetArcviolation( DdManager * dd, int arcviolation ); +extern int Cudd_ReadPopulationSize( DdManager * dd ); +extern void Cudd_SetPopulationSize( DdManager * dd, int populationSize ); +extern int Cudd_ReadNumberXovers( DdManager * dd ); +extern void Cudd_SetNumberXovers( DdManager * dd, int numberXovers ); +extern unsigned long Cudd_ReadMemoryInUse( DdManager * dd ); +extern int Cudd_PrintInfo( DdManager * dd, FILE * fp ); +extern long Cudd_ReadPeakNodeCount( DdManager * dd ); +extern int Cudd_ReadPeakLiveNodeCount( DdManager * dd ); +extern long Cudd_ReadNodeCount( DdManager * dd ); +extern long Cudd_zddReadNodeCount( DdManager * dd ); +extern int Cudd_AddHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_RemoveHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_IsInHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_StdPreReordHook( DdManager * dd, const char * str, void * data ); +extern int Cudd_StdPostReordHook( DdManager * dd, const char * str, void * data ); +extern int Cudd_EnableReorderingReporting( DdManager * dd ); +extern int Cudd_DisableReorderingReporting( DdManager * dd ); +extern int Cudd_ReorderingReporting( DdManager * dd ); +extern Cudd_ErrorType Cudd_ReadErrorCode( DdManager * dd ); +extern void Cudd_ClearErrorCode( DdManager * dd ); +extern FILE * Cudd_ReadStdout( DdManager * dd ); +extern void Cudd_SetStdout( DdManager * dd, FILE * fp ); +extern FILE * Cudd_ReadStderr( DdManager * dd ); +extern void Cudd_SetStderr( DdManager * dd, FILE * fp ); +extern unsigned int Cudd_ReadNextReordering( DdManager * dd ); +extern void Cudd_SetNextReordering( DdManager * dd, unsigned int next ); +extern double Cudd_ReadSwapSteps( DdManager * dd ); +extern unsigned int Cudd_ReadMaxLive( DdManager * dd ); +extern void Cudd_SetMaxLive( DdManager * dd, unsigned int maxLive ); +extern unsigned long Cudd_ReadMaxMemory( DdManager * dd ); +extern void Cudd_SetMaxMemory( DdManager * dd, unsigned long maxMemory ); +extern int Cudd_bddBindVar( DdManager * dd, int index ); +extern int Cudd_bddUnbindVar( DdManager * dd, int index ); +extern int Cudd_bddVarIsBound( DdManager * dd, int index ); +extern DdNode * Cudd_addExistAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addUnivAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addOrAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addApply( DdManager * dd, DdNode * ( * )(DdManager * , DdNode ** , DdNode ** ), DdNode * f, DdNode * g ); +extern DdNode * Cudd_addPlus( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addTimes( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addThreshold( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addSetNZ( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addDivide( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMinus( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMinimum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMaximum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addOneZeroMaximum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addDiff( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addAgreement( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addOr( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addNand( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addNor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addXor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addXnor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMonadicApply( DdManager * dd, DdNode * ( * op)(DdManager * , DdNode * ), DdNode * f ); +extern DdNode * Cudd_addLog( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addFindMax( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addFindMin( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addIthBit( DdManager * dd, DdNode * f, int bit ); +extern DdNode * Cudd_addScalarInverse( DdManager * dd, DdNode * f, DdNode * epsilon ); +extern DdNode * Cudd_addIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_addIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_addEvalConst( DdManager * dd, DdNode * f, DdNode * g ); +extern int Cudd_addLeq( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addCmpl( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addNegate( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addRoundOff( DdManager * dd, DdNode * f, int N ); +extern DdNode * Cudd_addWalsh( DdManager * dd, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_addResidue( DdManager * dd, int n, int m, int options, int top ); +extern DdNode * Cudd_bddAndAbstract( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * Cudd_bddAndAbstractLimit( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube, unsigned int limit ); +extern int Cudd_ApaNumberOfDigits( int binaryDigits ); +extern DdApaNumber Cudd_NewApaNumber( int digits ); +extern void Cudd_ApaCopy( int digits, DdApaNumber source, DdApaNumber dest ); +extern DdApaDigit Cudd_ApaAdd( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum ); +extern DdApaDigit Cudd_ApaSubtract( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff ); +extern DdApaDigit Cudd_ApaShortDivision( int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient ); +extern unsigned int Cudd_ApaIntDivision( int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient ); +extern void Cudd_ApaShiftRight( int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b ); +extern void Cudd_ApaSetToLiteral( int digits, DdApaNumber number, DdApaDigit literal ); +extern void Cudd_ApaPowerOfTwo( int digits, DdApaNumber number, int power ); +extern int Cudd_ApaCompare( int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second ); +extern int Cudd_ApaCompareRatios( int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen ); +extern int Cudd_ApaPrintHex( FILE * fp, int digits, DdApaNumber number ); +extern int Cudd_ApaPrintDecimal( FILE * fp, int digits, DdApaNumber number ); +extern int Cudd_ApaPrintExponential( FILE * fp, int digits, DdApaNumber number, int precision ); +extern DdApaNumber Cudd_ApaCountMinterm( DdManager * manager, DdNode * node, int nvars, int * digits ); +extern int Cudd_ApaPrintMinterm( FILE * fp, DdManager * dd, DdNode * node, int nvars ); +extern int Cudd_ApaPrintMintermExp( FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision ); +extern int Cudd_ApaPrintDensity( FILE * fp, DdManager * dd, DdNode * node, int nvars ); +extern DdNode * Cudd_UnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * Cudd_OverApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * Cudd_RemapUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * Cudd_RemapOverApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * Cudd_BiasedUnderApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * Cudd_BiasedOverApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * Cudd_bddExistAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_bddXorExistAbstract( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * Cudd_bddUnivAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_bddBooleanDiff( DdManager * manager, DdNode * f, int x ); +extern int Cudd_bddVarIsDependent( DdManager * dd, DdNode * f, DdNode * var ); +extern double Cudd_bddCorrelation( DdManager * manager, DdNode * f, DdNode * g ); +extern double Cudd_bddCorrelationWeights( DdManager * manager, DdNode * f, DdNode * g, double * prob ); +extern DdNode * Cudd_bddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_bddIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_bddIntersect( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddAnd( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddAndLimit( DdManager * dd, DdNode * f, DdNode * g, unsigned int limit ); +extern DdNode * Cudd_bddOr( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddNand( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddNor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddXor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddXnor( DdManager * dd, DdNode * f, DdNode * g ); +extern int Cudd_bddLeq( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addBddThreshold( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE value ); +extern DdNode * Cudd_addBddStrictThreshold( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE value ); +extern DdNode * Cudd_addBddInterval( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper ); +extern DdNode * Cudd_addBddIthBit( DdManager * dd, DdNode * f, int bit ); +extern DdNode * Cudd_BddToAdd( DdManager * dd, DdNode * B ); +extern DdNode * Cudd_addBddPattern( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_bddTransfer( DdManager * ddSource, DdManager * ddDestination, DdNode * f ); +extern int Cudd_DebugCheck( DdManager * table ); +extern int Cudd_CheckKeys( DdManager * table ); +extern DdNode * Cudd_bddClippingAnd( DdManager * dd, DdNode * f, DdNode * g, int maxDepth, int direction ); +extern DdNode * Cudd_bddClippingAndAbstract( DdManager * dd, DdNode * f, DdNode * g, DdNode * cube, int maxDepth, int direction ); +extern DdNode * Cudd_Cofactor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddCompose( DdManager * dd, DdNode * f, DdNode * g, int v ); +extern DdNode * Cudd_addCompose( DdManager * dd, DdNode * f, DdNode * g, int v ); +extern DdNode * Cudd_addPermute( DdManager * manager, DdNode * node, int * permut ); +extern DdNode * Cudd_addSwapVariables( DdManager * dd, DdNode * f, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddPermute( DdManager * manager, DdNode * node, int * permut ); +extern DdNode * Cudd_bddVarMap( DdManager * manager, DdNode * f ); +extern int Cudd_SetVarMap( DdManager * manager, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddSwapVariables( DdManager * dd, DdNode * f, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddAdjPermuteX( DdManager * dd, DdNode * B, DdNode ** x, int n ); +extern DdNode * Cudd_addVectorCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern DdNode * Cudd_addGeneralVectorCompose( DdManager * dd, DdNode * f, DdNode ** vectorOn, DdNode ** vectorOff ); +extern DdNode * Cudd_addNonSimCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern DdNode * Cudd_bddVectorCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern int Cudd_bddApproxConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddApproxDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddIterConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddIterDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddGenConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddGenDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddVarConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddVarDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern DdNode * Cudd_FindEssential( DdManager * dd, DdNode * f ); +extern int Cudd_bddIsVarEssential( DdManager * manager, DdNode * f, int id, int phase ); +extern DdTlcInfo * Cudd_FindTwoLiteralClauses( DdManager * dd, DdNode * f ); +extern int Cudd_PrintTwoLiteralClauses( DdManager * dd, DdNode * f, char ** names, FILE * fp ); +extern int Cudd_ReadIthClause( DdTlcInfo * tlc, int i, DdHalfWord * var1, DdHalfWord * var2, int * phase1, int * phase2 ); +extern void Cudd_tlcInfoFree( DdTlcInfo * t ); +extern int Cudd_DumpBlif( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, char * mname, FILE * fp, int mv ); +extern int Cudd_DumpBlifBody( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp, int mv ); +extern int Cudd_DumpDot( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpDaVinci( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpDDcal( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpFactoredForm( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern DdNode * Cudd_bddConstrain( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddRestrict( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddNPAnd( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_addConstrain( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode ** Cudd_bddConstrainDecomp( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addRestrict( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode ** Cudd_bddCharToVect( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_bddLICompaction( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddSqueeze( DdManager * dd, DdNode * l, DdNode * u ); +extern DdNode * Cudd_bddMinimize( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_SubsetCompress( DdManager * dd, DdNode * f, int nvars, int threshold ); +extern DdNode * Cudd_SupersetCompress( DdManager * dd, DdNode * f, int nvars, int threshold ); +extern MtrNode * Cudd_MakeTreeNode( DdManager * dd, unsigned int low, unsigned int size, unsigned int type ); +extern int Cudd_addHarwell( FILE * fp, DdManager * dd, DdNode ** E, DdNode ** * x, DdNode ** * y, DdNode ** * xn, DdNode ** * yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy, int pr ); +extern DdManager * Cudd_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory ); +extern void Cudd_Quit( DdManager * unique ); +extern int Cudd_PrintLinear( DdManager * table ); +extern int Cudd_ReadLinear( DdManager * table, int x, int y ); +extern DdNode * Cudd_bddLiteralSetIntersection( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addMatrixMultiply( DdManager * dd, DdNode * A, DdNode * B, DdNode ** z, int nz ); +extern DdNode * Cudd_addTimesPlus( DdManager * dd, DdNode * A, DdNode * B, DdNode ** z, int nz ); +extern DdNode * Cudd_addTriangle( DdManager * dd, DdNode * f, DdNode * g, DdNode ** z, int nz ); +extern DdNode * Cudd_addOuterSum( DdManager * dd, DdNode * M, DdNode * r, DdNode * c ); +extern DdNode * Cudd_PrioritySelect( DdManager * dd, DdNode * R, DdNode ** x, DdNode ** y, DdNode ** z, DdNode * Pi, int n, DdNode * ( * )(DdManager * , int, DdNode ** , DdNode ** , DdNode ** ) ); +extern DdNode * Cudd_Xgty( DdManager * dd, int N, DdNode ** z, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Xeqy( DdManager * dd, int N, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_addXeqy( DdManager * dd, int N, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Dxygtdxz( DdManager * dd, int N, DdNode ** x, DdNode ** y, DdNode ** z ); +extern DdNode * Cudd_Dxygtdyz( DdManager * dd, int N, DdNode ** x, DdNode ** y, DdNode ** z ); +extern DdNode * Cudd_Inequality( DdManager * dd, int N, int c, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Disequality( DdManager * dd, int N, int c, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_bddInterval( DdManager * dd, int N, DdNode ** x, unsigned int lowerB, unsigned int upperB ); +extern DdNode * Cudd_CProjection( DdManager * dd, DdNode * R, DdNode * Y ); +extern DdNode * Cudd_addHamming( DdManager * dd, DdNode ** xVars, DdNode ** yVars, int nVars ); +extern int Cudd_MinHammingDist( DdManager * dd, DdNode * f, int * minterm, int upperBound ); +extern DdNode * Cudd_bddClosestCube( DdManager * dd, DdNode * f, DdNode * g, int * distance ); +extern int Cudd_addRead( FILE * fp, DdManager * dd, DdNode ** E, DdNode ** * x, DdNode ** * y, DdNode ** * xn, DdNode ** * yn_, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy ); +extern int Cudd_bddRead( FILE * fp, DdManager * dd, DdNode ** E, DdNode ** * x, DdNode ** * y, int * nx, int * ny, int * m, int * n, int bx, int sx, int by, int sy ); +extern void Cudd_Ref( DdNode * n ); +extern void Cudd_RecursiveDeref( DdManager * table, DdNode * n ); +extern void Cudd_IterDerefBdd( DdManager * table, DdNode * n ); +extern void Cudd_DelayedDerefBdd( DdManager * table, DdNode * n ); +extern void Cudd_RecursiveDerefZdd( DdManager * table, DdNode * n ); +extern void Cudd_Deref( DdNode * node ); +extern int Cudd_CheckZeroRef( DdManager * manager ); +extern int Cudd_ReduceHeap( DdManager * table, Cudd_ReorderingType heuristic, int minsize ); +extern int Cudd_ShuffleHeap( DdManager * table, int * permutation ); +extern DdNode * Cudd_Eval( DdManager * dd, DdNode * f, int * inputs ); +extern DdNode * Cudd_ShortestPath( DdManager * manager, DdNode * f, int * weight, int * support, int * length ); +extern DdNode * Cudd_LargestCube( DdManager * manager, DdNode * f, int * length ); +extern int Cudd_ShortestLength( DdManager * manager, DdNode * f, int * weight ); +extern DdNode * Cudd_Decreasing( DdManager * dd, DdNode * f, int i ); +extern DdNode * Cudd_Increasing( DdManager * dd, DdNode * f, int i ); +extern int Cudd_EquivDC( DdManager * dd, DdNode * F, DdNode * G, DdNode * D ); +extern int Cudd_bddLeqUnless( DdManager * dd, DdNode * f, DdNode * g, DdNode * D ); +extern int Cudd_EqualSupNorm( DdManager * dd, DdNode * f, DdNode * g, CUDD_VALUE_TYPE tolerance, int pr ); +extern DdNode * Cudd_bddMakePrime( DdManager * dd, DdNode * cube, DdNode * f ); +extern double * Cudd_CofMinterm( DdManager * dd, DdNode * node ); +extern DdNode * Cudd_SolveEqn( DdManager * bdd, DdNode * F, DdNode * Y, DdNode ** G, int ** yIndex, int n ); +extern DdNode * Cudd_VerifySol( DdManager * bdd, DdNode * F, DdNode ** G, int * yIndex, int n ); +extern DdNode * Cudd_SplitSet( DdManager * manager, DdNode * S, DdNode ** xVars, int n, double m ); +extern DdNode * Cudd_SubsetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * Cudd_SupersetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * Cudd_SubsetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern DdNode * Cudd_SupersetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern void Cudd_SymmProfile( DdManager * table, int lower, int upper ); +extern unsigned int Cudd_Prime( unsigned int p ); +extern int Cudd_PrintMinterm( DdManager * manager, DdNode * node ); +extern int Cudd_bddPrintCover( DdManager * dd, DdNode * l, DdNode * u ); +extern int Cudd_PrintDebug( DdManager * dd, DdNode * f, int n, int pr ); +extern int Cudd_DagSize( DdNode * node ); +extern int Cudd_EstimateCofactor( DdManager * dd, DdNode * node, int i, int phase ); +extern int Cudd_EstimateCofactorSimple( DdNode * node, int i ); +extern int Cudd_SharingSize( DdNode ** nodeArray, int n ); +extern double Cudd_CountMinterm( DdManager * manager, DdNode * node, int nvars ); +extern int Cudd_EpdCountMinterm( DdManager * manager, DdNode * node, int nvars, EpDouble * epd ); +extern double Cudd_CountPath( DdNode * node ); +extern double Cudd_CountPathsToNonZero( DdNode * node ); +extern DdNode * Cudd_Support( DdManager * dd, DdNode * f ); +extern int * Cudd_SupportIndex( DdManager * dd, DdNode * f ); +extern int Cudd_SupportSize( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_VectorSupport( DdManager * dd, DdNode ** F, int n ); +extern int * Cudd_VectorSupportIndex( DdManager * dd, DdNode ** F, int n ); +extern int Cudd_VectorSupportSize( DdManager * dd, DdNode ** F, int n ); +extern int Cudd_ClassifySupport( DdManager * dd, DdNode * f, DdNode * g, DdNode ** common, DdNode ** onlyF, DdNode ** onlyG ); +extern int Cudd_CountLeaves( DdNode * node ); +extern int Cudd_bddPickOneCube( DdManager * ddm, DdNode * node, char * string ); +extern DdNode * Cudd_bddPickOneMinterm( DdManager * dd, DdNode * f, DdNode ** vars, int n ); +extern DdNode ** Cudd_bddPickArbitraryMinterms( DdManager * dd, DdNode * f, DdNode ** vars, int n, int k ); +extern DdNode * Cudd_SubsetWithMaskVars( DdManager * dd, DdNode * f, DdNode ** vars, int nvars, DdNode ** maskVars, int mvars ); +extern DdGen * Cudd_FirstCube( DdManager * dd, DdNode * f, int ** cube, CUDD_VALUE_TYPE * value ); +extern int Cudd_NextCube( DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value ); +extern DdGen * Cudd_FirstPrime(DdManager * dd, DdNode * l, DdNode * u, int ** cube ); +extern int Cudd_NextPrime(DdGen * gen, int ** cube ); +extern DdNode * Cudd_bddComputeCube( DdManager * dd, DdNode ** vars, int * phase, int n ); +extern DdNode * Cudd_addComputeCube( DdManager * dd, DdNode ** vars, int * phase, int n ); +extern DdNode * Cudd_CubeArrayToBdd( DdManager * dd, int * array ); +extern int Cudd_BddToCubeArray( DdManager * dd, DdNode * cube, int * array ); +extern DdGen * Cudd_FirstNode( DdManager * dd, DdNode * f, DdNode ** node ); +extern int Cudd_NextNode( DdGen * gen, DdNode ** node ); +extern int Cudd_GenFree( DdGen * gen ); +extern int Cudd_IsGenEmpty( DdGen * gen ); +extern DdNode * Cudd_IndicesToCube( DdManager * dd, int * array, int n ); +extern void Cudd_PrintVersion( FILE * fp ); +extern double Cudd_AverageDistance( DdManager * dd ); +extern long Cudd_Random( void ); +extern void Cudd_Srandom( long seed ); +extern double Cudd_Density( DdManager * dd, DdNode * f, int nvars ); +extern void Cudd_OutOfMem( long size ); +extern int Cudd_zddCount( DdManager * zdd, DdNode * P ); +extern double Cudd_zddCountDouble( DdManager * zdd, DdNode * P ); +extern DdNode * Cudd_zddProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddUnateProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddWeakDiv( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddDivide( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddWeakDivF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddDivideF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddComplement( DdManager * dd, DdNode * node ); +extern MtrNode * Cudd_MakeZddTreeNode( DdManager * dd, unsigned int low, unsigned int size, unsigned int type ); +extern DdNode * Cudd_zddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I ); +extern DdNode * Cudd_bddIsop( DdManager * dd, DdNode * L, DdNode * U ); +extern DdNode * Cudd_MakeBddFromZddCover( DdManager * dd, DdNode * node ); +extern int Cudd_zddDagSize( DdNode * p_node ); +extern double Cudd_zddCountMinterm( DdManager * zdd, DdNode * node, int path ); +extern void Cudd_zddPrintSubtable( DdManager * table ); +extern DdNode * Cudd_zddPortFromBdd( DdManager * dd, DdNode * B ); +extern DdNode * Cudd_zddPortToBdd( DdManager * dd, DdNode * f ); +extern int Cudd_zddReduceHeap( DdManager * table, Cudd_ReorderingType heuristic, int minsize ); +extern int Cudd_zddShuffleHeap( DdManager * table, int * permutation ); +extern DdNode * Cudd_zddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_zddUnion( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddIntersect( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddDiff( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddDiffConst( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddSubset1( DdManager * dd, DdNode * P, int var ); +extern DdNode * Cudd_zddSubset0( DdManager * dd, DdNode * P, int var ); +extern DdNode * Cudd_zddChange( DdManager * dd, DdNode * P, int var ); +extern void Cudd_zddSymmProfile( DdManager * table, int lower, int upper ); +extern int Cudd_zddPrintMinterm( DdManager * zdd, DdNode * node ); +extern int Cudd_zddPrintCover( DdManager * zdd, DdNode * node ); +extern int Cudd_zddPrintDebug( DdManager * zdd, DdNode * f, int n, int pr ); +extern DdGen * Cudd_zddFirstPath( DdManager * zdd, DdNode * f, int ** path ); +extern int Cudd_zddNextPath( DdGen * gen, int ** path ); +extern char * Cudd_zddCoverPathToString( DdManager * zdd, int * path, char * str ); +extern int Cudd_zddDumpDot( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_bddSetPiVar( DdManager * dd, int index ); +extern int Cudd_bddSetPsVar( DdManager * dd, int index ); +extern int Cudd_bddSetNsVar( DdManager * dd, int index ); +extern int Cudd_bddIsPiVar( DdManager * dd, int index ); +extern int Cudd_bddIsPsVar( DdManager * dd, int index ); +extern int Cudd_bddIsNsVar( DdManager * dd, int index ); +extern int Cudd_bddSetPairIndex( DdManager * dd, int index, int pairIndex ); +extern int Cudd_bddReadPairIndex( DdManager * dd, int index ); +extern int Cudd_bddSetVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddSetVarHardGroup( DdManager * dd, int index ); +extern int Cudd_bddResetVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddSetVarToBeUngrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarToBeUngrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarHardGroup( DdManager * dd, int index ); /**AutomaticEnd***************************************************************/ diff --git a/src/bdd/cudd/cuddAPI.c b/src/bdd/cudd/cuddAPI.c index 729dd329..233795e2 100644 --- a/src/bdd/cudd/cuddAPI.c +++ b/src/bdd/cudd/cuddAPI.c @@ -7,169 +7,197 @@ Synopsis [Application interface functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_addNewVar() - <li> Cudd_addNewVarAtLevel() - <li> Cudd_bddNewVar() - <li> Cudd_bddNewVarAtLevel() - <li> Cudd_addIthVar() - <li> Cudd_bddIthVar() - <li> Cudd_zddIthVar() - <li> Cudd_zddVarsFromBddVars() - <li> Cudd_addConst() - <li> Cudd_IsNonConstant() - <li> Cudd_AutodynEnable() - <li> Cudd_AutodynDisable() - <li> Cudd_ReorderingStatus() - <li> Cudd_AutodynEnableZdd() - <li> Cudd_AutodynDisableZdd() - <li> Cudd_ReorderingStatusZdd() - <li> Cudd_zddRealignmentEnabled() - <li> Cudd_zddRealignEnable() - <li> Cudd_zddRealignDisable() - <li> Cudd_bddRealignmentEnabled() - <li> Cudd_bddRealignEnable() - <li> Cudd_bddRealignDisable() - <li> Cudd_ReadOne() - <li> Cudd_ReadZddOne() - <li> Cudd_ReadZero() - <li> Cudd_ReadLogicZero() - <li> Cudd_ReadPlusInfinity() - <li> Cudd_ReadMinusInfinity() - <li> Cudd_ReadBackground() - <li> Cudd_SetBackground() - <li> Cudd_ReadCacheSlots() - <li> Cudd_ReadCacheUsedSlots() - <li> Cudd_ReadCacheLookUps() - <li> Cudd_ReadCacheHits() - <li> Cudd_ReadMinHit() - <li> Cudd_SetMinHit() - <li> Cudd_ReadLooseUpTo() - <li> Cudd_SetLooseUpTo() - <li> Cudd_ReadMaxCache() - <li> Cudd_ReadMaxCacheHard() - <li> Cudd_SetMaxCacheHard() - <li> Cudd_ReadSize() - <li> Cudd_ReadSlots() - <li> Cudd_ReadUsedSlots() - <li> Cudd_ExpectedUsedSlots() - <li> Cudd_ReadKeys() - <li> Cudd_ReadDead() - <li> Cudd_ReadMinDead() - <li> Cudd_ReadReorderings() - <li> Cudd_ReadReorderingTime() - <li> Cudd_ReadGarbageCollections() - <li> Cudd_ReadGarbageCollectionTime() - <li> Cudd_ReadNodesFreed() - <li> Cudd_ReadNodesDropped() - <li> Cudd_ReadUniqueLookUps() - <li> Cudd_ReadUniqueLinks() - <li> Cudd_ReadSiftMaxVar() - <li> Cudd_SetSiftMaxVar() - <li> Cudd_ReadMaxGrowth() - <li> Cudd_SetMaxGrowth() - <li> Cudd_ReadMaxGrowthAlternate() - <li> Cudd_SetMaxGrowthAlternate() - <li> Cudd_ReadReorderingCycle() - <li> Cudd_SetReorderingCycle() - <li> Cudd_ReadTree() - <li> Cudd_SetTree() - <li> Cudd_FreeTree() - <li> Cudd_ReadZddTree() - <li> Cudd_SetZddTree() - <li> Cudd_FreeZddTree() + <ul> + <li> Cudd_addNewVar() + <li> Cudd_addNewVarAtLevel() + <li> Cudd_bddNewVar() + <li> Cudd_bddNewVarAtLevel() + <li> Cudd_addIthVar() + <li> Cudd_bddIthVar() + <li> Cudd_zddIthVar() + <li> Cudd_zddVarsFromBddVars() + <li> Cudd_addConst() + <li> Cudd_IsNonConstant() + <li> Cudd_AutodynEnable() + <li> Cudd_AutodynDisable() + <li> Cudd_ReorderingStatus() + <li> Cudd_AutodynEnableZdd() + <li> Cudd_AutodynDisableZdd() + <li> Cudd_ReorderingStatusZdd() + <li> Cudd_zddRealignmentEnabled() + <li> Cudd_zddRealignEnable() + <li> Cudd_zddRealignDisable() + <li> Cudd_bddRealignmentEnabled() + <li> Cudd_bddRealignEnable() + <li> Cudd_bddRealignDisable() + <li> Cudd_ReadOne() + <li> Cudd_ReadZddOne() + <li> Cudd_ReadZero() + <li> Cudd_ReadLogicZero() + <li> Cudd_ReadPlusInfinity() + <li> Cudd_ReadMinusInfinity() + <li> Cudd_ReadBackground() + <li> Cudd_SetBackground() + <li> Cudd_ReadCacheSlots() + <li> Cudd_ReadCacheUsedSlots() + <li> Cudd_ReadCacheLookUps() + <li> Cudd_ReadCacheHits() + <li> Cudd_ReadMinHit() + <li> Cudd_SetMinHit() + <li> Cudd_ReadLooseUpTo() + <li> Cudd_SetLooseUpTo() + <li> Cudd_ReadMaxCache() + <li> Cudd_ReadMaxCacheHard() + <li> Cudd_SetMaxCacheHard() + <li> Cudd_ReadSize() + <li> Cudd_ReadSlots() + <li> Cudd_ReadUsedSlots() + <li> Cudd_ExpectedUsedSlots() + <li> Cudd_ReadKeys() + <li> Cudd_ReadDead() + <li> Cudd_ReadMinDead() + <li> Cudd_ReadReorderings() + <li> Cudd_ReadReorderingTime() + <li> Cudd_ReadGarbageCollections() + <li> Cudd_ReadGarbageCollectionTime() + <li> Cudd_ReadNodesFreed() + <li> Cudd_ReadNodesDropped() + <li> Cudd_ReadUniqueLookUps() + <li> Cudd_ReadUniqueLinks() + <li> Cudd_ReadSiftMaxVar() + <li> Cudd_SetSiftMaxVar() + <li> Cudd_ReadMaxGrowth() + <li> Cudd_SetMaxGrowth() + <li> Cudd_ReadMaxGrowthAlternate() + <li> Cudd_SetMaxGrowthAlternate() + <li> Cudd_ReadReorderingCycle() + <li> Cudd_SetReorderingCycle() + <li> Cudd_ReadTree() + <li> Cudd_SetTree() + <li> Cudd_FreeTree() + <li> Cudd_ReadZddTree() + <li> Cudd_SetZddTree() + <li> Cudd_FreeZddTree() <li> Cudd_NodeReadIndex() - <li> Cudd_ReadPerm() - <li> Cudd_ReadInvPerm() - <li> Cudd_ReadVars() - <li> Cudd_ReadEpsilon() - <li> Cudd_SetEpsilon() - <li> Cudd_ReadGroupCheck() - <li> Cudd_SetGroupcheck() - <li> Cudd_GarbageCollectionEnabled() - <li> Cudd_EnableGarbageCollection() - <li> Cudd_DisableGarbageCollection() - <li> Cudd_DeadAreCounted() - <li> Cudd_TurnOnCountDead() - <li> Cudd_TurnOffCountDead() - <li> Cudd_ReadRecomb() - <li> Cudd_SetRecomb() - <li> Cudd_ReadSymmviolation() - <li> Cudd_SetSymmviolation() - <li> Cudd_ReadArcviolation() - <li> Cudd_SetArcviolation() - <li> Cudd_ReadPopulationSize() - <li> Cudd_SetPopulationSize() - <li> Cudd_ReadNumberXovers() - <li> Cudd_SetNumberXovers() - <li> Cudd_ReadMemoryInUse() - <li> Cudd_PrintInfo() - <li> Cudd_ReadPeakNodeCount() - <li> Cudd_ReadPeakLiveNodeCount() - <li> Cudd_ReadNodeCount() - <li> Cudd_zddReadNodeCount() - <li> Cudd_AddHook() - <li> Cudd_RemoveHook() - <li> Cudd_IsInHook() - <li> Cudd_StdPreReordHook() - <li> Cudd_StdPostReordHook() - <li> Cudd_EnableReorderingReporting() - <li> Cudd_DisableReorderingReporting() - <li> Cudd_ReorderingReporting() - <li> Cudd_ReadErrorCode() - <li> Cudd_ClearErrorCode() - <li> Cudd_ReadStdout() - <li> Cudd_SetStdout() - <li> Cudd_ReadStderr() - <li> Cudd_SetStderr() - <li> Cudd_ReadNextReordering() - <li> Cudd_SetNextReordering() - <li> Cudd_ReadSwapSteps() - <li> Cudd_ReadMaxLive() - <li> Cudd_SetMaxLive() - <li> Cudd_ReadMaxMemory() - <li> Cudd_SetMaxMemory() - <li> Cudd_bddBindVar() - <li> Cudd_bddUnbindVar() - <li> Cudd_bddVarIsBound() - <li> Cudd_bddSetPiVar() - <li> Cudd_bddSetPsVar() - <li> Cudd_bddSetNsVar() - <li> Cudd_bddIsPiVar() - <li> Cudd_bddIsPsVar() - <li> Cudd_bddIsNsVar() - <li> Cudd_bddSetPairIndex() - <li> Cudd_bddReadPairIndex() - <li> Cudd_bddSetVarToBeGrouped() - <li> Cudd_bddSetVarHardGroup() - <li> Cudd_bddResetVarToBeGrouped() - <li> Cudd_bddIsVarToBeGrouped() - <li> Cudd_bddSetVarToBeUngrouped() - <li> Cudd_bddIsVarToBeUngrouped() - <li> Cudd_bddIsVarHardGroup() - </ul> - Static procedures included in this module: - <ul> - <li> fixVarTree() - </ul>] + <li> Cudd_ReadPerm() + <li> Cudd_ReadInvPerm() + <li> Cudd_ReadVars() + <li> Cudd_ReadEpsilon() + <li> Cudd_SetEpsilon() + <li> Cudd_ReadGroupCheck() + <li> Cudd_SetGroupcheck() + <li> Cudd_GarbageCollectionEnabled() + <li> Cudd_EnableGarbageCollection() + <li> Cudd_DisableGarbageCollection() + <li> Cudd_DeadAreCounted() + <li> Cudd_TurnOnCountDead() + <li> Cudd_TurnOffCountDead() + <li> Cudd_ReadRecomb() + <li> Cudd_SetRecomb() + <li> Cudd_ReadSymmviolation() + <li> Cudd_SetSymmviolation() + <li> Cudd_ReadArcviolation() + <li> Cudd_SetArcviolation() + <li> Cudd_ReadPopulationSize() + <li> Cudd_SetPopulationSize() + <li> Cudd_ReadNumberXovers() + <li> Cudd_SetNumberXovers() + <li> Cudd_ReadMemoryInUse() + <li> Cudd_PrintInfo() + <li> Cudd_ReadPeakNodeCount() + <li> Cudd_ReadPeakLiveNodeCount() + <li> Cudd_ReadNodeCount() + <li> Cudd_zddReadNodeCount() + <li> Cudd_AddHook() + <li> Cudd_RemoveHook() + <li> Cudd_IsInHook() + <li> Cudd_StdPreReordHook() + <li> Cudd_StdPostReordHook() + <li> Cudd_EnableReorderingReporting() + <li> Cudd_DisableReorderingReporting() + <li> Cudd_ReorderingReporting() + <li> Cudd_ReadErrorCode() + <li> Cudd_ClearErrorCode() + <li> Cudd_ReadStdout() + <li> Cudd_SetStdout() + <li> Cudd_ReadStderr() + <li> Cudd_SetStderr() + <li> Cudd_ReadNextReordering() + <li> Cudd_SetNextReordering() + <li> Cudd_ReadSwapSteps() + <li> Cudd_ReadMaxLive() + <li> Cudd_SetMaxLive() + <li> Cudd_ReadMaxMemory() + <li> Cudd_SetMaxMemory() + <li> Cudd_bddBindVar() + <li> Cudd_bddUnbindVar() + <li> Cudd_bddVarIsBound() + <li> Cudd_bddSetPiVar() + <li> Cudd_bddSetPsVar() + <li> Cudd_bddSetNsVar() + <li> Cudd_bddIsPiVar() + <li> Cudd_bddIsPsVar() + <li> Cudd_bddIsNsVar() + <li> Cudd_bddSetPairIndex() + <li> Cudd_bddReadPairIndex() + <li> Cudd_bddSetVarToBeGrouped() + <li> Cudd_bddSetVarHardGroup() + <li> Cudd_bddResetVarToBeGrouped() + <li> Cudd_bddIsVarToBeGrouped() + <li> Cudd_bddSetVarToBeUngrouped() + <li> Cudd_bddIsVarToBeUngrouped() + <li> Cudd_bddIsVarHardGroup() + </ul> + Static procedures included in this module: + <ul> + <li> fixVarTree() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -187,7 +215,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.59 2009/02/19 16:14:14 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -200,8 +228,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.1.1.1 2003/02/24 22:23:51 wj /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void fixVarTree ARGS((MtrNode *treenode, int *perm, int size)); -static int addMultiplicityGroups ARGS((DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask)); +static void fixVarTree (MtrNode *treenode, int *perm, int size); +static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask); /**AutomaticEnd***************************************************************/ @@ -235,8 +263,8 @@ Cudd_addNewVar( if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -269,8 +297,8 @@ Cudd_addNewVarAtLevel( if (level >= dd->size) return(Cudd_addIthVar(dd,level)); if (!cuddInsertSubtables(dd,1,level)) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -361,8 +389,8 @@ Cudd_addIthVar( if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -393,9 +421,9 @@ Cudd_bddIthVar( if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); if (i < dd->size) { - res = dd->vars[i]; + res = dd->vars[i]; } else { - res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); } return(res); @@ -437,27 +465,27 @@ Cudd_zddIthVar( /* First we build the node at the level of index i. */ lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); do { - dd->reordered = 0; - zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); + dd->reordered = 0; + zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); } while (dd->reordered == 1); if (zvar == NULL) - return(NULL); + return(NULL); cuddRef(zvar); /* Now we add the "filler" nodes above the level of index i. */ for (j = dd->permZ[i] - 1; j >= 0; j--) { - do { - dd->reordered = 0; - res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); - } while (dd->reordered == 1); - if (res == NULL) { + do { + dd->reordered = 0; + res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDerefZdd(dd,zvar); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd,zvar); - zvar = res; + zvar = res; } cuddDeref(zvar); return(zvar); @@ -500,75 +528,75 @@ Cudd_zddVarsFromBddVars( if (multiplicity < 1) return(0); allnew = dd->sizeZ == 0; if (dd->size * multiplicity > dd->sizeZ) { - res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); - if (res == 0) return(0); + res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); + if (res == 0) return(0); } /* Impose the order of the BDD variables to the ZDD variables. */ if (allnew) { - for (i = 0; i < dd->size; i++) { - for (j = 0; j < multiplicity; j++) { - dd->permZ[i * multiplicity + j] = - dd->perm[i] * multiplicity + j; - dd->invpermZ[dd->permZ[i * multiplicity + j]] = - i * multiplicity + j; + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + dd->permZ[i * multiplicity + j] = + dd->perm[i] * multiplicity + j; + dd->invpermZ[dd->permZ[i * multiplicity + j]] = + i * multiplicity + j; + } + } + for (i = 0; i < dd->sizeZ; i++) { + dd->univ[i]->index = dd->invpermZ[i]; } - } - for (i = 0; i < dd->sizeZ; i++) { - dd->univ[i]->index = dd->invpermZ[i]; - } } else { - permutation = ABC_ALLOC(int,dd->sizeZ); - if (permutation == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (i = 0; i < dd->size; i++) { - for (j = 0; j < multiplicity; j++) { - permutation[i * multiplicity + j] = - dd->invperm[i] * multiplicity + j; + permutation = ABC_ALLOC(int,dd->sizeZ); + if (permutation == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - } - for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { - permutation[i] = i; - } - res = Cudd_zddShuffleHeap(dd, permutation); - ABC_FREE(permutation); - if (res == 0) return(0); + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + permutation[i * multiplicity + j] = + dd->invperm[i] * multiplicity + j; + } + } + for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { + permutation[i] = i; + } + res = Cudd_zddShuffleHeap(dd, permutation); + ABC_FREE(permutation); + if (res == 0) return(0); } /* Copy and expand the variable group tree if it exists. */ if (dd->treeZ != NULL) { - Cudd_FreeZddTree(dd); + Cudd_FreeZddTree(dd); } if (dd->tree != NULL) { - dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); - if (dd->treeZ == NULL) return(0); + dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); + if (dd->treeZ == NULL) return(0); } else if (multiplicity > 1) { - dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); - if (dd->treeZ == NULL) return(0); - dd->treeZ->index = dd->invpermZ[0]; + dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); + if (dd->treeZ == NULL) return(0); + dd->treeZ->index = dd->invpermZ[0]; } /* Create groups for the ZDD variables derived from the same BDD variable. */ if (multiplicity > 1) { - char *vmask, *lmask; + char *vmask, *lmask; - vmask = ABC_ALLOC(char, dd->size); - if (vmask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - lmask = ABC_ALLOC(char, dd->size); - if (lmask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (i = 0; i < dd->size; i++) { - vmask[i] = lmask[i] = 0; - } - res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); - ABC_FREE(vmask); - ABC_FREE(lmask); - if (res == 0) return(0); + vmask = ABC_ALLOC(char, dd->size); + if (vmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + lmask = ABC_ALLOC(char, dd->size); + if (lmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + vmask[i] = lmask[i] = 0; + } + res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); + ABC_FREE(vmask); + ABC_FREE(lmask); + if (res == 0) return(0); } return(1); @@ -644,7 +672,7 @@ Cudd_AutodynEnable( { unique->autoDyn = 1; if (method != CUDD_REORDER_SAME) { - unique->autoMethod = method; + unique->autoMethod = method; } #ifndef DD_NO_DEATH_ROW /* If reordering is enabled, using the death row causes too many @@ -654,10 +682,10 @@ Cudd_AutodynEnable( unique->deathRowDepth = 1; unique->deadMask = unique->deathRowDepth - 1; if ((unsigned) unique->nextDead > unique->deadMask) { - unique->nextDead = 0; + unique->nextDead = 0; } unique->deathRow = ABC_REALLOC(DdNodePtr, unique->deathRow, - unique->deathRowDepth); + unique->deathRowDepth); #endif return; @@ -735,7 +763,7 @@ Cudd_AutodynEnableZdd( { unique->autoDynZ = 1; if (method != CUDD_REORDER_SAME) { - unique->autoMethodZ = method; + unique->autoMethodZ = method; } return; @@ -984,7 +1012,7 @@ Cudd_ReadZddOne( int i) { if (i < 0) - return(NULL); + return(NULL); return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd)); } /* end of Cudd_ReadZddOne */ @@ -1153,7 +1181,7 @@ Cudd_ReadCacheUsedSlots( int i; for (i = 0; i < slots; i++) { - used += cache[i].h != 0; + used += cache[i].h != 0; } return((double)used / (double) dd->cacheSlots); @@ -1177,7 +1205,7 @@ Cudd_ReadCacheLookUps( DdManager * dd) { return(dd->cacheHits + dd->cacheMisses + - dd->totCachehits + dd->totCacheMisses); + dd->totCachehits + dd->totCacheMisses); } /* end of Cudd_ReadCacheLookUps */ @@ -1319,9 +1347,9 @@ Cudd_SetLooseUpTo( unsigned int lut) { if (lut == 0) { - long datalimit = getSoftDataLimit(); - lut = (unsigned int) (datalimit / (sizeof(DdNode) * - DD_MAX_LOOSE_FRACTION)); + unsigned long datalimit = getSoftDataLimit(); + lut = (unsigned int) (datalimit / (sizeof(DdNode) * + DD_MAX_LOOSE_FRACTION)); } dd->looseUpTo = lut; @@ -1389,9 +1417,9 @@ Cudd_SetMaxCacheHard( unsigned int mc) { if (mc == 0) { - long datalimit = getSoftDataLimit(); - mc = (unsigned int) (datalimit / (sizeof(DdCache) * - DD_MAX_CACHE_FRACTION)); + unsigned long datalimit = getSoftDataLimit(); + mc = (unsigned int) (datalimit / (sizeof(DdCache) * + DD_MAX_CACHE_FRACTION)); } dd->maxCacheHard = mc; @@ -1485,38 +1513,38 @@ Cudd_ReadUsedSlots( /* Scan each BDD/ADD subtable. */ for (i = 0; i < size; i++) { - subtable = &(dd->subtables[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != sentinel) { - used++; + subtable = &(dd->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + used++; + } } } - } /* Scan the ZDD subtables. */ size = dd->sizeZ; for (i = 0; i < size; i++) { - subtable = &(dd->subtableZ[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - used++; + subtable = &(dd->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } } } - } /* Constant table. */ subtable = &(dd->constants); nodelist = subtable->nodelist; for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - used++; - } + node = nodelist[j]; + if (node != NULL) { + used++; + } } return((double)used / (double) dd->slots); @@ -1551,31 +1579,31 @@ Cudd_ExpectedUsedSlots( /* To each subtable we apply the corollary to Theorem 8.5 (occupancy ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. - ** The corollary says that for a a table with M buckets and a load ratio + ** The corollary says that for a table with M buckets and a load ratio ** of r, the expected number of empty buckets is asymptotically given ** by M * exp(-r). */ /* Scan each BDD/ADD subtable. */ for (i = 0; i < size; i++) { - subtable = &(dd->subtables[i]); - empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + subtable = &(dd->subtables[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); } /* Scan the ZDD subtables. */ size = dd->sizeZ; for (i = 0; i < size; i++) { - subtable = &(dd->subtableZ[i]); - empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + subtable = &(dd->subtableZ[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); } /* Constant table. */ subtable = &(dd->constants); empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + exp(-(double) subtable->keys / (double) subtable->slots); return(1.0 - empty / (double) dd->slots); @@ -2126,7 +2154,7 @@ Cudd_SetTree( MtrNode * tree) { if (dd->tree != NULL) { - Mtr_FreeTree(dd->tree); + Mtr_FreeTree(dd->tree); } dd->tree = tree; if (tree == NULL) return; @@ -2153,8 +2181,8 @@ Cudd_FreeTree( DdManager * dd) { if (dd->tree != NULL) { - Mtr_FreeTree(dd->tree); - dd->tree = NULL; + Mtr_FreeTree(dd->tree); + dd->tree = NULL; } return; @@ -2198,7 +2226,7 @@ Cudd_SetZddTree( MtrNode * tree) { if (dd->treeZ != NULL) { - Mtr_FreeTree(dd->treeZ); + Mtr_FreeTree(dd->treeZ); } dd->treeZ = tree; if (tree == NULL) return; @@ -2225,8 +2253,8 @@ Cudd_FreeZddTree( DdManager * dd) { if (dd->treeZ != NULL) { - Mtr_FreeTree(dd->treeZ); - dd->treeZ = NULL; + Mtr_FreeTree(dd->treeZ); + dd->treeZ = NULL; } return; @@ -2884,7 +2912,7 @@ Cudd_SetNumberXovers( SeeAlso [] ******************************************************************************/ -long +unsigned long Cudd_ReadMemoryInUse( DdManager * dd) { @@ -2917,78 +2945,80 @@ Cudd_PrintInfo( retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); if (retval == EOF) return(0); retval = fprintf(fp,"Hard limit for cache size: %u\n", - Cudd_ReadMaxCacheHard(dd)); + Cudd_ReadMaxCacheHard(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", - Cudd_ReadMinHit(dd)); + Cudd_ReadMinHit(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Garbage collection enabled: %s\n", - Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); + Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Limit for fast unique table growth: %u\n", - Cudd_ReadLooseUpTo(dd)); + Cudd_ReadLooseUpTo(dd)); if (retval == EOF) return(0); retval = fprintf(fp, - "Maximum number of variables sifted per reordering: %d\n", - Cudd_ReadSiftMaxVar(dd)); + "Maximum number of variables sifted per reordering: %d\n", + Cudd_ReadSiftMaxVar(dd)); if (retval == EOF) return(0); retval = fprintf(fp, - "Maximum number of variable swaps per reordering: %d\n", - Cudd_ReadSiftMaxSwap(dd)); + "Maximum number of variable swaps per reordering: %d\n", + Cudd_ReadSiftMaxSwap(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", - Cudd_ReadMaxGrowth(dd)); + Cudd_ReadMaxGrowth(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", - Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); + Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); if (retval == EOF) return(0); - retval = fprintf(fp,"Default BDD reordering method: %d\n", autoMethod); + retval = fprintf(fp,"Default BDD reordering method: %d\n", + (int) autoMethod); if (retval == EOF) return(0); retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", - Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); + Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); if (retval == EOF) return(0); - retval = fprintf(fp,"Default ZDD reordering method: %d\n", autoMethodZ); + retval = fprintf(fp,"Default ZDD reordering method: %d\n", + (int) autoMethodZ); if (retval == EOF) return(0); retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", - Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); + Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", - Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); + Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", - Cudd_DeadAreCounted(dd) ? "yes" : "no"); + Cudd_DeadAreCounted(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Group checking criterion: %d\n", - Cudd_ReadGroupcheck(dd)); + (int) Cudd_ReadGroupcheck(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Symmetry violation threshold: %d\n", - Cudd_ReadSymmviolation(dd)); + Cudd_ReadSymmviolation(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Arc violation threshold: %d\n", - Cudd_ReadArcviolation(dd)); + Cudd_ReadArcviolation(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"GA population size: %d\n", - Cudd_ReadPopulationSize(dd)); + Cudd_ReadPopulationSize(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of crossovers for GA: %d\n", - Cudd_ReadNumberXovers(dd)); + Cudd_ReadNumberXovers(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Next reordering threshold: %u\n", - Cudd_ReadNextReordering(dd)); + Cudd_ReadNextReordering(dd)); if (retval == EOF) return(0); /* Non-modifiable parameters. */ retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); if (retval == EOF) return(0); - retval = fprintf(fp,"Memory in use: %ld\n", Cudd_ReadMemoryInUse(dd)); + retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Peak number of nodes: %ld\n", - Cudd_ReadPeakNodeCount(dd)); + Cudd_ReadPeakNodeCount(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Peak number of live nodes: %d\n", - Cudd_ReadPeakLiveNodeCount(dd)); + Cudd_ReadPeakLiveNodeCount(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); if (retval == EOF) return(0); @@ -2997,36 +3027,36 @@ Cudd_PrintInfo( retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache look-ups: %.0f\n", - Cudd_ReadCacheLookUps(dd)); + Cudd_ReadCacheLookUps(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache hits: %.0f\n", - Cudd_ReadCacheHits(dd)); + Cudd_ReadCacheHits(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache insertions: %.0f\n", - dd->cacheinserts); + dd->cacheinserts); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache collisions: %.0f\n", - dd->cachecollisions); + dd->cachecollisions); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache deletions: %.0f\n", - dd->cachedeletions); + dd->cachedeletions); if (retval == EOF) return(0); retval = cuddCacheProfile(dd,fp); if (retval == 0) return(0); retval = fprintf(fp,"Soft limit for cache size: %u\n", - Cudd_ReadMaxCache(dd)); + Cudd_ReadMaxCache(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); if (retval == EOF) return(0); retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", - 100.0 * Cudd_ReadUsedSlots(dd), - 100.0 * Cudd_ExpectedUsedSlots(dd)); + 100.0 * Cudd_ReadUsedSlots(dd), + 100.0 * Cudd_ExpectedUsedSlots(dd)); if (retval == EOF) return(0); #ifdef DD_UNIQUE_PROFILE retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); if (retval == EOF) return(0); retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", - dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); + dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); if (retval == EOF) return(0); #endif retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); @@ -3038,36 +3068,36 @@ Cudd_PrintInfo( retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); if (retval == EOF) return(0); retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", - dd->allocated); + dd->allocated); if (retval == EOF) return(0); retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", - dd->reclaimed); + dd->reclaimed); if (retval == EOF) return(0); -#if DD_STATS +#ifdef DD_STATS retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); if (retval == EOF) return(0); retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); if (retval == EOF) return(0); #endif -#if DD_COUNT +#ifdef DD_COUNT retval = fprintf(fp,"Number of recursive calls: %.0f\n", - Cudd_ReadRecursiveCalls(dd)); + Cudd_ReadRecursiveCalls(dd)); if (retval == EOF) return(0); #endif retval = fprintf(fp,"Garbage collections so far: %d\n", - Cudd_ReadGarbageCollections(dd)); + Cudd_ReadGarbageCollections(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", - ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); + ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); if (retval == EOF) return(0); retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); if (retval == EOF) return(0); retval = fprintf(fp,"Time for reordering: %.2f sec\n", - ((double)Cudd_ReadReorderingTime(dd)/1000.0)); + ((double)Cudd_ReadReorderingTime(dd)/1000.0)); if (retval == EOF) return(0); -#if DD_COUNT +#ifdef DD_COUNT retval = fprintf(fp,"Node swaps in reordering: %.0f\n", - Cudd_ReadSwapSteps(dd)); + Cudd_ReadSwapSteps(dd)); if (retval == EOF) return(0); #endif @@ -3097,8 +3127,8 @@ Cudd_ReadPeakNodeCount( DdNodePtr *scan = dd->memoryList; while (scan != NULL) { - count += DD_MEM_CHUNK; - scan = (DdNodePtr *) *scan; + count += DD_MEM_CHUNK; + scan = (DdNodePtr *) *scan; } return(count); @@ -3125,7 +3155,7 @@ Cudd_ReadPeakLiveNodeCount( unsigned int live = dd->keys - dd->dead; if (live > dd->peakLiveNodes) { - dd->peakLiveNodes = live; + dd->peakLiveNodes = live; } return((int)dd->peakLiveNodes); @@ -3157,13 +3187,13 @@ Cudd_ReadNodeCount( cuddClearDeathRow(dd); #endif - count = dd->keys - dd->dead; + count = (long) (dd->keys - dd->dead); /* Count isolated projection functions. Their number is subtracted ** from the node count because they are not part of the BDDs. */ for (i=0; i < dd->size; i++) { - if (dd->vars[i]->ref == 1) count--; + if (dd->vars[i]->ref == 1) count--; } /* Subtract from the count the unused constants. */ if (DD_ZERO(dd)->ref == 1) count--; @@ -3192,7 +3222,7 @@ long Cudd_zddReadNodeCount( DdManager * dd) { - return(dd->keysZ - dd->deadZ + 2); + return((long)(dd->keysZ - dd->deadZ + 2)); } /* end of Cudd_zddReadNodeCount */ @@ -3214,43 +3244,43 @@ Cudd_zddReadNodeCount( int Cudd_AddHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook **hook, *nextHook, *newHook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = &(dd->preGCHook); - break; + hook = &(dd->preGCHook); + break; case CUDD_POST_GC_HOOK: - hook = &(dd->postGCHook); - break; + hook = &(dd->postGCHook); + break; case CUDD_PRE_REORDERING_HOOK: - hook = &(dd->preReorderingHook); - break; + hook = &(dd->preReorderingHook); + break; case CUDD_POST_REORDERING_HOOK: - hook = &(dd->postReorderingHook); - break; + hook = &(dd->postReorderingHook); + break; default: - return(0); + return(0); } /* Scan the list and find whether the function is already there. ** If so, just return. */ nextHook = *hook; while (nextHook != NULL) { - if (nextHook->f == f) { - return(2); - } - hook = &(nextHook->next); - nextHook = nextHook->next; + if (nextHook->f == f) { + return(2); + } + hook = &(nextHook->next); + nextHook = nextHook->next; } /* The function was not in the list. Create a new item and append it ** to the end of the list. */ newHook = ABC_ALLOC(DdHook,1); if (newHook == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } newHook->next = NULL; newHook->f = f; @@ -3276,36 +3306,36 @@ Cudd_AddHook( int Cudd_RemoveHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook **hook, *nextHook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = &(dd->preGCHook); - break; + hook = &(dd->preGCHook); + break; case CUDD_POST_GC_HOOK: - hook = &(dd->postGCHook); - break; + hook = &(dd->postGCHook); + break; case CUDD_PRE_REORDERING_HOOK: - hook = &(dd->preReorderingHook); - break; + hook = &(dd->preReorderingHook); + break; case CUDD_POST_REORDERING_HOOK: - hook = &(dd->postReorderingHook); - break; + hook = &(dd->postReorderingHook); + break; default: - return(0); + return(0); } nextHook = *hook; while (nextHook != NULL) { - if (nextHook->f == f) { - *hook = nextHook->next; - ABC_FREE(nextHook); - return(1); - } - hook = &(nextHook->next); - nextHook = nextHook->next; + if (nextHook->f == f) { + *hook = nextHook->next; + ABC_FREE(nextHook); + return(1); + } + hook = &(nextHook->next); + nextHook = nextHook->next; } return(0); @@ -3329,33 +3359,33 @@ Cudd_RemoveHook( int Cudd_IsInHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook *hook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = dd->preGCHook; - break; + hook = dd->preGCHook; + break; case CUDD_POST_GC_HOOK: - hook = dd->postGCHook; - break; + hook = dd->postGCHook; + break; case CUDD_PRE_REORDERING_HOOK: - hook = dd->preReorderingHook; - break; + hook = dd->preReorderingHook; + break; case CUDD_POST_REORDERING_HOOK: - hook = dd->postReorderingHook; - break; + hook = dd->postReorderingHook; + break; default: - return(0); + return(0); } /* Scan the list and find whether the function is already there. */ while (hook != NULL) { - if (hook->f == f) { - return(1); - } - hook = hook->next; + if (hook->f == f) { + return(1); + } + hook = hook->next; } return(0); @@ -3378,7 +3408,7 @@ Cudd_IsInHook( int Cudd_StdPreReordHook( DdManager *dd, - char *str, + const char *str, void *data) { Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; @@ -3394,60 +3424,60 @@ Cudd_StdPreReordHook( case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: case CUDD_REORDER_LINEAR_CONVERGE: - retval = fprintf(dd->out,"converging "); - if (retval == EOF) return(0); - break; + retval = fprintf(dd->out,"converging "); + if (retval == EOF) return(0); + break; default: - break; + break; } switch (method) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - retval = fprintf(dd->out,"random"); - break; + retval = fprintf(dd->out,"random"); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: - retval = fprintf(dd->out,"sifting"); - break; + retval = fprintf(dd->out,"sifting"); + break; case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: - retval = fprintf(dd->out,"symmetric sifting"); - break; + retval = fprintf(dd->out,"symmetric sifting"); + break; case CUDD_REORDER_LAZY_SIFT: - retval = fprintf(dd->out,"lazy sifting"); - break; + retval = fprintf(dd->out,"lazy sifting"); + break; case CUDD_REORDER_GROUP_SIFT: case CUDD_REORDER_GROUP_SIFT_CONV: - retval = fprintf(dd->out,"group sifting"); - break; + retval = fprintf(dd->out,"group sifting"); + break; case CUDD_REORDER_WINDOW2: case CUDD_REORDER_WINDOW3: case CUDD_REORDER_WINDOW4: case CUDD_REORDER_WINDOW2_CONV: case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: - retval = fprintf(dd->out,"window"); - break; + retval = fprintf(dd->out,"window"); + break; case CUDD_REORDER_ANNEALING: - retval = fprintf(dd->out,"annealing"); - break; + retval = fprintf(dd->out,"annealing"); + break; case CUDD_REORDER_GENETIC: - retval = fprintf(dd->out,"genetic"); - break; + retval = fprintf(dd->out,"genetic"); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - retval = fprintf(dd->out,"linear sifting"); - break; + retval = fprintf(dd->out,"linear sifting"); + break; case CUDD_REORDER_EXACT: - retval = fprintf(dd->out,"exact"); - break; + retval = fprintf(dd->out,"exact"); + break; default: - return(0); + return(0); } if (retval == EOF) return(0); retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? - Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); if (retval == EOF) return(0); fflush(dd->out); return(1); @@ -3471,7 +3501,7 @@ Cudd_StdPreReordHook( int Cudd_StdPostReordHook( DdManager *dd, - char *str, + const char *str, void *data) { long initialTime = (long) data; @@ -3480,8 +3510,8 @@ Cudd_StdPostReordHook( double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? - Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), - totalTimeSec); + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), + totalTimeSec); if (retval == EOF) return(0); retval = fflush(dd->out); if (retval == EOF) return(0); @@ -3508,10 +3538,10 @@ Cudd_EnableReorderingReporting( DdManager *dd) { if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { - return(0); + return(0); } if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { - return(0); + return(0); } return(1); @@ -3536,10 +3566,10 @@ Cudd_DisableReorderingReporting( DdManager *dd) { if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { - return(0); + return(0); } if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { - return(0); + return(0); } return(1); @@ -3822,7 +3852,7 @@ Cudd_SetMaxLive( SeeAlso [Cudd_SetMaxMemory] ******************************************************************************/ -long +unsigned long Cudd_ReadMaxMemory( DdManager *dd) { @@ -3846,7 +3876,7 @@ Cudd_ReadMaxMemory( void Cudd_SetMaxMemory( DdManager *dd, - long maxMemory) + unsigned long maxMemory) { dd->maxmemhard = maxMemory; @@ -4145,7 +4175,7 @@ Cudd_bddSetVarToBeGrouped( { if (index >= dd->size || index < 0) return(0); if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { - dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; } return(1); @@ -4196,8 +4226,8 @@ Cudd_bddResetVarToBeGrouped( { if (index >= dd->size || index < 0) return(0); if (dd->subtables[dd->perm[index]].varToBeGrouped <= - CUDD_LAZY_SOFT_GROUP) { - dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; + CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; } return(1); @@ -4223,9 +4253,9 @@ Cudd_bddIsVarToBeGrouped( { if (index >= dd->size || index < 0) return(-1); if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) - return(0); + return(0); else - return(dd->subtables[dd->perm[index]].varToBeGrouped); + return(dd->subtables[dd->perm[index]].varToBeGrouped); } /* end of Cudd_bddIsVarToBeGrouped */ @@ -4300,7 +4330,7 @@ Cudd_bddIsVarHardGroup( { if (index >= dd->size || index < 0) return(-1); if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) - return(1); + return(1); return(0); } /* end of Cudd_bddIsVarToBeGrouped */ @@ -4334,11 +4364,11 @@ fixVarTree( { treenode->index = treenode->low; treenode->low = ((int) treenode->index < size) ? - perm[treenode->index] : treenode->index; + perm[treenode->index] : treenode->index; if (treenode->child != NULL) - fixVarTree(treenode->child, perm, size); + fixVarTree(treenode->child, perm, size); if (treenode->younger != NULL) - fixVarTree(treenode->younger, perm, size); + fixVarTree(treenode->younger, perm, size); return; } /* end of fixVarTree */ @@ -4382,33 +4412,34 @@ addMultiplicityGroups( MtrNode *auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); - } - /* Build remaining groups. */ - startV = dd->permZ[auxnode->index] / multiplicity; - startL = auxnode->low / multiplicity; - stopV = startV + auxnode->size / multiplicity; - /* Walk down vmask starting at startV and build missing groups. */ - for (i = startV, j = startL; i < stopV; i++) { - if (vmask[i] == 0) { - MtrNode *node; - while (lmask[j] == 1) j++; - node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, - MTR_FIXED); - if (node == NULL) { - return(0); + if (auxnode->child != NULL) { + addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); } - node->index = dd->invpermZ[i * multiplicity]; - vmask[i] = 1; - lmask[j] = 1; + /* Build remaining groups. */ + startV = dd->permZ[auxnode->index] / multiplicity; + startL = auxnode->low / multiplicity; + stopV = startV + auxnode->size / multiplicity; + /* Walk down vmask starting at startV and build missing groups. */ + for (i = startV, j = startL; i < stopV; i++) { + if (vmask[i] == 0) { + MtrNode *node; + while (lmask[j] == 1) j++; + node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, + MTR_FIXED); + if (node == NULL) { + return(0); + } + node->index = dd->invpermZ[i * multiplicity]; + vmask[i] = 1; + lmask[j] = 1; + } } - } - auxnode = auxnode->younger; + auxnode = auxnode->younger; } return(1); } /* end of addMultiplicityGroups */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddAbs.c b/src/bdd/cudd/cuddAddAbs.c index 40d3222b..f420f99e 100644 --- a/src/bdd/cudd/cuddAddAbs.c +++ b/src/bdd/cudd/cuddAddAbs.c @@ -7,37 +7,65 @@ Synopsis [Quantification functions for ADDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_addExistAbstract() - <li> Cudd_addUnivAbstract() - <li> Cudd_addOrAbstract() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddExistAbstractRecur() - <li> cuddAddUnivAbstractRecur() - <li> cuddAddOrAbstractRecur() - </ul> - Static procedures included in this module: - <ul> - <li> addCheckPositiveCube() - </ul>] + <ul> + <li> Cudd_addExistAbstract() + <li> Cudd_addUnivAbstract() + <li> Cudd_addOrAbstract() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddExistAbstractRecur() + <li> cuddAddUnivAbstractRecur() + <li> cuddAddOrAbstractRecur() + </ul> + Static procedures included in this module: + <ul> + <li> addCheckPositiveCube() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,10 +86,10 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.15 2004/08/13 18:04:45 fabio Exp $"; #endif -static DdNode *two; +static DdNode *two; /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -74,7 +102,7 @@ static DdNode *two; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int addCheckPositiveCube ARGS((DdManager *manager, DdNode *cube)); +static int addCheckPositiveCube (DdManager *manager, DdNode *cube); /**AutomaticEnd***************************************************************/ @@ -115,13 +143,13 @@ Cudd_addExistAbstract( } do { - manager->reordered = 0; - res = cuddAddExistAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(manager,two); - return(NULL); + Cudd_RecursiveDeref(manager,two); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,two); @@ -152,16 +180,16 @@ Cudd_addUnivAbstract( DdNode * f, DdNode * cube) { - DdNode *res; + DdNode *res; if (addCheckPositiveCube(manager, cube) == 0) { - (void) fprintf(manager->err,"Error: Can only abstract cubes"); - return(NULL); + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); } do { - manager->reordered = 0; - res = cuddAddUnivAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddUnivAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -198,8 +226,8 @@ Cudd_addOrAbstract( } do { - manager->reordered = 0; - res = cuddAddOrAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddOrAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -230,38 +258,38 @@ cuddAddExistAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *zero; + DdNode *T, *E, *res, *res1, *res2, *zero; statLine(manager); zero = DD_ZERO(manager); - /* Cube is guaranteed to be a cube at this point. */ + /* Cube is guaranteed to be a cube at this point. */ if (f == zero || cuddIsConstant(cube)) { return(f); } /* Abstract a variable that does not appear in f => multiply by 2. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); - if (res == NULL) { + res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); + cuddDeref(res); return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -269,49 +297,49 @@ cuddAddExistAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); - if (res == NULL) { + res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddExistAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddExistAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); return(res); - } + } } /* end of cuddAddExistAbstractRecur */ @@ -335,7 +363,7 @@ cuddAddUnivAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *one, *zero; + DdNode *T, *E, *res, *res1, *res2, *one, *zero; statLine(manager); one = DD_ONE(manager); @@ -345,31 +373,31 @@ cuddAddUnivAbstractRecur( ** zero and one are the only constatnts c such that c*c=c. */ if (f == zero || f == one || cube == one) { - return(f); + return(f); } /* Abstract a variable that does not appear in f. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); - if (res == NULL) { + res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -377,47 +405,47 @@ cuddAddUnivAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); - if (res == NULL) { + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddUnivAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddUnivAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddUnivAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddUnivAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); return(res); } @@ -443,38 +471,24 @@ cuddAddOrAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *one; + DdNode *T, *E, *res, *res1, *res2, *one; statLine(manager); one = DD_ONE(manager); /* Cube is guaranteed to be a cube at this point. */ if (cuddIsConstant(f) || cube == one) { - return(f); + return(f); } /* Abstract a variable that does not appear in f. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res1); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); - return(res); + res = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); + return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -482,51 +496,51 @@ cuddAddOrAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - if (res1 != one) { - res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); + if (res1 != one) { + res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + } else { + res = res1; } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - } else { - res = res1; - } - cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddOrAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddOrAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddOrAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddOrAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); return(res); } @@ -567,5 +581,8 @@ addCheckPositiveCube( } /* end of addCheckPositiveCube */ + ABC_NAMESPACE_IMPL_END + + diff --git a/src/bdd/cudd/cuddAddApply.c b/src/bdd/cudd/cuddAddApply.c index 5bdc5773..7bea5871 100644 --- a/src/bdd/cudd/cuddAddApply.c +++ b/src/bdd/cudd/cuddAddApply.c @@ -7,47 +7,75 @@ Synopsis [Apply functions for ADDs and their operators.] Description [External procedures included in this module: - <ul> - <li> Cudd_addApply() - <li> Cudd_addMonadicApply() - <li> Cudd_addPlus() - <li> Cudd_addTimes() - <li> Cudd_addThreshold() - <li> Cudd_addSetNZ() - <li> Cudd_addDivide() - <li> Cudd_addMinus() - <li> Cudd_addMinimum() - <li> Cudd_addMaximum() - <li> Cudd_addOneZeroMaximum() - <li> Cudd_addDiff() - <li> Cudd_addAgreement() - <li> Cudd_addOr() - <li> Cudd_addNand() - <li> Cudd_addNor() - <li> Cudd_addXor() - <li> Cudd_addXnor() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddApplyRecur() - <li> cuddAddMonadicApplyRecur() - </ul>] + <ul> + <li> Cudd_addApply() + <li> Cudd_addMonadicApply() + <li> Cudd_addPlus() + <li> Cudd_addTimes() + <li> Cudd_addThreshold() + <li> Cudd_addSetNZ() + <li> Cudd_addDivide() + <li> Cudd_addMinus() + <li> Cudd_addMinimum() + <li> Cudd_addMaximum() + <li> Cudd_addOneZeroMaximum() + <li> Cudd_addDiff() + <li> Cudd_addAgreement() + <li> Cudd_addOr() + <li> Cudd_addNand() + <li> Cudd_addNor() + <li> Cudd_addXor() + <li> Cudd_addXnor() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddApplyRecur() + <li> cuddAddMonadicApplyRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at Boulder. - The University of Colorado at Boulder makes no warranty about the - suitability of this software for any purpose. It is presented on an - AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,7 +96,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.18 2009/02/19 16:15:26 fabio Exp $"; #endif @@ -109,15 +137,15 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23: DdNode * Cudd_addApply( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode **, DdNode **), + DD_AOP op, DdNode * f, DdNode * g) { DdNode *res; do { - dd->reordered = 0; - res = cuddAddApplyRecur(dd,op,f,g); + dd->reordered = 0; + res = cuddAddApplyRecur(dd,op,f,g); } while (dd->reordered == 1); return(res); @@ -150,13 +178,13 @@ Cudd_addPlus( if (F == DD_ZERO(dd)) return(G); if (G == DD_ZERO(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)+cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)+cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -191,13 +219,13 @@ Cudd_addTimes( if (F == DD_ONE(dd)) return(G); if (G == DD_ONE(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)*cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)*cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -227,11 +255,11 @@ Cudd_addThreshold( F = *f; G = *g; if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) >= cuddV(G)) { - return(F); - } else { - return(DD_ZERO(dd)); - } + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(DD_ZERO(dd)); + } } return(NULL); @@ -296,9 +324,9 @@ Cudd_addDivide( if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); if (G == DD_ONE(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)/cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)/cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -332,9 +360,9 @@ Cudd_addMinus( if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); if (G == DD_ZERO(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)-cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)-cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -371,15 +399,15 @@ Cudd_addMinimum( if (G == DD_MINUS_INFINITY(dd)) return(G); #endif if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) <= cuddV(G)) { - return(F); - } else { - return(G); - } + if (cuddV(F) <= cuddV(G)) { + return(F); + } else { + return(G); + } } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -416,15 +444,15 @@ Cudd_addMaximum( if (G == DD_PLUS_INFINITY(dd)) return(G); #endif if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) >= cuddV(G)) { - return(F); - } else { - return(G); - } + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(G); + } } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -453,13 +481,13 @@ Cudd_addOneZeroMaximum( if (*f == *g) return(DD_ZERO(dd)); if (*g == DD_PLUS_INFINITY(dd)) - return DD_ZERO(dd); + return DD_ZERO(dd); if (cuddIsConstant(*f) && cuddIsConstant(*g)) { - if (cuddV(*f) > cuddV(*g)) { - return(DD_ONE(dd)); - } else { - return(DD_ZERO(dd)); - } + if (cuddV(*f) > cuddV(*g)) { + return(DD_ONE(dd)); + } else { + return(DD_ZERO(dd)); + } } return(NULL); @@ -492,15 +520,15 @@ Cudd_addDiff( if (F == DD_PLUS_INFINITY(dd)) return(G); if (G == DD_PLUS_INFINITY(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) != cuddV(G)) { + if (cuddV(F) != cuddV(G)) { if (cuddV(F) < cuddV(G)) { return(F); } else { return(G); } - } else { - return(DD_PLUS_INFINITY(dd)); - } + } else { + return(DD_PLUS_INFINITY(dd)); + } } return(NULL); @@ -563,8 +591,8 @@ Cudd_addOr( if (cuddIsConstant(G)) return(F); if (F == G) return(F); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -595,8 +623,8 @@ Cudd_addNand( if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -627,8 +655,8 @@ Cudd_addNor( if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -661,8 +689,8 @@ Cudd_addXor( if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -695,8 +723,8 @@ Cudd_addXnor( if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -718,14 +746,14 @@ Cudd_addXnor( DdNode * Cudd_addMonadicApply( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode *), + DD_MAOP op, DdNode * f) { DdNode *res; do { - dd->reordered = 0; - res = cuddAddMonadicApplyRecur(dd,op,f); + dd->reordered = 0; + res = cuddAddMonadicApplyRecur(dd,op,f); } while (dd->reordered == 1); return(res); @@ -751,9 +779,9 @@ Cudd_addLog( DdNode * f) { if (cuddIsConstant(f)) { - CUDD_VALUE_TYPE value = log(cuddV(f)); - DdNode *res = cuddUniqueConst(dd,value); - return(res); + CUDD_VALUE_TYPE value = log(cuddV(f)); + DdNode *res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -780,16 +808,16 @@ Cudd_addLog( DdNode * cuddAddApplyRecur( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode **, DdNode **), + DD_AOP op, DdNode * f, DdNode * g) { DdNode *res, - *fv, *fvn, *gv, *gvn, - *T, *E; + *fv, *fvn, *gv, *gvn, + *T, *E; unsigned int ford, gord; unsigned int index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; /* Check terminal cases. Op may swap f and g to increase the * cache hit rate. @@ -799,7 +827,7 @@ cuddAddApplyRecur( if (res != NULL) return(res); /* Check cache. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) op; + cacheOp = (DD_CTFP) op; res = cuddCacheLookup2(dd,cacheOp,f,g); if (res != NULL) return(res); @@ -807,18 +835,18 @@ cuddAddApplyRecur( ford = cuddI(dd,f->index); gord = cuddI(dd,g->index); if (ford <= gord) { - index = f->index; - fv = cuddT(f); - fvn = cuddE(f); + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); } else { - index = g->index; - fv = fvn = f; + index = g->index; + fv = fvn = f; } if (gord <= ford) { - gv = cuddT(g); - gvn = cuddE(g); + gv = cuddT(g); + gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } T = cuddAddApplyRecur(dd,op,fv,gv); @@ -827,16 +855,16 @@ cuddAddApplyRecur( E = cuddAddApplyRecur(dd,op,fvn,gvn); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -864,11 +892,10 @@ cuddAddApplyRecur( DdNode * cuddAddMonadicApplyRecur( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode *), + DD_MAOP op, DdNode * f) { DdNode *res, *ft, *fe, *T, *E; - unsigned int ford; unsigned int index; /* Check terminal cases. */ @@ -881,7 +908,6 @@ cuddAddMonadicApplyRecur( if (res != NULL) return(res); /* Recursive step. */ - ford = cuddI(dd,f->index); index = f->index; ft = cuddT(f); fe = cuddE(f); @@ -892,16 +918,16 @@ cuddAddMonadicApplyRecur( E = cuddAddMonadicApplyRecur(dd,op,fe); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -918,5 +944,6 @@ cuddAddMonadicApplyRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddFind.c b/src/bdd/cudd/cuddAddFind.c index 6cc58f2d..4d63965d 100644 --- a/src/bdd/cudd/cuddAddFind.c +++ b/src/bdd/cudd/cuddAddFind.c @@ -8,22 +8,49 @@ extract the i-th bit.] Description [External procedures included in this module: - <ul> - <li> Cudd_addFindMax() - <li> Cudd_addFindMin() - <li> Cudd_addIthBit() - </ul> - Static functions included in this module: - <ul> - <li> addDoIthBit() - </ul>] + <ul> + <li> Cudd_addFindMax() + <li> Cudd_addFindMin() + <li> Cudd_addIthBit() + </ul> + Static functions included in this module: + <ul> + <li> addDoIthBit() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -33,6 +60,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.8 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -61,6 +89,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5 /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -68,10 +99,13 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index)); +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -95,12 +129,12 @@ Cudd_addFindMax( statLine(dd); if (cuddIsConstant(f)) { - return(f); + return(f); } res = cuddCacheLookup1(dd,Cudd_addFindMax,f); if (res != NULL) { - return(res); + return(res); } t = Cudd_addFindMax(dd,cuddT(f)); @@ -135,12 +169,12 @@ Cudd_addFindMin( statLine(dd); if (cuddIsConstant(f)) { - return(f); + return(f); } res = cuddCacheLookup1(dd,Cudd_addFindMin,f); if (res != NULL) { - return(res); + return(res); } t = Cudd_addFindMin(dd,cuddT(f)); @@ -192,13 +226,13 @@ Cudd_addIthBit( cuddRef(index); do { - dd->reordered = 0; - res = addDoIthBit(dd, f, index); + dd->reordered = 0; + res = addDoIthBit(dd, f, index); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, index); - return(NULL); + Cudd_RecursiveDeref(dd, index); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, index); @@ -244,9 +278,9 @@ addDoIthBit( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - mask = 1 << ((int) cuddV(index)); - value = (int) cuddV(f); - return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); } /* Check cache. */ @@ -263,16 +297,16 @@ addDoIthBit( E = addDoIthBit(dd,fvn,index); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -284,5 +318,7 @@ addDoIthBit( } /* end of addDoIthBit */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAddInv.c b/src/bdd/cudd/cuddAddInv.c index 05650c0e..cae00ca1 100644 --- a/src/bdd/cudd/cuddAddInv.c +++ b/src/bdd/cudd/cuddAddInv.c @@ -7,20 +7,47 @@ Synopsis [Function to compute the scalar inverse of an ADD.] Description [External procedures included in this module: - <ul> - <li> Cudd_addScalarInverse() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddScalarInverseRecur() - </ul>] + <ul> + <li> Cudd_addScalarInverse() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddScalarInverseRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -31,6 +58,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,7 +79,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.9 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -97,12 +125,12 @@ Cudd_addScalarInverse( DdNode *res; if (!cuddIsConstant(epsilon)) { - (void) fprintf(dd->err,"Invalid epsilon\n"); - return(NULL); + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); } do { - dd->reordered = 0; - res = cuddAddScalarInverseRecur(dd,f,epsilon); + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); } while (dd->reordered == 1); return(res); @@ -135,10 +163,10 @@ cuddAddScalarInverseRecur( statLine(dd); if (cuddIsConstant(f)) { - if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); - value = 1.0 / cuddV(f); - res = cuddUniqueConst(dd,value); - return(res); + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); } res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); @@ -150,17 +178,19 @@ cuddAddScalarInverseRecur( e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); } + cuddDeref(t); + cuddDeref(e); cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); @@ -173,5 +203,7 @@ cuddAddScalarInverseRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAddIte.c b/src/bdd/cudd/cuddAddIte.c index def55537..67f1cf14 100644 --- a/src/bdd/cudd/cuddAddIte.c +++ b/src/bdd/cudd/cuddAddIte.c @@ -7,29 +7,56 @@ Synopsis [ADD ITE function and satellites.] Description [External procedures included in this module: - <ul> - <li> Cudd_addIte() - <li> Cudd_addIteConstant() - <li> Cudd_addEvalConst() - <li> Cudd_addCmpl() - <li> Cudd_addLeq() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddIteRecur() - <li> cuddAddCmplRecur() - </ul> - Static procedures included in this module: - <ul> - <li> addVarToConst() - </ul>] + <ul> + <li> Cudd_addIte() + <li> Cudd_addIteConstant() + <li> Cudd_addEvalConst() + <li> Cudd_addCmpl() + <li> Cudd_addLeq() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddIteRecur() + <li> cuddAddCmplRecur() + </ul> + Static procedures included in this module: + <ul> + <li> addVarToConst() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -39,6 +66,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.15 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -74,7 +102,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void addVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)); +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); /**AutomaticEnd***************************************************************/ @@ -107,8 +135,8 @@ Cudd_addIte( DdNode *res; do { - dd->reordered = 0; - res = cuddAddIteRecur(dd,f,g,h); + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); } while (dd->reordered == 1); return(res); @@ -144,7 +172,7 @@ Cudd_addIteConstant( statLine(dd); /* Trivial cases. */ - if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ return(g); } if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ @@ -155,7 +183,7 @@ Cudd_addIteConstant( addVarToConst(f,&g,&h,one,zero); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ + if (g == h) { /* ITE(F,G,G) = G */ return(g); } if (cuddIsConstant(g) && cuddIsConstant(h)) { @@ -169,7 +197,7 @@ Cudd_addIteConstant( /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { - return(DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } /* Check cache. */ @@ -180,7 +208,7 @@ Cudd_addIteConstant( /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf,v); /* v = top_var(F,G,H) */ + v = ddMin(topf,v); /* v = top_var(F,G,H) */ Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; @@ -199,13 +227,13 @@ Cudd_addIteConstant( /* Recursive step. */ t = Cudd_addIteConstant(dd,Fv,Gv,Hv); if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { - cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { - cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); return(t); @@ -279,24 +307,24 @@ Cudd_addEvalConst( /* Recursive step. */ if (Fv != zero) { - t = Cudd_addEvalConst(dd,Fv,Gv); - if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); - } - if (Fnv != zero) { - e = Cudd_addEvalConst(dd,Fnv,Gnv); - if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } - } - cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); - return(t); + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); } else { /* Fnv must be != zero */ - e = Cudd_addEvalConst(dd,Fnv,Gnv); - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); - return(e); + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); } } /* end of Cudd_addEvalConst */ @@ -323,8 +351,8 @@ Cudd_addCmpl( DdNode *res; do { - dd->reordered = 0; - res = cuddAddCmplRecur(dd,f); + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -358,39 +386,38 @@ Cudd_addLeq( statLine(dd); if (cuddIsConstant(f)) { - if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); - if (f == DD_MINUS_INFINITY(dd)) return(1); - if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ } if (g == DD_PLUS_INFINITY(dd)) return(1); if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ /* Check cache. */ - tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *))Cudd_addLeq,f,g); + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); if (tmp != NULL) { - return(tmp == DD_ONE(dd)); + return(tmp == DD_ONE(dd)); } /* Compute cofactors. One of f and g is not constant. */ topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); if (topf <= topg) { - fv = cuddT(f); fvn = cuddE(f); + fv = cuddT(f); fvn = cuddE(f); } else { - fv = fvn = f; + fv = fvn = f; } if (topg <= topf) { - gv = cuddT(g); gvn = cuddE(g); + gv = cuddT(g); gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); /* Store result in cache and return. */ - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *)) - Cudd_addLeq,f,g,Cudd_NotCond(DD_ONE(dd),res==0)); + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); return(res); } /* end of Cudd_addLeq */ @@ -424,13 +451,13 @@ cuddAddIteRecur( DdNode *one,*zero; DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; unsigned int topf,topg,toph,v; - int index = 0; // Suppress "might be used uninitialized" + int index; statLine(dd); /* Trivial cases. */ /* One variable cases. */ - if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ return(g); } if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ @@ -441,11 +468,11 @@ cuddAddIteRecur( addVarToConst(f,&g,&h,one,zero); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ + if (g == h) { /* ITE(F,G,G) = G */ return(g); } - if (g == one) { /* ITE(F,1,0) = F */ + if (g == one) { /* ITE(F,1,0) = F */ if (h == zero) return(f); } @@ -456,12 +483,12 @@ cuddAddIteRecur( /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - r = cuddUniqueInter(dd,(int)f->index,g,h); - return(r); + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); } if (topf < v && cuddT(f) == zero && cuddE(f) == one) { - r = cuddUniqueInter(dd,(int)f->index,h,g); - return(r); + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); } /* Check cache. */ @@ -472,20 +499,20 @@ cuddAddIteRecur( /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf,v); /* v = top_var(F,G,H) */ - index = f->index; + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } if (topg == v) { - index = g->index; + index = g->index; Gv = cuddT(g); Gnv = cuddE(g); } else { Gv = Gnv = g; } if (toph == v) { - index = h->index; + index = h->index; Hv = cuddT(h); Hnv = cuddE(h); } else { Hv = Hnv = h; @@ -498,16 +525,16 @@ cuddAddIteRecur( e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); if (r == NULL) { - Cudd_RecursiveDeref(dd,t); - Cudd_RecursiveDeref(dd,e); - return(NULL); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -545,14 +572,14 @@ cuddAddCmplRecur( if (cuddIsConstant(f)) { if (f == zero) { - return(one); - } else { - return(zero); - } + return(one); + } else { + return(zero); + } } r = cuddCacheLookup1(dd,Cudd_addCmpl,f); if (r != NULL) { - return(r); + return(r); } Fv = cuddT(f); Fnv = cuddE(f); @@ -561,15 +588,15 @@ cuddAddCmplRecur( cuddRef(t); e = cuddAddCmplRecur(dd,Fnv); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -606,13 +633,15 @@ addVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = one; + *gp = one; } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = zero; + *hp = zero; } } /* end of addVarToConst */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddNeg.c b/src/bdd/cudd/cuddAddNeg.c index d99d0357..c21c995a 100644 --- a/src/bdd/cudd/cuddAddNeg.c +++ b/src/bdd/cudd/cuddAddNeg.c @@ -4,35 +4,63 @@ PackageName [cudd] - Synopsis [function to compute the negation of an ADD.] + Synopsis [Function to compute the negation of an ADD.] Description [External procedures included in this module: - <ul> - <li> Cudd_addNegate() - <li> Cudd_addRoundOff() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddNegateRecur() - <li> cuddAddRoundOffRecur() - </ul> ] + <ul> + <li> Cudd_addNegate() + <li> Cudd_addRoundOff() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddNegateRecur() + <li> cuddAddRoundOffRecur() + </ul> ] Author [Fabio Somenzi, Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" +#include "util_hack.h" #include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.12 2009/02/20 02:14:58 fabio Exp $"; #endif @@ -96,7 +124,7 @@ Cudd_addNegate( DdNode *res; do { - res = cuddAddNegateRecur(dd,f); + res = cuddAddNegateRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -126,7 +154,7 @@ Cudd_addRoundOff( double trunc = pow(10.0,(double)N); do { - res = cuddAddRoundOffRecur(dd,f,trunc); + res = cuddAddRoundOffRecur(dd,f,trunc); } while (dd->reordered == 1); return(res); @@ -154,14 +182,14 @@ cuddAddNegateRecur( DdNode * f) { DdNode *res, - *fv, *fvn, - *T, *E; + *fv, *fvn, + *T, *E; statLine(dd); /* Check terminal cases. */ if (cuddIsConstant(f)) { - res = cuddUniqueConst(dd,-cuddV(f)); - return(res); + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); } /* Check cache */ @@ -177,15 +205,15 @@ cuddAddNegateRecur( E = cuddAddNegateRecur(dd,fvn); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -217,15 +245,15 @@ cuddAddRoundOffRecur( DdNode *res, *fv, *fvn, *T, *E; double n; - DdNode *(*cacheOp)(DdManager *, DdNode *); - + DD_CTFP1 cacheOp; + statLine(dd); if (cuddIsConstant(f)) { n = ceil(cuddV(f)*trunc)/trunc; - res = cuddUniqueConst(dd,n); - return(res); + res = cuddUniqueConst(dd,n); + return(res); } - cacheOp = (DdNode *(*)(DdManager *, DdNode *)) Cudd_addRoundOff; + cacheOp = (DD_CTFP1) Cudd_addRoundOff; res = cuddCacheLookup1(dd,cacheOp,f); if (res != NULL) { return(res); @@ -241,14 +269,14 @@ cuddAddRoundOffRecur( E = cuddAddRoundOffRecur(dd,fvn,trunc); if (E == NULL) { Cudd_RecursiveDeref(dd,T); - return(NULL); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -256,12 +284,13 @@ cuddAddRoundOffRecur( /* Store result. */ cuddCacheInsert1(dd,cacheOp,f,res); return(res); - + } /* end of cuddAddRoundOffRecur */ /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddWalsh.c b/src/bdd/cudd/cuddAddWalsh.c index 44b4415d..e8e8a641 100644 --- a/src/bdd/cudd/cuddAddWalsh.c +++ b/src/bdd/cudd/cuddAddWalsh.c @@ -8,21 +8,48 @@ functions in ADD form.] Description [External procedures included in this module: - <ul> - <li> Cudd_addWalsh() - <li> Cudd_addResidue() - </ul> - Static procedures included in this module: - <ul> - <li> addWalshInt() - </ul>] + <ul> + <li> Cudd_addWalsh() + <li> Cudd_addResidue() + </ul> + Static procedures included in this module: + <ul> + <li> addWalshInt() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -33,6 +60,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.10 2008/04/17 21:17:11 fabio Exp $"; #endif @@ -68,7 +96,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addWalshInt ARGS((DdManager *dd, DdNode **x, DdNode **y, int n)); +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); /**AutomaticEnd***************************************************************/ @@ -98,8 +126,8 @@ Cudd_addWalsh( DdNode *res; do { - dd->reordered = 0; - res = addWalshInt(dd, x, y, n); + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); } while (dd->reordered == 1); return(res); @@ -137,8 +165,8 @@ Cudd_addResidue( int options /* options */, int top /* index of top variable */) { - int msbLsb; /* MSB on top (1) or LSB on top (0) */ - int tc; /* two's complement (1) or unsigned (0) */ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ int i, j, k, t, residue, thisOne, previous, index; DdNode **array[2], *var, *tmp, *res; @@ -151,89 +179,89 @@ Cudd_addResidue( /* Allocate and initialize working arrays. */ array[0] = ABC_ALLOC(DdNode *,m); if (array[0] == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } array[1] = ABC_ALLOC(DdNode *,m); if (array[1] == NULL) { - ABC_FREE(array[0]); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + ABC_FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < m; i++) { - array[0][i] = array[1][i] = NULL; + array[0][i] = array[1][i] = NULL; } /* Initialize residues. */ for (i = 0; i < m; i++) { - tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); - if (tmp == NULL) { - for (j = 0; j < i; j++) { - Cudd_RecursiveDeref(dd,array[1][j]); + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); - } - cuddRef(tmp); - array[1][i] = tmp; + cuddRef(tmp); + array[1][i] = tmp; } /* Main iteration. */ - residue = 1; /* residue of 2**0 */ + residue = 1; /* residue of 2**0 */ for (k = 0; k < n; k++) { - /* Choose current and previous arrays. */ - thisOne = k & 1; - previous = thisOne ^ 1; - /* Build an ADD projection function. */ - if (msbLsb) { - index = top+n-k-1; - } else { - index = top+k; - } - var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); - if (var == NULL) { - for (j = 0; j < m; j++) { - Cudd_RecursiveDeref(dd,array[previous][j]); + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); - } - cuddRef(var); - for (i = 0; i < m; i ++) { - t = (i + residue) % m; - tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); - if (tmp == NULL) { - for (j = 0; j < i; j++) { - Cudd_RecursiveDeref(dd,array[thisOne][j]); + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); } - for (j = 0; j < m; j++) { - Cudd_RecursiveDeref(dd,array[previous][j]); + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; } - cuddRef(tmp); - array[thisOne][i] = tmp; - } - /* One layer completed. Free the other array for the next iteration. */ - for (i = 0; i < m; i++) { - Cudd_RecursiveDeref(dd,array[previous][i]); - } - Cudd_RecursiveDeref(dd,var); - /* Update residue of 2**k. */ - residue = (2 * residue) % m; - /* Adjust residue for MSB, if this is a two's complement number. */ - if (tc && (k == n - 1)) { - residue = (m - residue) % m; - } } /* We are only interested in the 0-residue node of the top layer. */ for (i = 1; i < m; i++) { - Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); } res = array[(n - 1) & 1][0]; @@ -274,8 +302,7 @@ addWalshInt( int n) { DdNode *one, *minusone; - DdNode *t = NULL; // Suppress "might be used uninitialized" - DdNode *u, *t1, *u1, *v, *w; + DdNode *t, *u, *t1, *u1, *v, *w; int i; one = DD_ONE(dd); @@ -287,84 +314,86 @@ addWalshInt( cuddRef(minusone); v = Cudd_addIte(dd, y[n-1], minusone, one); if (v == NULL) { - Cudd_RecursiveDeref(dd, minusone); - return(NULL); + Cudd_RecursiveDeref(dd, minusone); + return(NULL); } cuddRef(v); u = Cudd_addIte(dd, x[n-1], v, one); if (u == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, v); - return(NULL); + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); } cuddRef(u); Cudd_RecursiveDeref(dd, v); if (n>1) { - w = Cudd_addIte(dd, y[n-1], one, minusone); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(w); - t = Cudd_addIte(dd, x[n-1], w, minusone); - if (t == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, u); + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(t); - Cudd_RecursiveDeref(dd, w); } cuddDeref(minusone); /* minusone is in the result; it won't die */ /* Loop to build the rest of the ADD */ for (i=n-2; i>=0; i--) { - t1 = t; u1 = u; - v = Cudd_addIte(dd, y[i], t1, u1); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - return(NULL); - } - cuddRef(v); - u = Cudd_addIte(dd, x[i], v, u1); - if (u == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - if (i>0) { - w = Cudd_addIte(dd, y[i], u1, t1); - if (u == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, u); - return(NULL); + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); } - cuddRef(w); - t = Cudd_addIte(dd, x[i], w, t1); + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } Cudd_RecursiveDeref(dd, u1); Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(t); - Cudd_RecursiveDeref(dd, w); - } - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); } cuddDeref(u); return(u); } /* end of addWalshInt */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAndAbs.c b/src/bdd/cudd/cuddAndAbs.c index 10b057ac..2f38490d 100644 --- a/src/bdd/cudd/cuddAndAbs.c +++ b/src/bdd/cudd/cuddAndAbs.c @@ -7,20 +7,48 @@ Synopsis [Combined AND and existential abstraction for BDDs] Description [External procedures included in this module: - <ul> - <li> Cudd_bddAndAbstract() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddAndAbstractRecur() - </ul>] + <ul> + <li> Cudd_bddAndAbstract() + <li> Cudd_bddAndAbstractLimit() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddAndAbstractRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -31,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,7 +80,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.19 2004/08/13 18:04:46 fabio Exp $"; #endif @@ -101,8 +130,8 @@ Cudd_bddAndAbstract( DdNode *res; do { - manager->reordered = 0; - res = cuddBddAndAbstractRecur(manager, f, g, cube); + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); return(res); @@ -135,10 +164,11 @@ Cudd_bddAndAbstractLimit( { DdNode *res; unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; do { manager->reordered = 0; - manager->maxLive = (manager->keys - manager->dead) + - (manager->keysZ - manager->deadZ) + limit; res = cuddBddAndAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); manager->maxLive = saveLimit; @@ -147,7 +177,6 @@ Cudd_bddAndAbstractLimit( } /* end of Cudd_bddAndAbstractLimit */ - /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ @@ -184,23 +213,23 @@ cuddBddAndAbstractRecur( /* Terminal cases. */ if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); - if (f == one && g == one) return(one); + if (f == one && g == one) return(one); if (cube == one) { - return(cuddBddAndRecur(manager, f, g)); + return(cuddBddAndRecur(manager, f, g)); } if (f == one || f == g) { - return(cuddBddExistAbstractRecur(manager, g, cube)); + return(cuddBddExistAbstractRecur(manager, g, cube)); } if (g == one) { - return(cuddBddExistAbstractRecur(manager, f, cube)); + return(cuddBddExistAbstractRecur(manager, f, cube)); } /* At this point f, g, and cube are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } /* Here we can skip the use of cuddI, because the operands are known @@ -214,129 +243,132 @@ cuddBddAndAbstractRecur( topcube = manager->perm[cube->index]; while (topcube < top) { - cube = cuddT(cube); - if (cube == one) { - return(cuddBddAndRecur(manager, f, g)); - } - topcube = manager->perm[cube->index]; + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; } /* Now, topcube >= top. */ /* Check cache. */ if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); - if (r != NULL) { - return(r); - } + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } } + if ( manager->TimeStop && manager->TimeStop < clock() ) + 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); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg == top) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } - if (topcube == top) { /* quantify */ - DdNode *Cube = cuddT(cube); - t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); - if (t == NULL) return(NULL); - /* Special case: 1 OR anything = 1. Hence, no need to compute - ** the else branch if t is 1. Likewise t + t * anything == t. - ** Notice that t == fe implies that fe does not depend on the - ** variables in Cube. Likewise for t == ge. - */ - if (t == one || t == fe || t == ge) { - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, - f, g, cube, t); - return(t); - } - cuddRef(t); - /* Special case: t + !t * anything == t + anything. */ - if (t == Cudd_Not(fe)) { - e = cuddBddExistAbstractRecur(manager, ge, Cube); - } else if (t == Cudd_Not(ge)) { - e = cuddBddExistAbstractRecur(manager, fe, Cube); - } else { - e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); - } - if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - if (t == e) { - r = t; - cuddDeref(t); - } else { - cuddRef(e); - r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_DelayedDerefBdd(manager, t); - Cudd_DelayedDerefBdd(manager, e); - cuddDeref(r); - } - } else { - t = cuddBddAndAbstractRecur(manager, ft, gt, cube); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddBddAndAbstractRecur(manager, fe, ge, cube); - if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - if (t == e) { - r = t; - cuddDeref(t); - } else { - cuddRef(e); - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager, (int) index, - Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } - r = Cudd_Not(r); + if (t == e) { + r = t; + cuddDeref(t); } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); } - cuddDeref(e); - cuddDeref(t); - } } if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); return (r); } /* end of cuddBddAndAbstractRecur */ @@ -346,5 +378,7 @@ cuddBddAndAbstractRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAnneal.c b/src/bdd/cudd/cuddAnneal.c index c133cdc8..7a08b5ae 100644 --- a/src/bdd/cudd/cuddAnneal.c +++ b/src/bdd/cudd/cuddAnneal.c @@ -7,31 +7,58 @@ Synopsis [Reordering of DDs based on simulated annealing] Description [Internal procedures included in this file: - <ul> - <li> cuddAnnealing() - </ul> - Static procedures included in this file: - <ul> - <li> stopping_criterion() - <li> random_generator() - <li> ddExchange() - <li> ddJumpingAux() - <li> ddJumpingUp() - <li> ddJumpingDown() - <li> siftBackwardProb() - <li> copyOrder() - <li> restoreOrder() - </ul> - ] + <ul> + <li> cuddAnnealing() + </ul> + Static procedures included in this file: + <ul> + <li> stopping_criterion() + <li> random_generator() + <li> ddExchange() + <li> ddJumpingAux() + <li> ddJumpingUp() + <li> ddJumpingDown() + <li> siftBackwardProb() + <li> copyOrder() + <li> restoreOrder() + </ul> + ] SeeAlso [] Author [Jae-Young Jang, Jorgen Sivesind] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -41,6 +68,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,14 +96,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.14 2004/08/13 18:04:46 fabio Exp $"; #endif #ifdef DD_STATS -extern int ddTotalNumberSwapping; -extern int ddTotalNISwaps; -static int tosses; -static int acceptances; +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; #endif /*---------------------------------------------------------------------------*/ @@ -89,15 +117,15 @@ static int acceptances; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int stopping_criterion ARGS((int c1, int c2, int c3, int c4, double temp)); -static double random_generator ARGS(()); -static int ddExchange ARGS((DdManager *table, int x, int y, double temp)); -static int ddJumpingAux ARGS((DdManager *table, int x, int x_low, int x_high, double temp)); -static Move * ddJumpingUp ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * ddJumpingDown ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int siftBackwardProb ARGS((DdManager *table, Move *moves, int size, double temp)); -static void copyOrder ARGS((DdManager *table, int *array, int lower, int upper)); -static int restoreOrder ARGS((DdManager *table, int *array, int lower, int upper)); +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); /**AutomaticEnd***************************************************************/ @@ -136,11 +164,11 @@ cuddAnnealing( int size; int x,y; int result; - int c1, c2, c3, c4; - int BestCost; - int *BestOrder; - double NewTemp, temp; - double rand1; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; int innerloop, maxGen; int ecount, ucount, dcount; @@ -158,8 +186,8 @@ cuddAnnealing( BestCost = size; BestOrder = ABC_ALLOC(int,nvars); if (BestOrder == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } copyOrder(table,BestOrder,lower,upper); @@ -174,76 +202,76 @@ cuddAnnealing( while (!stopping_criterion(c1, c2, c3, c4, temp)) { #ifdef DD_STATS - (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", - temp,size,maxGen); - tosses = acceptances = 0; + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; #endif - for (innerloop = 0; innerloop < maxGen; innerloop++) { - /* Choose x, y randomly. */ - x = (int) Cudd_Random() % nvars; - do { - y = (int) Cudd_Random() % nvars; - } while (x == y); - x += lower; - y += lower; - if (x > y) { - int tmp = x; - x = y; - y = tmp; - } - - /* Choose move with roulette wheel. */ - rand1 = random_generator(); - if (rand1 < EXC_PROB) { - result = ddExchange(table,x,y,temp); /* exchange */ - ecount++; + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; #if 0 - (void) fprintf(table->out, - "Exchange of %d and %d: size = %d\n", - x,y,table->keys - table->isolated); + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); #endif - } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { - result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ - ucount++; + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; #if 0 - (void) fprintf(table->out, - "Jump up of %d to %d: size = %d\n", - y,x,table->keys - table->isolated); + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); #endif - } else { - result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ - dcount++; + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; #if 0 - (void) fprintf(table->out, - "Jump down of %d to %d: size = %d\n", - x,y,table->keys - table->isolated); + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); #endif + } + + if (!result) { + ABC_FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } } - - if (!result) { - ABC_FREE(BestOrder); - return(0); - } - - size = table->keys - table->isolated; /* keep current size */ - if (size < BestCost) { /* update best order */ - BestCost = size; - copyOrder(table,BestOrder,lower,upper); + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); } - } - c1 = c2; - c2 = c3; - c3 = c4; - c4 = size; - NewTemp = ALPHA * temp; - if (NewTemp >= 1.0) { - maxGen = (int)(log(NewTemp) / log(temp) * maxGen); - } - temp = NewTemp; /* control variable */ + temp = NewTemp; /* control variable */ #ifdef DD_STATS - (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", - tosses,acceptances); - fflush(table->out); + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); #endif } @@ -286,11 +314,11 @@ stopping_criterion( double temp) { if (STOP_TEMP < temp) { - return(0); + return(0); } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { - return(1); + return(1); } else { - return(0); + return(0); } } /* end of stopping_criterion */ @@ -308,8 +336,7 @@ stopping_criterion( ******************************************************************************/ static double -random_generator( - ) +random_generator(void) { return((double)(Cudd_Random() / 2147483561.0)); @@ -351,83 +378,83 @@ ddExchange( initial_size = limit_size = table->keys - table->isolated; for (;;) { - if (x_next == y_next) { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,y_next,y); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; - x = y; - y = tmp; - } else if (x == y_next) { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - tmp = x; - x = y; - y = tmp; - } else { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,y_next,y); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - x = x_next; - y = y_next; - } + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } - x_next = cuddNextHigh(table,x); - y_next = cuddNextLow(table,y); - if (x_next > y_ref) break; + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; - if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } } if (y_next>=x_ref) { @@ -447,16 +474,16 @@ ddExchange( if (!result) goto ddExchangeOutOfMem; while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(1); ddExchangeOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table,(DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } return(0); @@ -499,36 +526,36 @@ ddJumpingAux( moves = NULL; if (cuddNextLow(table,x) < x_low) { - if (cuddNextHigh(table,x) > x_high) return(1); - moves = ddJumpingDown(table,x,x_high,initial_size); - /* after that point x --> x_high unless early termination */ - if (moves == NULL) goto ddJumpingAuxOutOfMem; - /* move backward and stop at best position or accept uphill move */ - result = siftBackwardProb(table,moves,initial_size,temp); - if (!result) goto ddJumpingAuxOutOfMem; + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; } else if (cuddNextHigh(table,x) > x_high) { - moves = ddJumpingUp(table,x,x_low,initial_size); - /* after that point x --> x_low unless early termination */ - if (moves == NULL) goto ddJumpingAuxOutOfMem; - /* move backward and stop at best position or accept uphill move */ - result = siftBackwardProb(table,moves,initial_size,temp); - if (!result) goto ddJumpingAuxOutOfMem; + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; } else { - (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); - goto ddJumpingAuxOutOfMem; + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; } while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(1); ddJumpingAuxOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -564,30 +591,30 @@ ddJumpingUp( moves = NULL; y = cuddNextLow(table,x); while (y >= x_low) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) goto ddJumpingUpOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddJumpingUpOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > table->maxGrowth * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); } return(moves); ddJumpingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -623,30 +650,30 @@ ddJumpingDown( moves = NULL; y = cuddNextHigh(table,x); while (y <= x_high) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddJumpingDownOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddJumpingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > table->maxGrowth * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } - x = y; - y = cuddNextHigh(table,x); + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); } return(moves); ddJumpingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -681,9 +708,9 @@ siftBackwardProb( /* Look for best size during the last sifting */ for (move = moves; move != NULL; move = move->next) { - if (move->size < best_size) { - best_size = move->size; - } + if (move->size < best_size) { + best_size = move->size; + } } /* If best_size equals size, the last sifting did not produce any @@ -691,17 +718,17 @@ siftBackwardProb( ** this change or not. */ if (best_size == size) { - coin = random_generator(); + coin = random_generator(); #ifdef DD_STATS - tosses++; + tosses++; #endif - threshold = exp(-((double)(table->keys - table->isolated - size))/temp); - if (coin < threshold) { + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { #ifdef DD_STATS - acceptances++; + acceptances++; #endif - return(1); - } + return(1); + } } /* Either there was improvement, or we have decided not to @@ -709,9 +736,9 @@ siftBackwardProb( */ res = table->keys - table->isolated; for (move = moves; move != NULL; move = move->next) { - if (res == best_size) return(1); - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); } return(1); @@ -743,7 +770,7 @@ copyOrder( nvars = upper - lower + 1; for (i = 0; i < nvars; i++) { - array[i] = table->invperm[i+lower]; + array[i] = table->invperm[i+lower]; } } /* end of copyOrder */ @@ -772,22 +799,24 @@ restoreOrder( int nvars = upper - lower + 1; for (i = 0; i < nvars; i++) { - x = table->perm[array[i]]; + x = table->perm[array[i]]; #ifdef DD_DEBUG assert(x >= lower && x <= upper); #endif - y = cuddNextLow(table,x); - while (y >= i + lower) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) return(0); - x = y; y = cuddNextLow(table,x); - } + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } } return(1); } /* end of restoreOrder */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddApa.c b/src/bdd/cudd/cuddApa.c index 04dac030..82547b54 100644 --- a/src/bdd/cudd/cuddApa.c +++ b/src/bdd/cudd/cuddApa.c @@ -7,24 +7,66 @@ Synopsis [Arbitrary precision arithmetic functions.] Description [External procedures included in this module: - <ul> - <li> - </ul> - Internal procedures included in this module: - <ul> - <li> () - </ul> - Static procedures included in this module: - <ul> - <li> () - </ul>] + <ul> + <li> Cudd_ApaNumberOfDigits() + <li> Cudd_NewApaNumber() + <li> Cudd_ApaCopy() + <li> Cudd_ApaAdd() + <li> Cudd_ApaSubtract() + <li> Cudd_ApaShortDivision() + <li> Cudd_ApaIntDivision() + <li> Cudd_ApaShiftRight() + <li> Cudd_ApaSetToLiteral() + <li> Cudd_ApaPowerOfTwo() + <li> Cudd_ApaCompare() + <li> Cudd_ApaCompareRatios() + <li> Cudd_ApaPrintHex() + <li> Cudd_ApaPrintDecimal() + <li> Cudd_ApaPrintExponential() + <li> Cudd_ApaCountMinterm() + <li> Cudd_ApaPrintMinterm() + <li> Cudd_ApaPrintMintermExp() + <li> Cudd_ApaPrintDensity() + </ul> + Static procedures included in this module: + <ul> + <li> cuddApaCountMintermAux() + <li> cuddApaStCountfree() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -34,6 +76,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,15 +94,18 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.19 2009/03/08 01:27:50 fabio Exp $"; #endif -static DdNode *background, *zero; +static DdNode *background, *zero; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -67,11 +113,15 @@ static DdNode *background, *zero; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdApaNumber cuddApaCountMintermAux ARGS((DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table)); -static enum st_retval cuddApaStCountfree ARGS((char * key, char * value, char * arg)); +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -101,11 +151,11 @@ Cudd_ApaNumberOfDigits( digits = binaryDigits / DD_APA_BITS; if ((digits * DD_APA_BITS) != binaryDigits) - digits++; + digits++; return(digits); } /* end of Cudd_ApaNumberOfDigits */ - + /**Function******************************************************************** @@ -149,7 +199,7 @@ Cudd_ApaCopy( int i; for (i = 0; i < digits; i++) { - dest[i] = source[i]; + dest[i] = source[i]; } } /* end of Cudd_ApaCopy */ @@ -178,10 +228,10 @@ Cudd_ApaAdd( DdApaDoubleDigit partial = 0; for (i = digits - 1; i >= 0; i--) { - partial = a[i] + b[i] + DD_MSDIGIT(partial); - sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); } - return(DD_MSDIGIT(partial)); + return((DdApaDigit) DD_MSDIGIT(partial)); } /* end of Cudd_ApaAdd */ @@ -210,10 +260,10 @@ Cudd_ApaSubtract( DdApaDoubleDigit partial = DD_APA_BASE; for (i = digits - 1; i >= 0; i--) { - partial = a[i] - b[i] + DD_MSDIGIT(partial) + DD_APA_MASK; - diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); } - return(DD_MSDIGIT(partial) - 1); + return((DdApaDigit) DD_MSDIGIT(partial) - 1); } /* end of Cudd_ApaSubtract */ @@ -242,9 +292,9 @@ Cudd_ApaShortDivision( remainder = 0; for (i = 0; i < digits; i++) { - partial = remainder * DD_APA_BASE + dividend[i]; - quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); - remainder = (DdApaDigit) (partial % divisor); + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); } return(remainder); @@ -283,9 +333,9 @@ Cudd_ApaIntDivision( double ddiv = (double) divisor; for (i = 0; i < digits; i++) { - partial = (double) remainder * DD_APA_BASE + dividend[i]; - quotient[i] = (DdApaDigit) (partial / ddiv); - remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); } return(remainder); @@ -317,7 +367,7 @@ Cudd_ApaShiftRight( int i; for (i = digits - 1; i > 0; i--) { - b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); } b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); @@ -344,7 +394,7 @@ Cudd_ApaSetToLiteral( int i; for (i = 0; i < digits - 1; i++) - number[i] = 0; + number[i] = 0; number[digits - 1] = literal; } /* end of Cudd_ApaSetToLiteral */ @@ -373,7 +423,7 @@ Cudd_ApaPowerOfTwo( int index; for (i = 0; i < digits; i++) - number[i] = 0; + number[i] = 0; i = digits - 1 - power / DD_APA_BITS; if (i < 0) return; index = power & (DD_APA_BITS - 1); @@ -407,14 +457,14 @@ Cudd_ApaCompare( /* Find first non-zero in both numbers. */ for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) - if (first[firstNZ] != 0) break; + if (first[firstNZ] != 0) break; for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) - if (second[secondNZ] != 0) break; + if (second[secondNZ] != 0) break; if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); for (i = 0; i < digitsFirst - firstNZ; i++) { - if (first[firstNZ + i] > second[secondNZ + i]) return(1); - else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); } return(0); @@ -453,11 +503,13 @@ Cudd_ApaCompareRatios( second = Cudd_NewApaNumber(digitsSecond); secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + ABC_FREE(first); + ABC_FREE(second); if (result == 0) { - if ((double)firstRem/firstDen > (double)secondRem/secondDen) - return(1); - else if ((double)firstRem/firstDen < (double)secondRem/secondDen) - return(-1); + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); } return(result); @@ -485,9 +537,9 @@ Cudd_ApaPrintHex( int i, result; for (i = 0; i < digits; i++) { - result = fprintf(fp,DD_APA_HEXPRINT,number[i]); - if (result == EOF) - return(0); + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); } return(1); @@ -518,33 +570,33 @@ Cudd_ApaPrintDecimal( unsigned char *decimal; int leadingzero; int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; - + work = Cudd_NewApaNumber(digits); if (work == NULL) - return(0); + return(0); decimal = ABC_ALLOC(unsigned char, decimalDigits); if (decimal == NULL) { - ABC_FREE(work); - return(0); + ABC_FREE(work); + return(0); } Cudd_ApaCopy(digits,number,work); for (i = decimalDigits - 1; i >= 0; i--) { - remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); - decimal[i] = remainder; + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; } ABC_FREE(work); leadingzero = 1; for (i = 0; i < decimalDigits; i++) { - leadingzero = leadingzero && (decimal[i] == 0); - if ((!leadingzero) || (i == (decimalDigits - 1))) { - result = fprintf(fp,"%1d",decimal[i]); - if (result == EOF) { - ABC_FREE(decimal); - return(0); + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + ABC_FREE(decimal); + return(0); + } } } - } ABC_FREE(decimal); return(1); @@ -575,36 +627,36 @@ Cudd_ApaPrintExponential( DdApaNumber work; unsigned char *decimal; int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; - + work = Cudd_NewApaNumber(digits); if (work == NULL) - return(0); + return(0); decimal = ABC_ALLOC(unsigned char, decimalDigits); if (decimal == NULL) { - ABC_FREE(work); - return(0); + ABC_FREE(work); + return(0); } Cudd_ApaCopy(digits,number,work); first = decimalDigits - 1; for (i = decimalDigits - 1; i >= 0; i--) { - remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); - decimal[i] = remainder; - if (remainder != 0) first = i; /* keep track of MS non-zero */ + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ } ABC_FREE(work); last = ddMin(first + precision, decimalDigits); for (i = first; i < last; i++) { - result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); - if (result == EOF) { - ABC_FREE(decimal); - return(0); - } + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + ABC_FREE(decimal); + return(0); + } } ABC_FREE(decimal); result = fprintf(fp,"e+%d",decimalDigits - first - 1); if (result == EOF) { - return(0); + return(0); } return(1); @@ -635,9 +687,9 @@ Cudd_ApaCountMinterm( int nvars, int * digits) { - DdApaNumber max, min; + DdApaNumber max, min; st_table *table; - DdApaNumber i,count; + DdApaNumber i,count; background = manager->background; zero = Cudd_Not(manager->one); @@ -645,46 +697,46 @@ Cudd_ApaCountMinterm( *digits = Cudd_ApaNumberOfDigits(nvars+1); max = Cudd_NewApaNumber(*digits); if (max == NULL) { - return(NULL); + return(NULL); } Cudd_ApaPowerOfTwo(*digits,max,nvars); min = Cudd_NewApaNumber(*digits); if (min == NULL) { - ABC_FREE(max); - return(NULL); + ABC_FREE(max); + return(NULL); } Cudd_ApaSetToLiteral(*digits,min,0); - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - ABC_FREE(max); - ABC_FREE(min); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + return(NULL); } i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); if (i == NULL) { - ABC_FREE(max); - ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); - st_free_table(table); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); } count = Cudd_NewApaNumber(*digits); if (count == NULL) { - ABC_FREE(max); - ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); - st_free_table(table); - if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); + return(NULL); } if (Cudd_IsComplement(node)) { - (void) Cudd_ApaSubtract(*digits,max,i,count); + (void) Cudd_ApaSubtract(*digits,max,i,count); } else { - Cudd_ApaCopy(*digits,i,count); + Cudd_ApaCopy(*digits,i,count); } ABC_FREE(max); ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); + st_foreach(table, cuddApaStCountfree, NULL); st_free_table(table); if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); return(count); @@ -718,11 +770,11 @@ Cudd_ApaPrintMinterm( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); result = Cudd_ApaPrintDecimal(fp,digits,count); ABC_FREE(count); if (fprintf(fp,"\n") == EOF) { - return(0); + return(0); } return(result); @@ -758,11 +810,11 @@ Cudd_ApaPrintMintermExp( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); result = Cudd_ApaPrintExponential(fp,digits,count,precision); ABC_FREE(count); if (fprintf(fp,"\n") == EOF) { - return(0); + return(0); } return(result); @@ -796,7 +848,7 @@ Cudd_ApaPrintDensity( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); size = Cudd_DagSize(node); density = Cudd_NewApaNumber(digits); remainder = Cudd_ApaIntDivision(digits,count,size,density); @@ -805,7 +857,7 @@ Cudd_ApaPrintDensity( ABC_FREE(density); fractional = (unsigned int)((double)remainder / size * 1000000); if (fprintf(fp,".%u\n", fractional) == EOF) { - return(0); + return(0); } return(result); @@ -852,18 +904,18 @@ cuddApaCountMintermAux( st_table * table) { DdNode *Nt, *Ne; - DdApaNumber mint, mint1, mint2; - DdApaDigit carryout; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; if (cuddIsConstant(node)) { - if (node == background || node == zero) { - return(min); - } else { - return(max); - } + if (node == background || node == zero) { + return(min); + } else { + return(max); + } } - if (node->ref > 1 && st_lookup(table, (char *)node, (char **)&mint)) { - return(mint); + if (node->ref > 1 && st_lookup(table, (const char *)node, (char **)&mint)) { + return(mint); } Nt = cuddT(node); Ne = cuddE(node); @@ -872,20 +924,20 @@ cuddApaCountMintermAux( if (mint1 == NULL) return(NULL); mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); if (mint2 == NULL) { - if (Nt->ref == 1) ABC_FREE(mint1); - return(NULL); + if (Nt->ref == 1) ABC_FREE(mint1); + return(NULL); } mint = Cudd_NewApaNumber(digits); if (mint == NULL) { - if (Nt->ref == 1) ABC_FREE(mint1); - if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); - return(NULL); + if (Nt->ref == 1) ABC_FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); + return(NULL); } if (Cudd_IsComplement(Ne)) { - (void) Cudd_ApaSubtract(digits,max,mint2,mint); - carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); } else { - carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); } Cudd_ApaShiftRight(digits,carryout,mint,mint); /* If the refernce count of a child is 1, its minterm count @@ -893,12 +945,12 @@ cuddApaCountMintermAux( ** freed here. */ if (Nt->ref == 1) ABC_FREE(mint1); if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); - + if (node->ref > 1) { - if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { - ABC_FREE(mint); - return(NULL); - } + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + ABC_FREE(mint); + return(NULL); + } } return(mint); @@ -922,7 +974,7 @@ cuddApaStCountfree( char * value, char * arg) { - DdApaNumber d; + DdApaNumber d; d = (DdApaNumber) value; ABC_FREE(d); diff --git a/src/bdd/cudd/cuddApprox.c b/src/bdd/cudd/cuddApprox.c index 9641aac0..1fdb595f 100644 --- a/src/bdd/cudd/cuddApprox.c +++ b/src/bdd/cudd/cuddApprox.c @@ -8,41 +8,68 @@ Description [External procedures provided by this module: <ul> - <li> Cudd_UnderApprox() - <li> Cudd_OverApprox() - <li> Cudd_RemapUnderApprox() - <li> Cudd_RemapOverApprox() - <li> Cudd_BiasedUnderApprox() - <li> Cudd_BiasedOverApprox() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddUnderApprox() - <li> cuddRemapUnderApprox() - <li> cuddBiasedUnderApprox() - </ul> - Static procedures included in this module: - <ul> - <li> gatherInfoAux() - <li> gatherInfo() - <li> computeSavings() - <li> UAmarkNodes() - <li> UAbuildSubset() - <li> updateRefs() - <li> RAmarkNodes() - <li> BAmarkNodes() - <li> RAbuildSubset() - </ul> - ] + <li> Cudd_UnderApprox() + <li> Cudd_OverApprox() + <li> Cudd_RemapUnderApprox() + <li> Cudd_RemapOverApprox() + <li> Cudd_BiasedUnderApprox() + <li> Cudd_BiasedOverApprox() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddUnderApprox() + <li> cuddRemapUnderApprox() + <li> cuddBiasedUnderApprox() + </ul> + Static procedures included in this module: + <ul> + <li> gatherInfoAux() + <li> gatherInfo() + <li> computeSavings() + <li> UAmarkNodes() + <li> UAbuildSubset() + <li> updateRefs() + <li> RAmarkNodes() + <li> BAmarkNodes() + <li> RAbuildSubset() + </ul> + ] SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -57,21 +84,22 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define NOTHING 0 -#define REPLACE_T 1 -#define REPLACE_E 2 -#define REPLACE_N 3 -#define REPLACE_TT 4 -#define REPLACE_TE 5 +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 -#define DONT_CARE 0 -#define CARE 1 -#define TOTAL_CARE 2 -#define CARE_ERROR 3 +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -90,25 +118,25 @@ ABC_NAMESPACE_IMPL_START ** reference count of the node from an internal node; and the flag ** that says whether the node should be replaced and how. */ typedef struct NodeData { - double mintermsP; /* minterms for the regular node */ - double mintermsN; /* minterms for the complemented node */ - int functionRef; /* references from within this function */ - char care; /* node intersects care set */ - char replace; /* replacement decision */ - short int parity; /* 1: even; 2: odd; 3: both */ - DdNode *resultP; /* result for even parity */ - DdNode *resultN; /* result for odd parity */ + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ } NodeData; typedef struct ApproxInfo { - DdNode *one; /* one constant */ - DdNode *zero; /* BDD zero constant */ - NodeData *page; /* per-node information */ - st_table *table; /* hash table to access the per-node info */ - int index; /* index of the current node */ - double max; /* max number of minterms */ - int size; /* how many nodes are left */ - double minterms; /* how many minterms are left */ + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + st_table *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ } ApproxInfo; /* Item of the queue used in the levelized traversal of the BDD. */ @@ -140,7 +168,7 @@ typedef struct LocalQueueItem { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.27 2009/02/19 16:16:51 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -153,17 +181,17 @@ static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void updateParity ARGS((DdNode *node, ApproxInfo *info, int newparity)); -static NodeData * gatherInfoAux ARGS((DdNode *node, ApproxInfo *info, int parity)); -static ApproxInfo * gatherInfo ARGS((DdManager *dd, DdNode *node, int numVars, int parity)); -static int computeSavings ARGS((DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)); -static int updateRefs ARGS((DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)); -static int UAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality)); -static DdNode * UAbuildSubset ARGS((DdManager *dd, DdNode *node, ApproxInfo *info)); -static int RAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality)); -static int BAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0)); -static DdNode * RAbuildSubset ARGS((DdManager *dd, DdNode *node, ApproxInfo *info)); -static int BAapplyBias ARGS((DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache)); +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); /**AutomaticEnd***************************************************************/ @@ -208,8 +236,8 @@ Cudd_UnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); } while (dd->reordered == 1); return(subset); @@ -256,8 +284,8 @@ Cudd_OverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -299,8 +327,8 @@ Cudd_RemapUnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); } while (dd->reordered == 1); return(subset); @@ -346,8 +374,8 @@ Cudd_RemapOverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -394,9 +422,9 @@ Cudd_BiasedUnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, - quality0); + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); } while (dd->reordered == 1); return(subset); @@ -445,9 +473,9 @@ Cudd_BiasedOverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, - quality0); + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -493,39 +521,39 @@ cuddUnderApprox( int result; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, safe); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Mark nodes that should be replaced by zero. */ result = UAmarkNodes(dd, f, info, threshold, safe, quality); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = UAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -533,16 +561,16 @@ cuddUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - } - cuddDeref(subset); + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); } #endif return(subset); @@ -582,40 +610,40 @@ cuddRemapUnderApprox( int result; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, TRUE); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Mark nodes that should be replaced by zero. */ result = RAmarkNodes(dd, f, info, threshold, quality); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = RAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -623,16 +651,16 @@ cuddRemapUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - } - cuddDeref(subset); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; } #endif return(subset); @@ -667,61 +695,61 @@ cuddBiasedUnderApprox( int numVars /* maximum number of variables */, int threshold /* threshold under which approximation stops */, double quality1 /* minimum improvement for accepted changes when b=1 */, - double quality0 /* minimum improvement for accepted changes when b=1 */) + double quality0 /* minimum improvement for accepted changes when b=0 */) { ApproxInfo *info; DdNode *subset; int result; - DdHashTable *cache; + DdHashTable *cache; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, TRUE); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cache = cuddHashTableInit(dd,2,2); result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); if (result == CARE_ERROR) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - cuddHashTableQuit(cache); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cuddHashTableQuit(cache); /* Mark nodes that should be replaced by zero. */ result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = RAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -729,16 +757,16 @@ cuddBiasedUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - } - cuddDeref(subset); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; } #endif return(subset); @@ -772,16 +800,16 @@ updateParity( NodeData *infoN; DdNode *E; - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) return; + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) return; if ((infoN->parity & newparity) != 0) return; - infoN->parity |= newparity; + infoN->parity |= (short) newparity; if (Cudd_IsConstant(node)) return; updateParity(cuddT(node),info,newparity); E = cuddE(node); if (Cudd_IsComplement(E)) { - updateParity(Cudd_Not(E),info,3-newparity); + updateParity(Cudd_Not(E),info,3-newparity); } else { - updateParity(E,info,newparity); + updateParity(E,info,newparity); } return; @@ -811,18 +839,18 @@ gatherInfoAux( ApproxInfo * info /* info on BDD */, int parity /* gather parity information */) { - DdNode *N, *Nt, *Ne; + DdNode *N, *Nt, *Ne; NodeData *infoN, *infoT, *infoE; N = Cudd_Regular(node); /* Check whether entry for this node exists. */ - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (parity) { - /* Update parity and propagate. */ - updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); - } - return(infoN); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); } /* Compute the cofactors. */ @@ -839,21 +867,21 @@ gatherInfoAux( /* Point to the correct location in the page. */ infoN = &(info->page[info->index++]); - infoN->parity |= 1 + (short) Cudd_IsComplement(node); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); infoN->mintermsP = infoT->mintermsP/2; infoN->mintermsN = infoT->mintermsN/2; if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { - infoN->mintermsP += infoE->mintermsN/2; - infoN->mintermsN += infoE->mintermsP/2; + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; } else { - infoN->mintermsP += infoE->mintermsP/2; - infoN->mintermsN += infoE->mintermsN/2; + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; } /* Insert entry for the node in the table. */ if (st_insert(info->table,(char *)N, (char *)infoN) == ST_OUT_OF_MEM) { - return(NULL); + return(NULL); } return(infoN); @@ -882,7 +910,7 @@ gatherInfo( int numVars /* number of variables node depends on */, int parity /* gather parity information */) { - ApproxInfo *info; + ApproxInfo *info; NodeData *infoTop; /* If user did not give numVars value, set it to the maximum @@ -891,13 +919,13 @@ gatherInfo( ** log gives. */ if (numVars == 0) { - numVars = DBL_MAX_EXP - 1; + numVars = DBL_MAX_EXP - 1; } info = ABC_ALLOC(ApproxInfo,1); if (info == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } info->max = pow(2.0,(double) numVars); info->one = DD_ONE(dd); @@ -910,41 +938,41 @@ gatherInfo( ** that stores the per-node information. */ info->page = ABC_ALLOC(NodeData,info->size); if (info->page == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(info); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(info); + return(NULL); } memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ - info->table = st_init_table(st_ptrcmp, st_ptrhash);; + info->table = st_init_table(st_ptrcmp,st_ptrhash); if (info->table == NULL) { - ABC_FREE(info->page); - ABC_FREE(info); - return(NULL); + ABC_FREE(info->page); + ABC_FREE(info); + return(NULL); } /* We visit the DAG in post-order DFS. Hence, the constant node is ** in first position, and the root of the DAG is in last position. */ /* Info for the constant node: Initialize only fields different from 0. */ if (st_insert(info->table, (char *)info->one, (char *)info->page) == ST_OUT_OF_MEM) { - ABC_FREE(info->page); - ABC_FREE(info); - st_free_table(info->table); - return(NULL); + ABC_FREE(info->page); + ABC_FREE(info); + st_free_table(info->table); + return(NULL); } info->page[0].mintermsP = info->max; info->index = 1; infoTop = gatherInfoAux(node,info,parity); if (infoTop == NULL) { - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - return(NULL); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + return(NULL); } if (Cudd_IsComplement(node)) { - info->minterms = infoTop->mintermsN; + info->minterms = infoTop->mintermsN; } else { - info->minterms = infoTop->mintermsP; + info->minterms = infoTop->mintermsP; } infoTop->functionRef = 1; @@ -988,36 +1016,36 @@ computeSavings( ** count is set equal to the function reference count so that the ** search will continue from it when it is retrieved. */ item = (LocalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) - return(0); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); + return(0); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); item->localRef = infoN->functionRef; /* Process the queue. */ while (queue->first != NULL) { - item = (LocalQueueItem *) queue->first; - node = item->node; - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - if (node == skip) continue; - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (item->localRef != infoN->functionRef) { - /* This node is shared. */ - continue; - } - savings++; - if (!cuddIsConstant(cuddT(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (item == NULL) return(0); - item->localRef++; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (item == NULL) return(0); - item->localRef++; - } + item = (LocalQueueItem *) queue->first; + node = item->node; + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + if (node == skip) continue; + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (item->localRef != infoN->functionRef) { + /* This node is shared. */ + continue; + } + savings++; + if (!cuddIsConstant(cuddT(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (item == NULL) return(0); + item->localRef++; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (item == NULL) return(0); + item->localRef++; + } } #ifdef DD_DEBUG @@ -1060,45 +1088,43 @@ updateRefs( ** when it is retrieved. */ item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) - return(0); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); + return(0); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); infoN->functionRef = 0; if (skip != NULL) { - /* Increase the function reference count of the node to be skipped - ** by 1 to account for the node pointing to it that will be created. */ - skip = Cudd_Regular(skip); - (void) st_lookup(info->table, (char *)skip, (char **)&infoN); - infoN->functionRef++; + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + (void) st_lookup(info->table, (const char *)skip, (char **)&infoN); + infoN->functionRef++; } /* Process the queue. */ while (queue->first != NULL) { - item = (LocalQueueItem *) queue->first; - node = item->node; - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (infoN->functionRef != 0) { - /* This node is shared or must be skipped. */ - continue; - } - savings++; - if (!cuddIsConstant(cuddT(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (item == NULL) return(0); - (void) st_lookup(info->table, (char *)cuddT(node), - (char **)&infoN); - infoN->functionRef--; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (item == NULL) return(0); - (void) st_lookup(info->table, (char *)Cudd_Regular(cuddE(node)), - (char **)&infoN); - infoN->functionRef--; - } + item = (LocalQueueItem *) queue->first; + node = item->node; + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (infoN->functionRef != 0) { + /* This node is shared or must be skipped. */ + continue; + } + savings++; + if (!cuddIsConstant(cuddT(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (item == NULL) return(0); + (void) st_lookup(info->table, (const char *)cuddT(node), (char **)&infoN); + infoN->functionRef--; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (item == NULL) return(0); + (void) st_lookup(info->table, (const char *)Cudd_Regular(cuddE(node)), (char **)&infoN); + infoN->functionRef--; + } } #ifdef DD_DEBUG @@ -1142,88 +1168,88 @@ UAmarkNodes( #if 0 (void) printf("initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } node = Cudd_Regular(f); item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; - node = Cudd_Regular(node); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (safe && infoN->parity == 3) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - impactP = item->impactP; - impactN = item->impactN; - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,NULL,info,localQueue); - if (savings == 0) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = TRUE; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = TRUE; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("replace: new size = %d new minterms = %g\n", - info->size, info->minterms); + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); #endif - savings -= updateRefs(dd,node,NULL,info,localQueue); - assert(savings == 0); - continue; - } - if (!cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } } cuddLevelQueueQuit(queue); @@ -1257,28 +1283,28 @@ UAbuildSubset( NodeData *infoN; if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (infoN->replace == TRUE) { - return(info->zero); - } - if (N == node ) { - if (infoN->resultP != NULL) { - return(infoN->resultP); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (infoN->replace == TRUE) { + return(info->zero); } - } else { - if (infoN->resultN != NULL) { - return(infoN->resultN); + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } } - } } else { - (void) fprintf(dd->err, - "Something is wrong, ought to be in info table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); @@ -1286,42 +1312,42 @@ UAbuildSubset( t = UAbuildSubset(dd, Nt, info); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = UAbuildSubset(dd, Ne, info); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); if (N == node) { - infoN->resultP = r; + infoN->resultP = r; } else { - infoN->resultN = r; + infoN->resultN = r; } return(r); @@ -1363,277 +1389,266 @@ RAmarkNodes( #if 0 (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } /* Enqueue regular pointer to root and initialize impact. */ node = Cudd_Regular(f); item = (GlobalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } /* The nodes retrieved here are guaranteed to be non-terminal. ** The initial node is not terminal because constant nodes are ** dealt with in the calling procedure. Subsequent nodes are inserted ** only if they are not terminal. */ while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; -#ifdef DD_DEBUG - assert(item->impactP >= 0 && item->impactP <= 1.0); - assert(item->impactN >= 0 && item->impactN <= 1.0); - assert(!Cudd_IsComplement(node)); - assert(!Cudd_IsConstant(node)); -#endif - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; #ifdef DD_DEBUG - assert(infoN->parity >= 1 && infoN->parity <= 3); + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); #endif - if (infoN->parity == 3) { - /* This node can be reached through paths of different parity. - ** It is not safe to replace it, because remapping will give - ** an incorrect result, while replacement by 0 may cause node - ** splitting. */ - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - T = cuddT(node); - E = cuddE(node); - shared = NULL; - impactP = item->impactP; - impactN = item->impactN; - if (Cudd_bddLeq(dd,T,E)) { - /* Here we know that E is regular. */ -#ifdef DD_DEBUG - assert(!Cudd_IsComplement(E)); -#endif - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)E, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) { cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); return(0); - } - } else { - savings = 1; } - replace = REPLACE_E; - } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity >= 1 && infoN->parity <= 3); #endif - impact = impactN; - minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - } else { - savings = 1; - } - replace = REPLACE_T; + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; } - numOnset = impact * minterms; - } else if (Cudd_bddLeq(dd,E,T)) { - /* Here E may be complemented. */ - DdNode *Ereg = Cudd_Regular(E); - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoT->mintermsP/2.0 - - ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)E, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; } - } else { - savings = 1; - } - replace = REPLACE_T; - } else { + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)Ereg, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity == 2); #endif - impact = impactN; - minterms = ((E == Ereg) ? infoE->mintermsN : - infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; } + numOnset = impact * minterms; } else { - savings = 1; - } - replace = REPLACE_E; - } - numOnset = impact * minterms; - } else { - DdNode *Ereg = Cudd_Regular(E); - DdNode *TT = cuddT(T); - DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TT == ET) { - shared = TT; - replace = REPLACE_TT; - } else { - DdNode *TE = cuddE(T); - DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TE == EE) { - shared = TE; - replace = REPLACE_TE; - } else { - replace = REPLACE_N; - } - } - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,shared,info,localQueue); - if (shared != NULL) { - NodeData *infoS; - (void) st_lookup(info->table, (char *)Cudd_Regular(shared), - (char **)&infoS); - if (Cudd_IsComplement(shared)) { - numOnset -= (infoS->mintermsN * impactP + - infoS->mintermsP * impactN)/2.0; - } else { - numOnset -= (infoS->mintermsP * impactP + - infoS->mintermsN * impactN)/2.0; - } - savings--; + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + (void) st_lookup(info->table, (const char *)Cudd_Regular(shared), (char **)&infoS); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } } - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - if (replace == REPLACE_T || replace == REPLACE_E) - (void) printf("node %p: impact = %g numOnset = %g savings %d\n", - node, impact, numOnset, savings); - else - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = replace; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("remap(%d): new size = %d new minterms = %g\n", - replace, info->size, info->minterms); + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); #endif - if (replace == REPLACE_N) { - savings -= updateRefs(dd,node,NULL,info,localQueue); - } else if (replace == REPLACE_T) { - savings -= updateRefs(dd,node,E,info,localQueue); - } else if (replace == REPLACE_E) { - savings -= updateRefs(dd,node,T,info,localQueue); - } else { + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { #ifdef DD_DEBUG - assert(replace == REPLACE_TT || replace == REPLACE_TE); + assert(replace == REPLACE_TT || replace == REPLACE_TE); #endif - savings -= updateRefs(dd,node,shared,info,localQueue) - 1; - } - assert(savings == 0); - } else { - replace = NOTHING; - } - if (replace == REPLACE_N) continue; - if ((replace == REPLACE_E || replace == NOTHING) && - !cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (replace == REPLACE_E) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - if ((replace == REPLACE_T || replace == NOTHING) && - !Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + replace = NOTHING; } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - } - if ((replace == REPLACE_TT || replace == REPLACE_TE) && - !Cudd_IsConstant(shared)) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), - cuddI(dd,Cudd_Regular(shared)->index)); - if (Cudd_IsComplement(shared)) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } } } - } cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); @@ -1678,278 +1693,277 @@ BAmarkNodes( #if 0 (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } /* Enqueue regular pointer to root and initialize impact. */ node = Cudd_Regular(f); item = (GlobalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } /* The nodes retrieved here are guaranteed to be non-terminal. ** The initial node is not terminal because constant nodes are ** dealt with in the calling procedure. Subsequent nodes are inserted ** only if they are not terminal. */ while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; #ifdef DD_DEBUG - assert(item->impactP >= 0 && item->impactP <= 1.0); - assert(item->impactN >= 0 && item->impactN <= 1.0); - assert(!Cudd_IsComplement(node)); - assert(!Cudd_IsConstant(node)); + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); #endif - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - quality = infoN->care ? quality1 : quality0; -#ifdef DD_DEBUG - assert(infoN->parity >= 1 && infoN->parity <= 3); -#endif - if (infoN->parity == 3) { - /* This node can be reached through paths of different parity. - ** It is not safe to replace it, because remapping will give - ** an incorrect result, while replacement by 0 may cause node - ** splitting. */ - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - T = cuddT(node); - E = cuddE(node); - shared = NULL; - impactP = item->impactP; - impactN = item->impactN; - if (Cudd_bddLeq(dd,T,E)) { - /* Here we know that E is regular. */ -#ifdef DD_DEBUG - assert(!Cudd_IsComplement(E)); -#endif - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)E, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) { cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); return(0); - } - } else { - savings = 1; } - replace = REPLACE_E; - } else { + quality = infoN->care ? quality1 : quality0; #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity >= 1 && infoN->parity <= 3); #endif - impact = impactN; - minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - } else { - savings = 1; - } - replace = REPLACE_T; + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; } - numOnset = impact * minterms; - } else if (Cudd_bddLeq(dd,E,T)) { - /* Here E may be complemented. */ - DdNode *Ereg = Cudd_Regular(E); - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoT->mintermsP/2.0 - - ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)E, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; } - } else { - savings = 1; - } - replace = REPLACE_T; - } else { + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)Ereg, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity == 2); #endif - impact = impactN; - minterms = ((E == Ereg) ? infoE->mintermsN : - infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; } + numOnset = impact * minterms; } else { - savings = 1; - } - replace = REPLACE_E; - } - numOnset = impact * minterms; - } else { - DdNode *Ereg = Cudd_Regular(E); - DdNode *TT = cuddT(T); - DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TT == ET) { - shared = TT; - replace = REPLACE_TT; - } else { - DdNode *TE = cuddE(T); - DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TE == EE) { - shared = TE; - replace = REPLACE_TE; - } else { - replace = REPLACE_N; - } - } - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,shared,info,localQueue); - if (shared != NULL) { - NodeData *infoS; - (void) st_lookup(info->table, (char *)Cudd_Regular(shared), - (char **)&infoS); - if (Cudd_IsComplement(shared)) { - numOnset -= (infoS->mintermsN * impactP + - infoS->mintermsP * impactN)/2.0; - } else { - numOnset -= (infoS->mintermsP * impactP + - infoS->mintermsN * impactN)/2.0; - } - savings--; + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + (void) st_lookup(info->table, (const char *)Cudd_Regular(shared), (char **)&infoS); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } } - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - if (replace == REPLACE_T || replace == REPLACE_E) - (void) printf("node %p: impact = %g numOnset = %g savings %d\n", - node, impact, numOnset, savings); - else - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = replace; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("remap(%d): new size = %d new minterms = %g\n", - replace, info->size, info->minterms); + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); #endif - if (replace == REPLACE_N) { - savings -= updateRefs(dd,node,NULL,info,localQueue); - } else if (replace == REPLACE_T) { - savings -= updateRefs(dd,node,E,info,localQueue); - } else if (replace == REPLACE_E) { - savings -= updateRefs(dd,node,T,info,localQueue); - } else { + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { #ifdef DD_DEBUG - assert(replace == REPLACE_TT || replace == REPLACE_TE); + assert(replace == REPLACE_TT || replace == REPLACE_TE); #endif - savings -= updateRefs(dd,node,shared,info,localQueue) - 1; - } - assert(savings == 0); - } else { - replace = NOTHING; - } - if (replace == REPLACE_N) continue; - if ((replace == REPLACE_E || replace == NOTHING) && - !cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (replace == REPLACE_E) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - if ((replace == REPLACE_T || replace == NOTHING) && - !Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; - } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } + replace = NOTHING; } - } - if ((replace == REPLACE_TT || replace == REPLACE_TE) && - !Cudd_IsConstant(shared)) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), - cuddI(dd,Cudd_Regular(shared)->index)); - if (Cudd_IsComplement(shared)) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } } - } cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); @@ -1982,124 +1996,124 @@ RAbuildSubset( NodeData *infoN; if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (N == node ) { - if (infoN->resultP != NULL) { - return(infoN->resultP); - } - } else { - if (infoN->resultN != NULL) { - return(infoN->resultN); - } - } - if (infoN->replace == REPLACE_T) { - r = RAbuildSubset(dd, Ne, info); - return(r); - } else if (infoN->replace == REPLACE_E) { - r = RAbuildSubset(dd, Nt, info); - return(r); - } else if (infoN->replace == REPLACE_N) { - return(info->zero); - } else if (infoN->replace == REPLACE_TT) { - DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), - Cudd_IsComplement(node)); - int index = cuddT(N)->index; - DdNode *e = info->zero; - DdNode *t = RAbuildSubset(dd, Ntt, info); - if (t == NULL) { - return(NULL); - } - cuddRef(t); - if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - } - cuddDeref(t); - return(r); - } else if (infoN->replace == REPLACE_TE) { - DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), - Cudd_IsComplement(node)); - int index = cuddT(N)->index; - DdNode *t = info->one; - DdNode *e = RAbuildSubset(dd, Nte, info); - if (e == NULL) { - return(NULL); + if (infoN->resultN != NULL) { + return(infoN->resultN); + } } - cuddRef(e); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - return(NULL); + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); } - r =Cudd_Not(r); - cuddDeref(e); - return(r); - } } else { - (void) fprintf(dd->err, - "Something is wrong, ought to be in info table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } t = RAbuildSubset(dd, Nt, info); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = RAbuildSubset(dd, Ne, info); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); if (N == node) { - infoN->resultP = r; + infoN->resultP = r; } else { - infoN->resultN = r; + infoN->resultN = r; } return(r); @@ -2137,61 +2151,63 @@ BAapplyBias( one = DD_ONE(dd); zero = Cudd_Not(one); - if (!st_lookup(info->table, (char *) f, (char **)&infoF)) - return(CARE_ERROR); + if (!st_lookup(info->table, (const char *)f, (char **)&infoF)) + return(CARE_ERROR); if (f == one) return(TOTAL_CARE); if (b == zero) return(infoF->care); if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && - (res = cuddHashTableLookup2(cache,f,b)) != NULL) { - if (res->ref == 0) { - cache->manager->dead++; - cache->manager->constants.dead++; - } - return(infoF->care); + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); } topf = dd->perm[f->index]; B = Cudd_Regular(b); topb = cuddI(dd,B->index); if (topf <= topb) { - Ft = cuddT(f); Fe = cuddE(f); + Ft = cuddT(f); Fe = cuddE(f); } else { - Ft = Fe = f; + Ft = Fe = f; } if (topb <= topf) { - /* We know that b is not constant because f is not. */ - Bt = cuddT(B); Be = cuddE(B); - if (Cudd_IsComplement(b)) { - Bt = Cudd_Not(Bt); - Be = Cudd_Not(Be); - } + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } } else { - Bt = Be = b; + Bt = Be = b; } careT = BAapplyBias(dd, Ft, Bt, info, cache); if (careT == CARE_ERROR) - return(CARE_ERROR); + return(CARE_ERROR); careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); if (careE == CARE_ERROR) - return(CARE_ERROR); + return(CARE_ERROR); if (careT == TOTAL_CARE && careE == TOTAL_CARE) { - infoF->care = TOTAL_CARE; + infoF->care = TOTAL_CARE; } else { - infoF->care = CARE; + infoF->care = CARE; } if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { - ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { - return(CARE_ERROR); - } + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } } return(infoF->care); } /* end of BAapplyBias */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddBddAbs.c b/src/bdd/cudd/cuddBddAbs.c index 80d24ca4..a3892af1 100644 --- a/src/bdd/cudd/cuddBddAbs.c +++ b/src/bdd/cudd/cuddBddAbs.c @@ -7,31 +7,58 @@ Synopsis [Quantification functions for BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddExistAbstract() - <li> Cudd_bddXorExistAbstract() - <li> Cudd_bddUnivAbstract() - <li> Cudd_bddBooleanDiff() - <li> Cudd_bddVarIsDependent() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddExistAbstractRecur() - <li> cuddBddXorExistAbstractRecur() - <li> cuddBddBooleanDiffRecur() - </ul> - Static procedures included in this module: - <ul> - <li> bddCheckPositiveCube() - </ul> - ] + <ul> + <li> Cudd_bddExistAbstract() + <li> Cudd_bddXorExistAbstract() + <li> Cudd_bddUnivAbstract() + <li> Cudd_bddBooleanDiff() + <li> Cudd_bddVarIsDependent() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddExistAbstractRecur() + <li> cuddBddXorExistAbstractRecur() + <li> cuddBddBooleanDiffRecur() + </ul> + Static procedures included in this module: + <ul> + <li> bddCheckPositiveCube() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -42,6 +69,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -62,7 +90,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.26 2004/08/13 18:04:46 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -76,7 +104,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int bddCheckPositiveCube ARGS((DdManager *manager, DdNode *cube)); +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); /**AutomaticEnd***************************************************************/ @@ -108,14 +136,14 @@ Cudd_bddExistAbstract( if (bddCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; return(NULL); } do { - manager->reordered = 0; - res = cuddBddExistAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -148,14 +176,14 @@ Cudd_bddXorExistAbstract( if (bddCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; return(NULL); } do { - manager->reordered = 0; - res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); return(res); @@ -181,18 +209,18 @@ Cudd_bddUnivAbstract( DdNode * f, DdNode * cube) { - DdNode *res; + DdNode *res; if (bddCheckPositiveCube(manager, cube) == 0) { - (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); } do { - manager->reordered = 0; - res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); } while (manager->reordered == 1); if (res != NULL) res = Cudd_Not(res); @@ -229,8 +257,8 @@ Cudd_bddBooleanDiff( var = manager->vars[x]; do { - manager->reordered = 0; - res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); } while (manager->reordered == 1); return(res); @@ -254,13 +282,13 @@ Cudd_bddBooleanDiff( ******************************************************************************/ int Cudd_bddVarIsDependent( - DdManager *dd, /* manager */ - DdNode *f, /* function */ - DdNode *var /* variable */) + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) { DdNode *F, *res, *zero, *ft, *fe; unsigned topf, level; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; int retval; zero = Cudd_Not(DD_ONE(dd)); @@ -274,14 +302,13 @@ Cudd_bddVarIsDependent( /* Check terminal case. If topf > index of var, f does not depend on var. ** Therefore, var is not dependent in f. */ if (topf > level) { - return(0); + return(0); } - cacheOp = - (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_bddVarIsDependent; + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; res = cuddCacheLookup2(dd,cacheOp,f,var); if (res != NULL) { - return(res != zero); + return(res != zero); } /* Compute cofactors. */ @@ -289,10 +316,10 @@ Cudd_bddVarIsDependent( fe = Cudd_NotCond(cuddE(F), f != F); if (topf == level) { - retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); } else { - retval = Cudd_bddVarIsDependent(dd,ft,var) && - Cudd_bddVarIsDependent(dd,fe,var); + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); } cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); @@ -327,13 +354,13 @@ cuddBddExistAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *F, *T, *E, *res, *res1, *res2, *one; + DdNode *F, *T, *E, *res, *res1, *res2, *one; statLine(manager); one = DD_ONE(manager); F = Cudd_Regular(f); - /* Cube is guaranteed to be a cube at this point. */ + /* Cube is guaranteed to be a cube at this point. */ if (cube == one || F == one) { return(f); } @@ -341,78 +368,78 @@ cuddBddExistAbstractRecur( /* Abstract a variable that does not appear in f. */ while (manager->perm[F->index] > manager->perm[cube->index]) { - cube = cuddT(cube); - if (cube == one) return(f); + cube = cuddT(cube); + if (cube == one) return(f); } /* Check the cache. */ if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { - return(res); + return(res); } /* Compute the cofactors of f. */ T = cuddT(F); E = cuddE(F); if (f != F) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } /* If the two indices are the same, so are their levels. */ if (F->index == cube->index) { - if (T == one || E == one || T == Cudd_Not(E)) { - return(one); - } - res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); - if (res1 == one) { - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); - return(one); - } + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } cuddRef(res1); - res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_IterDerefBdd(manager,res1); - return(NULL); - } + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); - if (res == NULL) { + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); Cudd_IterDerefBdd(manager, res1); Cudd_IterDerefBdd(manager, res2); - return(NULL); - } - res = Cudd_Not(res); - cuddRef(res); - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); - cuddDeref(res); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ - res1 = cuddBddExistAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddBddExistAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_IterDerefBdd(manager, res1); - return(NULL); - } + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } cuddRef(res2); - /* ITE takes care of possible complementation of res1 and of the + /* ITE takes care of possible complementation of res1 and of the ** case in which res1 == res2. */ - res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); - if (res == NULL) { - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); return(res); - } + } } /* end of cuddBddExistAbstractRecur */ @@ -448,39 +475,39 @@ cuddBddXorExistAbstractRecur( /* Terminal cases. */ if (f == g) { - return(zero); + return(zero); } if (f == Cudd_Not(g)) { - return(one); + return(one); } if (cube == one) { - return(cuddBddXorRecur(manager, f, g)); + return(cuddBddXorRecur(manager, f, g)); } if (f == one) { - return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); } if (g == one) { - return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); } if (f == zero) { - return(cuddBddExistAbstractRecur(manager, g, cube)); + return(cuddBddExistAbstractRecur(manager, g, cube)); } if (g == zero) { - return(cuddBddExistAbstractRecur(manager, f, cube)); + return(cuddBddExistAbstractRecur(manager, f, cube)); } /* At this point f, g, and cube are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } /* Check cache. */ r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); if (r != NULL) { - return(r); + return(r); } /* Here we can skip the use of cuddI, because the operands are known @@ -494,38 +521,38 @@ cuddBddXorExistAbstractRecur( topcube = manager->perm[cube->index]; if (topcube < top) { - return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); } /* Now, topcube >= top. */ if (topf == top) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg == top) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } if (topcube == top) { - Cube = cuddT(cube); + Cube = cuddT(cube); } else { - Cube = cube; + Cube = cube; } t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); @@ -535,53 +562,53 @@ cuddBddXorExistAbstractRecur( ** the else branch if t is 1. */ if (t == one && topcube == top) { - cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); - return(one); + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); } cuddRef(t); e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - cuddRef(e); - - if (topcube == top) { /* abstract */ - r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - cuddDeref(r); - } else if (t == e) { - r = t; - cuddDeref(t); - cuddDeref(e); - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); } r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(r); Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); - return(NULL); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } - } - cuddDeref(e); - cuddDeref(t); + cuddDeref(e); + cuddDeref(t); } cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); return (r); @@ -613,15 +640,15 @@ cuddBddBooleanDiffRecur( statLine(manager); if (cuddI(manager,f->index) > manager->perm[var->index]) { - /* f does not depend on var. */ - return(Cudd_Not(DD_ONE(manager))); + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); } /* From now on, f is non-constant. */ /* If the two indices are the same, so are their levels. */ if (f->index == var->index) { - res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); return(res); } @@ -630,7 +657,7 @@ cuddBddBooleanDiffRecur( /* Check the cache. */ res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); if (res != NULL) { - return(res); + return(res); } /* Compute the cofactors of f. */ @@ -641,17 +668,17 @@ cuddBddBooleanDiffRecur( cuddRef(res1); res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); if (res2 == NULL) { - Cudd_IterDerefBdd(manager, res1); - return(NULL); + Cudd_IterDerefBdd(manager, res1); + return(NULL); } cuddRef(res2); /* ITE takes care of possible complementation of res1 and of the ** case in which res1 == res2. */ res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); if (res == NULL) { - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - return(NULL); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); } cuddDeref(res1); cuddDeref(res2); @@ -690,5 +717,7 @@ bddCheckPositiveCube( } /* end of bddCheckPositiveCube */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBddCorr.c b/src/bdd/cudd/cuddBddCorr.c index f3f017b0..32d5d97c 100644 --- a/src/bdd/cudd/cuddBddCorr.c +++ b/src/bdd/cudd/cuddBddCorr.c @@ -7,26 +7,53 @@ Synopsis [Correlation between BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddCorrelation() - <li> Cudd_bddCorrelationWeights() - </ul> - Static procedures included in this module: - <ul> - <li> bddCorrelationAux() - <li> bddCorrelationWeightsAux() - <li> CorrelCompare() - <li> CorrelHash() - <li> CorrelCleanUp() - </ul> - ] + <ul> + <li> Cudd_bddCorrelation() + <li> Cudd_bddCorrelationWeights() + </ul> + Static procedures included in this module: + <ul> + <li> bddCorrelationAux() + <li> bddCorrelationWeightsAux() + <li> CorrelCompare() + <li> CorrelHash() + <li> CorrelCleanUp() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -37,6 +64,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -62,17 +90,20 @@ typedef struct hashEntry { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.14 2004/08/13 18:04:46 fabio Exp $"; #endif #ifdef CORREL_STATS -static int num_calls; +static int num_calls; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -80,14 +111,18 @@ static int num_calls; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static double bddCorrelationAux ARGS((DdManager *dd, DdNode *f, DdNode *g, st_table *table)); -static double bddCorrelationWeightsAux ARGS((DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table)); -static int CorrelCompare ARGS((const char *key1, const char *key2)); -static int CorrelHash ARGS((const char *key, int modulus)); -static enum st_retval CorrelCleanUp ARGS((char *key, char *value, char *arg)); +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (const char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -116,7 +151,7 @@ Cudd_bddCorrelation( { st_table *table; - double correlation; + double correlation; #ifdef CORREL_STATS num_calls = 0; @@ -125,7 +160,7 @@ Cudd_bddCorrelation( table = st_init_table(CorrelCompare,CorrelHash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); correlation = bddCorrelationAux(manager,f,g,table); - st_foreach(table, (ST_PFSR)CorrelCleanUp, NIL(char)); + st_foreach(table, CorrelCleanUp, NIL(char)); st_free_table(table); return(correlation); @@ -159,7 +194,7 @@ Cudd_bddCorrelationWeights( { st_table *table; - double correlation; + double correlation; #ifdef CORREL_STATS num_calls = 0; @@ -168,7 +203,7 @@ Cudd_bddCorrelationWeights( table = st_init_table(CorrelCompare,CorrelHash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); - st_foreach(table, (ST_PFSR)CorrelCleanUp, NIL(char)); + st_foreach(table, CorrelCleanUp, NIL(char)); st_free_table(table); return(correlation); @@ -205,9 +240,9 @@ bddCorrelationAux( DdNode * g, st_table * table) { - DdNode *Fv, *Fnv, *G, *Gv, *Gnv; - double min, *pmin, min1, min2, *dummy; - HashEntry *entry; + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; unsigned int topF, topG; statLine(dd); @@ -224,19 +259,19 @@ bddCorrelationAux( ** (f' EXNOR g') = (f EXNOR g). */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* From now on, f is regular. */ entry = ABC_ALLOC(HashEntry,1); if (entry == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } entry->f = f; entry->g = g; @@ -244,10 +279,10 @@ bddCorrelationAux( ** correlation(f,g') = 1 - correlation(f,g) ** to minimize the risk of cancellation. */ - if (st_lookup(table, (char *)entry, (char **)&dummy)) { - min = *dummy; - ABC_FREE(entry); - return(min); + if (st_lookup(table, (const char *)entry, (char **)&dummy)) { + min = *dummy; + ABC_FREE(entry); + return(min); } G = Cudd_Regular(g); @@ -256,33 +291,33 @@ bddCorrelationAux( if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } if (g != G) { - Gv = Cudd_Not(Gv); - Gnv = Cudd_Not(Gnv); + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); } min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; if (min1 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return(CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return(CUDD_OUT_OF_MEM); } min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; if (min2 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return(CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return(CUDD_OUT_OF_MEM); } min = (min1+min2); pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min; if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(entry); - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min); @@ -308,10 +343,10 @@ bddCorrelationWeightsAux( double * prob, st_table * table) { - DdNode *Fv, *Fnv, *G, *Gv, *Gnv; - double min, *pmin, min1, min2, *dummy; - HashEntry *entry; - int topF, topG, index; + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; statLine(dd); #ifdef CORREL_STATS @@ -327,19 +362,19 @@ bddCorrelationWeightsAux( ** (f' EXNOR g') = (f EXNOR g). */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* From now on, f is regular. */ entry = ABC_ALLOC(HashEntry,1); if (entry == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } entry->f = f; entry->g = g; @@ -347,51 +382,51 @@ bddCorrelationWeightsAux( ** correlation(f,g') = 1 - correlation(f,g) ** to minimize the risk of cancellation. */ - if (st_lookup(table, (char *)entry, (char **)&dummy)) { - min = *dummy; - ABC_FREE(entry); - return(min); + if (st_lookup(table, (const char *)entry, (char **)&dummy)) { + min = *dummy; + ABC_FREE(entry); + return(min); } G = Cudd_Regular(g); topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); if (topF <= topG) { - Fv = cuddT(f); Fnv = cuddE(f); - index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; } else { - Fv = Fnv = f; - index = G->index; + Fv = Fnv = f; + index = G->index; } if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } if (g != G) { - Gv = Cudd_Not(Gv); - Gnv = Cudd_Not(Gnv); + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); } min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; if (min1 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return((double)CUDD_OUT_OF_MEM); } min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); if (min2 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return((double)CUDD_OUT_OF_MEM); } min = (min1+min2); pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min; if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(entry); - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min); @@ -440,10 +475,10 @@ CorrelHash( const char * key, int modulus) { - const HashEntry *entry; + HashEntry *entry; int val = 0; - entry = (const HashEntry *) key; + entry = (HashEntry *) key; #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); #else @@ -471,7 +506,7 @@ CorrelCleanUp( char * value, char * arg) { - double *d; + double *d; HashEntry *entry; entry = (HashEntry *) key; @@ -482,5 +517,7 @@ CorrelCleanUp( } /* end of CorrelCleanUp */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c index 92d1171b..4e75aab2 100644 --- a/src/bdd/cudd/cuddBddIte.c +++ b/src/bdd/cudd/cuddBddIte.c @@ -7,40 +7,68 @@ Synopsis [BDD ITE function and satellites.] Description [External procedures included in this module: - <ul> + <ul> <li> Cudd_bddIte() - <li> Cudd_bddIteConstant() - <li> Cudd_bddIntersect() - <li> Cudd_bddAnd() - <li> Cudd_bddOr() - <li> Cudd_bddNand() - <li> Cudd_bddNor() - <li> Cudd_bddXor() - <li> Cudd_bddXnor() - <li> Cudd_bddLeq() - </ul> + <li> Cudd_bddIteConstant() + <li> Cudd_bddIntersect() + <li> Cudd_bddAnd() + <li> Cudd_bddAndLimit() + <li> Cudd_bddOr() + <li> Cudd_bddNand() + <li> Cudd_bddNor() + <li> Cudd_bddXor() + <li> Cudd_bddXnor() + <li> Cudd_bddLeq() + </ul> Internal procedures included in this module: - <ul> - <li> cuddBddIteRecur() - <li> cuddBddIntersectRecur() - <li> cuddBddAndRecur() - <li> cuddBddXorRecur() - </ul> + <ul> + <li> cuddBddIteRecur() + <li> cuddBddIntersectRecur() + <li> cuddBddAndRecur() + <li> cuddBddXorRecur() + </ul> Static procedures included in this module: - <ul> - <li> bddVarToConst() - <li> bddVarToCanonical() - <li> bddVarToCanonicalSimple() - </ul>] + <ul> + <li> bddVarToConst() + <li> bddVarToCanonical() + <li> bddVarToCanonicalSimple() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -51,6 +79,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -71,7 +100,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.24 2004/08/13 18:04:46 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -85,9 +114,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void bddVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)); -static int bddVarToCanonical ARGS((DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)); -static int bddVarToCanonicalSimple ARGS((DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)); +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); /**AutomaticEnd***************************************************************/ @@ -120,8 +149,8 @@ Cudd_bddIte( DdNode *res; do { - dd->reordered = 0; - res = cuddBddIteRecur(dd,f,g,h); + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); } while (dd->reordered == 1); return(res); @@ -148,85 +177,85 @@ Cudd_bddIteConstant( DdNode * g, DdNode * h) { - DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - int comple; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; unsigned int topf, topg, toph, v; statLine(dd); /* Trivial cases. */ - if (f == one) /* ITE(1,G,H) => G */ - return(g); + if (f == one) /* ITE(1,G,H) => G */ + return(g); - if (f == zero) /* ITE(0,G,H) => H */ - return(h); + if (f == zero) /* ITE(0,G,H) => H */ + return(h); /* f now not a constant. */ - bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ - /* to constants */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ - if (g == h) /* ITE(F,G,G) => G */ - return(g); + if (g == h) /* ITE(F,G,G) => G */ + return(g); if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) - return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ - /* => DD_NON_CONSTANT */ + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ if (g == Cudd_Not(h)) - return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ - /* if F != G and F != G' */ + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); /* Cache lookup. */ r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); if (r != NULL) { - return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); } v = ddMin(topg, toph); /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - return(DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf, v); /* v = top_var(F,G,H) */ - Fv = cuddT(f); Fnv = cuddE(f); + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); } else { - Fv = Fnv = f; + Fv = Fnv = f; } if (topg == v) { - Gv = cuddT(g); Gnv = cuddE(g); + Gv = cuddT(g); Gnv = cuddE(g); } else { - Gv = Gnv = g; + Gv = Gnv = g; } if (toph == v) { - H = Cudd_Regular(h); - Hv = cuddT(H); Hnv = cuddE(H); - if (Cudd_IsComplement(h)) { - Hv = Cudd_Not(Hv); - Hnv = Cudd_Not(Hnv); - } + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } } else { - Hv = Hnv = h; + Hv = Hnv = h; } /* Recursion. */ t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { - cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { - cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); return(Cudd_NotCond(t,comple)); @@ -258,8 +287,8 @@ Cudd_bddIntersect( DdNode *res; do { - dd->reordered = 0; - res = cuddBddIntersectRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -290,8 +319,8 @@ Cudd_bddAnd( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -300,6 +329,42 @@ Cudd_bddAnd( /**Function******************************************************************** + Synopsis [Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than <code>limit</code> are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + Synopsis [Computes the disjunction of two BDDs f and g.] Description [Computes the disjunction of two BDDs f and g. Returns a @@ -321,8 +386,8 @@ Cudd_bddOr( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); } while (dd->reordered == 1); res = Cudd_NotCond(res,res != NULL); return(res); @@ -353,8 +418,8 @@ Cudd_bddNand( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); } while (dd->reordered == 1); res = Cudd_NotCond(res,res != NULL); return(res); @@ -385,8 +450,8 @@ Cudd_bddNor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); } while (dd->reordered == 1); return(res); @@ -416,8 +481,8 @@ Cudd_bddXor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddXorRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -447,8 +512,8 @@ Cudd_bddXnor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); } while (dd->reordered == 1); return(res); @@ -481,20 +546,20 @@ Cudd_bddLeq( if (f == g) return(1); if (Cudd_IsComplement(g)) { - /* Special case: if f is regular and g is complemented, - ** f(1,...,1) = 1 > 0 = g(1,...,1). - */ - if (!Cudd_IsComplement(f)) return(0); - /* Both are complemented: Swap and complement because - ** f <= g <=> g' <= f' and we want the second argument to be regular. - */ - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); } else if (Cudd_IsComplement(f) && g < f) { - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); } /* Now g is regular and, if f is not regular, f < g. */ @@ -508,10 +573,9 @@ Cudd_bddLeq( /* Here neither f nor g is constant. */ /* Check cache. */ - tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *))Cudd_bddLeq,f,g); + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); if (tmp != NULL) { - return(tmp == one); + return(tmp == one); } /* Compute cofactors. */ @@ -519,18 +583,18 @@ Cudd_bddLeq( topf = dd->perm[F->index]; topg = dd->perm[g->index]; if (topf <= topg) { - fv = cuddT(F); fvn = cuddE(F); - if (f != F) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); - } + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } } else { - fv = fvn = f; + fv = fvn = f; } if (topg <= topf) { - gv = cuddT(g); gvn = cuddE(g); + gv = cuddT(g); gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } /* Recursive calls. Since we want to maximize the probability of @@ -541,7 +605,7 @@ Cudd_bddLeq( res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); /* Store result in cache and return. */ - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_bddLeq,f,g,(res ? one : zero)); + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); return(res); } /* end of Cudd_bddLeq */ @@ -572,52 +636,52 @@ cuddBddIteRecur( DdNode * g, DdNode * h) { - DdNode *one, *zero, *res; - DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; unsigned int topf, topg, toph, v; - int index = 0; // Suppress "might be used uninitialized" - int comple; + int index; + int comple; statLine(dd); /* Terminal cases. */ /* One variable cases. */ - if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ - return(g); + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); - if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ - return(h); + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); /* From now on, f is known not to be a constant. */ - if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - if (h == zero) { /* ITE(F,1,0) = F */ - return(f); - } else { - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); - return(Cudd_NotCond(res,res != NULL)); - } + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ - if (h == one) { /* ITE(F,0,1) = !F */ - return(Cudd_Not(f)); - } else { - res = cuddBddAndRecur(dd,Cudd_Not(f),h); - return(res); - } + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } } if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - res = cuddBddAndRecur(dd,f,g); - return(res); + res = cuddBddAndRecur(dd,f,g); + return(res); } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ - res = cuddBddAndRecur(dd,f,Cudd_Not(g)); - return(Cudd_NotCond(res,res != NULL)); + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); } /* Check remaining one variable case. */ - if (g == h) { /* ITE(F,G,G) = G */ - return(g); + if (g == h) { /* ITE(F,G,G) = G */ + return(g); } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ - res = cuddBddXorRecur(dd,f,h); - return(res); + res = cuddBddXorRecur(dd,f,h); + return(res); } /* From here, there are no constants. */ @@ -629,40 +693,40 @@ cuddBddIteRecur( /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - r = cuddUniqueInter(dd, (int) f->index, g, h); - return(Cudd_NotCond(r,comple && r != NULL)); + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); } /* Check cache. */ r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf, v); /* v = top_var(F,G,H) */ - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - Fv = Fnv = f; + Fv = Fnv = f; } if (topg == v) { - index = g->index; - Gv = cuddT(g); Gnv = cuddE(g); + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); } else { - Gv = Gnv = g; + Gv = Gnv = g; } if (toph == v) { - H = Cudd_Regular(h); - index = H->index; - Hv = cuddT(H); Hnv = cuddE(H); - if (Cudd_IsComplement(h)) { - Hv = Cudd_Not(Hv); - Hnv = Cudd_Not(Hnv); - } + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } } else { - Hv = Hnv = h; + Hv = Hnv = h; } /* Recursive step. */ @@ -672,16 +736,16 @@ cuddBddIteRecur( e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); + Cudd_IterDerefBdd(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); if (r == NULL) { - Cudd_IterDerefBdd(dd,t); - Cudd_IterDerefBdd(dd,e); - return(NULL); + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -739,27 +803,27 @@ cuddBddIntersectRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } /* Compute partial results. */ @@ -767,33 +831,33 @@ cuddBddIntersectRecur( if (t == NULL) return(NULL); cuddRef(t); if (t != zero) { - e = zero; + e = zero; } else { - e = cuddBddIntersectRecur(dd,fnv,gnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddRef(e); if (t == e) { /* both equal zero */ - res = t; + res = t; } else if (Cudd_IsComplement(t)) { - res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (res == NULL) { - Cudd_IterDerefBdd(dd, t); - Cudd_IterDerefBdd(dd, e); - return(NULL); - } - res = Cudd_Not(res); + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); } else { - res = cuddUniqueInter(dd,(int)index,t,e); - if (res == NULL) { - Cudd_IterDerefBdd(dd, t); - Cudd_IterDerefBdd(dd, e); - return(NULL); - } + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } } cuddDeref(e); cuddDeref(t); @@ -835,33 +899,36 @@ cuddBddAndRecur( F = Cudd_Regular(f); G = Cudd_Regular(g); if (F == G) { - if (f == g) return(f); - else return(Cudd_Not(one)); + if (f == g) return(f); + else return(Cudd_Not(one)); } if (F == one) { - if (f == one) return(g); - else return(f); + if (f == one) return(g); + else return(f); } if (G == one) { - if (g == one) return(f); - else return(g); + if (g == one) return(f); + else return(g); } /* At this point f and g are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; - F = Cudd_Regular(f); - G = Cudd_Regular(g); + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); } /* Check cache. */ if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); - if (r != NULL) return(r); + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); } + if ( manager->TimeStop && manager->TimeStop < clock() ) + return NULL; + /* Here we can skip the use of cuddI, because the operands are known ** to be non-constant. */ @@ -870,27 +937,27 @@ cuddBddAndRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } t = cuddBddAndRecur(manager, fv, gv); @@ -899,35 +966,35 @@ cuddBddAndRecur( e = cuddBddAndRecur(manager, fnv, gnv); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); + Cudd_IterDerefBdd(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); return(r); } /* end of cuddBddAndRecur */ @@ -964,15 +1031,15 @@ cuddBddXorRecur( if (f == g) return(zero); if (f == Cudd_Not(g)) return(one); if (f > g) { /* Try to increase cache efficiency and simplify tests. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } if (g == zero) return(f); if (g == one) return(Cudd_Not(f)); if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* Now the first argument is regular. */ if (f == one) return(Cudd_Not(g)); @@ -992,23 +1059,23 @@ cuddBddXorRecur( /* Compute cofactors. */ if (topf <= topg) { - index = f->index; - fv = cuddT(f); - fnv = cuddE(f); + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } t = cuddBddXorRecur(manager, fv, gv); @@ -1017,31 +1084,31 @@ cuddBddXorRecur( e = cuddBddXorRecur(manager, fnv, gnv); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); + Cudd_IterDerefBdd(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); @@ -1078,14 +1145,14 @@ bddVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = one; + *gp = one; } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ - *gp = Cudd_Not(one); + *gp = Cudd_Not(one); } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = Cudd_Not(one); + *hp = Cudd_Not(one); } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ - *hp = one; + *hp = one; } } /* end of bddVarToConst */ @@ -1112,10 +1179,10 @@ bddVarToCanonical( unsigned int * topgp, unsigned int * tophp) { - register DdNode *F, *G, *H, *r, *f, *g, *h; - register unsigned int topf, topg, toph; - DdNode *one = dd->one; - int comple, change; + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; f = *fp; g = *gp; @@ -1129,56 +1196,56 @@ bddVarToCanonical( change = 0; - if (G == one) { /* ITE(F,c,H) */ - if ((topf > toph) || (topf == toph && f > h)) { - r = h; - h = f; - f = r; /* ITE(F,1,H) = ITE(H,1,F) */ - if (g != one) { /* g == zero */ - f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ - h = Cudd_Not(h); + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; } - change = 1; - } - } else if (H == one) { /* ITE(F,G,c) */ - if ((topf > topg) || (topf == topg && f > g)) { - r = g; - g = f; - f = r; /* ITE(F,G,0) = ITE(G,F,0) */ - if (h == one) { - f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ - g = Cudd_Not(g); + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; } - change = 1; - } - } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ - if ((topf > topg) || (topf == topg && f > g)) { - r = f; - f = g; - g = r; - h = Cudd_Not(r); - change = 1; - } } /* adjust pointers so that the first 2 arguments to ITE are regular */ if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ - f = Cudd_Not(f); - r = g; - g = h; - h = r; - change = 1; + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; } comple = 0; if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ - g = Cudd_Not(g); - h = Cudd_Not(h); - change = 1; - comple = 1; + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; } if (change != 0) { - *fp = f; - *gp = g; - *hp = h; + *fp = f; + *gp = g; + *hp = h; } *topfp = cuddI(dd,f->index); *topgp = cuddI(dd,g->index); @@ -1214,8 +1281,8 @@ bddVarToCanonicalSimple( unsigned int * topgp, unsigned int * tophp) { - register DdNode *r, *f, *g, *h; - int comple, change; + register DdNode *r, *f, *g, *h; + int comple, change; f = *fp; g = *gp; @@ -1224,24 +1291,24 @@ bddVarToCanonicalSimple( change = 0; /* adjust pointers so that the first 2 arguments to ITE are regular */ - if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ - f = Cudd_Not(f); - r = g; - g = h; - h = r; - change = 1; + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; } comple = 0; - if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ - g = Cudd_Not(g); - h = Cudd_Not(h); - change = 1; - comple = 1; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; } if (change) { - *fp = f; - *gp = g; - *hp = h; + *fp = f; + *gp = g; + *hp = h; } /* Here we can skip the use of cuddI, because the operands are known @@ -1255,5 +1322,7 @@ bddVarToCanonicalSimple( } /* end of bddVarToCanonicalSimple */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBridge.c b/src/bdd/cudd/cuddBridge.c index da0b4379..97a6f393 100644 --- a/src/bdd/cudd/cuddBridge.c +++ b/src/bdd/cudd/cuddBridge.c @@ -8,48 +8,76 @@ different managers.] Description [External procedures included in this file: - <ul> - <li> Cudd_addBddThreshold() - <li> Cudd_addBddStrictThreshold() - <li> Cudd_addBddInterval() - <li> Cudd_addBddIthBit() - <li> Cudd_BddToAdd() - <li> Cudd_addBddPattern() - <li> Cudd_bddTransfer() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddBddTransfer() - <li> cuddAddBddDoPattern() - </ul> - Static procedures included in this file: - <ul> - <li> addBddDoThreshold() - <li> addBddDoStrictThreshold() - <li> addBddDoInterval() - <li> addBddDoIthBit() - <li> ddBddToAddRecur() - <li> cuddBddTransferRecur() - </ul> - ] + <ul> + <li> Cudd_addBddThreshold() + <li> Cudd_addBddStrictThreshold() + <li> Cudd_addBddInterval() + <li> Cudd_addBddIthBit() + <li> Cudd_BddToAdd() + <li> Cudd_addBddPattern() + <li> Cudd_bddTransfer() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddBddTransfer() + <li> cuddAddBddDoPattern() + </ul> + Static procedures included in this file: + <ul> + <li> addBddDoThreshold() + <li> addBddDoStrictThreshold() + <li> addBddDoInterval() + <li> addBddDoIthBit() + <li> ddBddToAddRecur() + <li> cuddBddTransferRecur() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -70,7 +98,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.19 2008/04/25 06:42:55 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -78,21 +106,29 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addBddDoThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val)); -static DdNode * addBddDoStrictThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val)); -static DdNode * addBddDoInterval ARGS((DdManager *dd, DdNode *f, DdNode *l, DdNode *u)); -static DdNode * addBddDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index)); -static DdNode * ddBddToAddRecur ARGS((DdManager *dd, DdNode *B)); -static DdNode * cuddBddTransferRecur ARGS((DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table)); +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -128,13 +164,13 @@ Cudd_addBddThreshold( cuddRef(val); do { - dd->reordered = 0; - res = addBddDoThreshold(dd, f, val); + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, val); - return(NULL); + Cudd_RecursiveDeref(dd, val); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, val); @@ -173,13 +209,13 @@ Cudd_addBddStrictThreshold( cuddRef(val); do { - dd->reordered = 0; - res = addBddDoStrictThreshold(dd, f, val); + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, val); - return(NULL); + Cudd_RecursiveDeref(dd, val); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, val); @@ -223,20 +259,20 @@ Cudd_addBddInterval( cuddRef(l); u = cuddUniqueConst(dd,upper); if (u == NULL) { - Cudd_RecursiveDeref(dd,l); - return(NULL); + Cudd_RecursiveDeref(dd,l); + return(NULL); } cuddRef(u); do { - dd->reordered = 0; - res = addBddDoInterval(dd, f, l, u); + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, l); - Cudd_RecursiveDeref(dd, u); - return(NULL); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, l); @@ -280,13 +316,13 @@ Cudd_addBddIthBit( cuddRef(index); do { - dd->reordered = 0; - res = addBddDoIthBit(dd, f, index); + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, index); - return(NULL); + Cudd_RecursiveDeref(dd, index); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, index); @@ -317,8 +353,8 @@ Cudd_BddToAdd( DdNode *res; do { - dd->reordered = 0; - res = ddBddToAddRecur(dd, B); + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); } while (dd->reordered ==1); return(res); @@ -347,8 +383,8 @@ Cudd_addBddPattern( DdNode *res; do { - dd->reordered = 0; - res = cuddAddBddDoPattern(dd, f); + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); } while (dd->reordered == 1); return(res); @@ -377,8 +413,8 @@ Cudd_bddTransfer( { DdNode *res; do { - ddDestination->reordered = 0; - res = cuddBddTransfer(ddSource, ddDestination, f); + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); } while (ddDestination->reordered == 1); return(res); @@ -414,7 +450,7 @@ cuddBddTransfer( st_generator *gen = NULL; DdNode *key, *value; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) goto failure; res = cuddBddTransferRecur(ddS, ddD, f, table); if (res != NULL) cuddRef(res); @@ -424,8 +460,8 @@ cuddBddTransfer( ** reordering. */ gen = st_init_gen(table); if (gen == NULL) goto failure; - while (st_gen(gen, (const char **) &key, (char **) &value)) { - Cudd_RecursiveDeref(ddD, value); + while (st_gen(gen, (const char **)&key, (char **)&value)) { + Cudd_RecursiveDeref(ddD, value); } st_free_gen(gen); gen = NULL; st_free_table(table); table = NULL; @@ -434,8 +470,8 @@ cuddBddTransfer( return(res); failure: + /* No need to free gen because it is always NULL here. */ if (table != NULL) st_free_table(table); - if (gen != NULL) st_free_gen(gen); return(NULL); } /* end of cuddBddTransfer */ @@ -465,7 +501,7 @@ cuddAddBddDoPattern( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); } /* Check cache. */ @@ -482,25 +518,25 @@ cuddAddBddDoPattern( E = cuddAddBddDoPattern(dd,fvn); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -543,7 +579,7 @@ addBddDoThreshold( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); } /* Check cache. */ @@ -560,25 +596,25 @@ addBddDoThreshold( E = addBddDoThreshold(dd,fvn,val); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -616,7 +652,7 @@ addBddDoStrictThreshold( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); } /* Check cache. */ @@ -633,25 +669,25 @@ addBddDoStrictThreshold( E = addBddDoStrictThreshold(dd,fvn,val); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -690,7 +726,7 @@ addBddDoInterval( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); } /* Check cache. */ @@ -707,25 +743,25 @@ addBddDoInterval( E = addBddDoInterval(dd,fvn,l,u); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -764,9 +800,9 @@ addBddDoIthBit( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - mask = 1 << ((int) cuddV(index)); - value = (int) cuddV(f); - return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); } /* Check cache. */ @@ -783,25 +819,25 @@ addBddDoIthBit( E = addBddDoIthBit(dd,fvn,index); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -839,24 +875,24 @@ ddBddToAddRecur( one = DD_ONE(dd); if (Cudd_IsConstant(B)) { - if (B == one) { - res = one; - } else { - res = DD_ZERO(dd); - } - return(res); + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); } /* Check visited table */ res = cuddCacheLookup1(dd,ddBddToAddRecur,B); if (res != NULL) return(res); if (Cudd_IsComplement(B)) { - complement = 1; - Bt = cuddT(Cudd_Regular(B)); - Be = cuddE(Cudd_Regular(B)); + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); } else { - Bt = cuddT(B); - Be = cuddE(B); + Bt = cuddT(B); + Be = cuddE(B); } T = ddBddToAddRecur(dd, Bt); @@ -865,32 +901,32 @@ ddBddToAddRecur( E = ddBddToAddRecur(dd, Be); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); /* No need to check for T == E, because it is guaranteed not to happen. */ res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); if (res == NULL) { - Cudd_RecursiveDeref(dd ,T); - Cudd_RecursiveDeref(dd ,E); - return(NULL); + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); } cuddDeref(T); cuddDeref(E); if (complement) { - cuddRef(res); - res1 = cuddAddCmplRecur(dd, res); - if (res1 == NULL) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); Cudd_RecursiveDeref(dd, res); - return(NULL); - } - cuddRef(res1); - Cudd_RecursiveDeref(dd, res); - res = res1; - cuddDeref(res); + res = res1; + cuddDeref(res); } /* Store result. */ @@ -922,7 +958,7 @@ cuddBddTransferRecur( { DdNode *ft, *fe, *t, *e, *var, *res; DdNode *one, *zero; - int index; + int index; int comple = 0; statLine(ddD); @@ -937,8 +973,13 @@ cuddBddTransferRecur( /* Now f is a regular pointer to a non-constant node. */ /* Check the cache. */ - if(st_lookup(table, (char *)f, (char **) &res)) - return(Cudd_NotCond(res,comple)); + if (st_lookup(table, (const char *)f, (char **)&res)) + return(Cudd_NotCond(res,comple)); + + if ( ddS->TimeStop && ddS->TimeStop < clock() ) + return NULL; + if ( ddD->TimeStop && ddD->TimeStop < clock() ) + return NULL; /* Recursive step. */ index = f->index; @@ -960,27 +1001,29 @@ cuddBddTransferRecur( zero = Cudd_Not(one); var = cuddUniqueInter(ddD,index,one,zero); if (var == NULL) { - Cudd_RecursiveDeref(ddD, t); - Cudd_RecursiveDeref(ddD, e); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); return(NULL); } res = cuddBddIteRecur(ddD,var,t,e); if (res == NULL) { - Cudd_RecursiveDeref(ddD, t); - Cudd_RecursiveDeref(ddD, e); - return(NULL); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(ddD, t); Cudd_RecursiveDeref(ddD, e); if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { - Cudd_RecursiveDeref(ddD, res); - return(NULL); + Cudd_RecursiveDeref(ddD, res); + return(NULL); } return(Cudd_NotCond(res,comple)); } /* end of cuddBddTransferRecur */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCache.c b/src/bdd/cudd/cuddCache.c index d66a8606..d9722ee9 100644 --- a/src/bdd/cudd/cuddCache.c +++ b/src/bdd/cudd/cuddCache.c @@ -7,41 +7,69 @@ Synopsis [Functions for cache insertion and lookup.] Description [Internal procedures included in this module: - <ul> - <li> cuddInitCache() - <li> cuddCacheInsert() - <li> cuddCacheInsert2() - <li> cuddCacheLookup() - <li> cuddCacheLookupZdd() - <li> cuddCacheLookup2() - <li> cuddCacheLookup2Zdd() - <li> cuddConstantLookup() - <li> cuddCacheProfile() - <li> cuddCacheResize() - <li> cuddCacheFlush() - <li> cuddComputeFloorLog2() - </ul> - Static procedures included in this module: - <ul> - </ul> ] + <ul> + <li> cuddInitCache() + <li> cuddCacheInsert() + <li> cuddCacheInsert2() + <li> cuddCacheLookup() + <li> cuddCacheLookupZdd() + <li> cuddCacheLookup2() + <li> cuddCacheLookup2Zdd() + <li> cuddConstantLookup() + <li> cuddCacheProfile() + <li> cuddCacheResize() + <li> cuddCacheFlush() + <li> cuddComputeFloorLog2() + </ul> + Static procedures included in this module: + <ul> + </ul> ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -65,7 +93,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.34 2009/02/19 16:17:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -123,8 +151,8 @@ cuddInitCache( cacheSize = 1 << logSize; unique->acache = ABC_ALLOC(DdCache,cacheSize+1); if (unique->acache == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } /* If the size of the cache entry is a power of 2, we want to ** enforce alignment to that power of two. This happens when @@ -145,8 +173,8 @@ cuddInitCache( unique->maxCacheHard = maxCacheSize; /* If cacheSlack is non-negative, we can resize. */ unique->cacheSlack = (int) ddMin(maxCacheSize, - DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - - 2 * (int) cacheSize; + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; Cudd_SetMinHit(unique,DD_MIN_HIT); /* Initialize to avoid division by 0 and immediate resizing. */ unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); @@ -163,10 +191,10 @@ cuddInitCache( /* Initialize the cache */ for (i = 0; (unsigned) i < cacheSize; i++) { - unique->cache[i].h = 0; /* unused slots */ - unique->cache[i].data = NULL; /* invalid entry */ + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ #ifdef DD_CACHE_PROFILE - unique->cache[i].count = 0; + unique->cache[i].count = 0; #endif } @@ -235,7 +263,7 @@ cuddCacheInsert( void cuddCacheInsert2( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g, DdNode * data) @@ -277,7 +305,7 @@ cuddCacheInsert2( void cuddCacheInsert1( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f, DdNode * data) { @@ -343,21 +371,21 @@ cuddCacheLookup( posn = ddCHash2(uh,uf,ug,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && - en->h==uh) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -405,21 +433,21 @@ cuddCacheLookupZdd( posn = ddCHash2(uh,uf,ug,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && - en->h==uh) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -443,7 +471,7 @@ cuddCacheLookupZdd( DdNode * cuddCacheLookup2( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g) { @@ -461,20 +489,20 @@ cuddCacheLookup2( posn = ddCHash2(op,f,g,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -497,7 +525,7 @@ cuddCacheLookup2( DdNode * cuddCacheLookup1( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f) { int posn; @@ -514,20 +542,20 @@ cuddCacheLookup1( posn = ddCHash2(op,f,f,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -551,7 +579,7 @@ cuddCacheLookup1( DdNode * cuddCacheLookup2Zdd( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g) { @@ -569,20 +597,20 @@ cuddCacheLookup2Zdd( posn = ddCHash2(op,f,g,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -605,7 +633,7 @@ cuddCacheLookup2Zdd( DdNode * cuddCacheLookup1Zdd( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f) { int posn; @@ -622,20 +650,20 @@ cuddCacheLookup1Zdd( posn = ddCHash2(op,f,f,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -688,8 +716,8 @@ cuddConstantLookup( * referenced, but only tested for being a constant. */ if (en->data != NULL && - en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { - table->cacheHits++; + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; return(en->data); } @@ -697,8 +725,8 @@ cuddConstantLookup( table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -746,46 +774,46 @@ cuddCacheProfile( hystogramQ = ABC_ALLOC(double, nbins); if (hystogramQ == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } hystogramR = ABC_ALLOC(double, nbins); if (hystogramR == NULL) { - ABC_FREE(hystogramQ); - table->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < nbins; i++) { - hystogramQ[i] = 0; - hystogramR[i] = 0; + hystogramQ[i] = 0; + hystogramR[i] = 0; } for (i = 0; i < slots; i++) { - thiscount = (long) cache[i].count; - if (thiscount > max) { - max = thiscount; - imax = i; - } - if (thiscount < min) { - min = thiscount; - imin = i; - } - if (thiscount == 0) { - nzeroes++; - } - count = (double) thiscount; - mean += count; - meansq += count * count; - totalcount += count; - expected += count * (double) i; - bin = (i * nbins) / slots; - hystogramQ[bin] += (double) thiscount; - bin = i % nbins; - hystogramR[bin] += (double) thiscount; + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; } mean /= (double) slots; meansq /= (double) slots; - + /* Compute the standard deviation from both the data and the ** theoretical model for a random distribution. */ stddev = sqrt(meansq - mean*mean); @@ -803,43 +831,43 @@ cuddCacheProfile( if (retval == EOF) return(0); exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", - 100.0 - (double) nzeroes * 100.0 / (double) slots, - exUsed); + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); if (retval == EOF) return(0); if (totalcount > 0) { - expected /= totalcount; - retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); - if (retval == EOF) return(0); - retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", - expected); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp," %.0f", hystogramQ[i]); + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\nBy residue: "); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp," %.0f", hystogramR[i]); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\n"); - if (retval == EOF) return(0); } ABC_FREE(hystogramQ); ABC_FREE(hystogramR); #else for (i = 0; i < slots; i++) { - nzeroes += cache[i].h == 0; + nzeroes += cache[i].h == 0; } exUsed = 100.0 * - (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / - (double) slots)); + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", - 100.0 - (double) nzeroes * 100.0 / (double) slots, - exUsed); + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); if (retval == EOF) return(0); #endif return(1); @@ -868,8 +896,8 @@ cuddCacheResize( unsigned int slots, oldslots; double offset; int moved = 0; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifndef DD_CACHE_PROFILE ptruint misalignment; DdNodePtr *mem; @@ -882,11 +910,11 @@ cuddCacheResize( #ifdef DD_VERBOSE (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", - oldslots, slots); + oldslots, slots); (void) fprintf(table->err, - "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", - table->cacheHits, table->cacheMisses, - table->cacheHits / (table->cacheHits + table->cacheMisses)); + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); #endif saveHandler = MMoutOfMemory; @@ -896,14 +924,14 @@ cuddCacheResize( /* If we fail to allocate the new table we just give up. */ if (cache == NULL) { #ifdef DD_VERBOSE - (void) fprintf(table->err,"Resizing failed. Giving up.\n"); + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); #endif - table->cacheSlots = oldslots; - table->acache = oldacache; - /* Do not try to resize again. */ - table->maxCacheHard = oldslots - 1; - table->cacheSlack = - (int)(oldslots + 1); - return; + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; } /* If the size of the cache entry is a power of 2, we want to ** enforce alignment to that power of two. This happens when @@ -923,28 +951,28 @@ cuddCacheResize( /* Clear new cache. */ for (i = 0; (unsigned) i < slots; i++) { - cache[i].data = NULL; - cache[i].h = 0; + cache[i].data = NULL; + cache[i].h = 0; #ifdef DD_CACHE_PROFILE - cache[i].count = 0; + cache[i].count = 0; #endif } /* Copy from old cache to new one. */ for (i = 0; (unsigned) i < oldslots; i++) { - old = &oldcache[i]; - if (old->data != NULL) { - posn = ddCHash2(old->h,old->f,old->g,shift); - entry = &cache[posn]; - entry->f = old->f; - entry->g = old->g; - entry->h = old->h; - entry->data = old->data; + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; #ifdef DD_CACHE_PROFILE - entry->count = 1; + entry->count = 1; #endif - moved++; - } + moved++; + } } ABC_FREE(oldacache); @@ -983,8 +1011,8 @@ cuddCacheFlush( slots = table->cacheSlots; cache = table->cache; for (i = 0; i < slots; i++) { - table->cachedeletions += cache[i].data != NULL; - cache[i].data = NULL; + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; } table->cacheLastInserts = table->cacheinserts; @@ -1014,8 +1042,8 @@ cuddComputeFloorLog2( assert(value > 0); #endif while (value > 1) { - floorLog++; - value >>= 1; + floorLog++; + value >>= 1; } return(floorLog); @@ -1024,5 +1052,7 @@ cuddComputeFloorLog2( /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddCheck.c b/src/bdd/cudd/cuddCheck.c index 92c0f5e1..5526aaf2 100644 --- a/src/bdd/cudd/cuddCheck.c +++ b/src/bdd/cudd/cuddCheck.c @@ -7,30 +7,57 @@ Synopsis [Functions to check consistency of data structures.] Description [External procedures included in this module: - <ul> - <li> Cudd_DebugCheck() - <li> Cudd_CheckKeys() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddHeapProfile() - <li> cuddPrintNode() - <li> cuddPrintVarGroups() - </ul> - Static procedures included in this module: - <ul> - <li> debugFindParent() - </ul> - ] + <ul> + <li> Cudd_DebugCheck() + <li> Cudd_CheckKeys() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddHeapProfile() + <li> cuddPrintNode() + <li> cuddPrintVarGroups() + </ul> + Static procedures included in this module: + <ul> + <li> debugFindParent() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,7 +88,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.35 2009/03/08 02:49:01 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -74,9 +102,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void debugFindParent ARGS((DdManager *table, DdNode *node)); +static void debugFindParent (DdManager *table, DdNode *node); #if 0 -static void debugCheckParent ARGS((DdManager *table, DdNode *node)); +static void debugCheckParent (DdManager *table, DdNode *node); #endif /**AutomaticEnd***************************************************************/ @@ -115,232 +143,233 @@ Cudd_DebugCheck( DdManager * table) { unsigned int i; - int j,count; - int slots; - DdNodePtr *nodelist; - DdNode *f; - DdNode *sentinel = &(table->sentinel); - st_table *edgeTable; /* stores internal ref count for each node */ - st_generator *gen; - int flag = 0; - int totalNode; - int deadNode; - int index; - - - edgeTable = st_init_table(st_ptrcmp, st_ptrhash);; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); /* Check the BDD/ADD subtables. */ for (i = 0; i < (unsigned) table->size; i++) { - index = table->invperm[i]; - if (i != (unsigned) table->perm[index]) { - (void) fprintf(table->err, - "Permutation corrupted: invperm[%d] = %d\t perm[%d] = %d\n", - i, index, index, table->perm[index]); - } - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - - totalNode = 0; - deadNode = 0; - for (j = 0; j < slots; j++) { /* for each subtable slot */ - f = nodelist[j]; - while (f != sentinel) { - totalNode++; - if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { - if ((int) f->index != index) { - (void) fprintf(table->err, - "Error: node has illegal index\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if ((unsigned) cuddI(table,cuddT(f)->index) <= i || - (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) - <= i) { - (void) fprintf(table->err, - "Error: node has illegal children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (Cudd_Regular(cuddT(f)) != cuddT(f)) { - (void) fprintf(table->err, - "Error: node has illegal form\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f) == cuddE(f)) { - (void) fprintf(table->err, - "Error: node has identical children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { (void) fprintf(table->err, - "Error: live node has dead children\n"); - cuddPrintNode(f,table->err); - flag =1; - } - /* Increment the internal reference count for the - ** then child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddT(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddT(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - - /* Increment the internal reference count for the - ** else child of the current node. - */ - if (st_lookup(edgeTable,(char *)Cudd_Regular(cuddE(f)),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { - deadNode++; + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; #if 0 - debugCheckParent(table,f); + debugCheckParent(table,f); #endif - } else { - fprintf(table->err, - "Error: node has illegal Then or Else pointers\n"); - cuddPrintNode(f,table->err); + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); flag = 1; } - - f = f->next; - } /* for each element of the collision list */ - } /* for each subtable slot */ - - if ((unsigned) totalNode != table->subtables[i].keys) { - fprintf(table->err,"Error: wrong number of total nodes\n"); - flag = 1; - } - if ((unsigned) deadNode != table->subtables[i].dead) { - fprintf(table->err,"Error: wrong number of dead nodes\n"); - flag = 1; - } - } /* for each BDD/ADD subtable */ + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ /* Check the ZDD subtables. */ for (i = 0; i < (unsigned) table->sizeZ; i++) { - index = table->invpermZ[i]; - if (i != (unsigned) table->permZ[index]) { - (void) fprintf(table->err, - "Permutation corrupted: invpermZ[%d] = %d\t permZ[%d] = %d in ZDD\n", - i, index, index, table->permZ[index]); - } - nodelist = table->subtableZ[i].nodelist; - slots = table->subtableZ[i].slots; - - totalNode = 0; - deadNode = 0; - for (j = 0; j < slots; j++) { /* for each subtable slot */ - f = nodelist[j]; - while (f != NULL) { - totalNode++; - if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { - if ((int) f->index != index) { - (void) fprintf(table->err, - "Error: ZDD node has illegal index\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (Cudd_IsComplement(cuddT(f)) || - Cudd_IsComplement(cuddE(f))) { - (void) fprintf(table->err, - "Error: ZDD node has complemented children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || - (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { - (void) fprintf(table->err, - "Error: ZDD node has illegal children\n"); - cuddPrintNode(f,table->err); - cuddPrintNode(cuddT(f),table->err); - cuddPrintNode(cuddE(f),table->err); - flag = 1; - } - if (cuddT(f) == DD_ZERO(table)) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { (void) fprintf(table->err, - "Error: ZDD node has zero then child\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { - (void) fprintf(table->err, - "Error: ZDD live node has dead children\n"); - cuddPrintNode(f,table->err); - flag =1; - } - /* Increment the internal reference count for the - ** then child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddT(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddT(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - - /* Increment the internal reference count for the - ** else child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddE(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddE(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - table->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); - } - } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { - deadNode++; + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; #if 0 - debugCheckParent(table,f); + debugCheckParent(table,f); #endif - } else { + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { fprintf(table->err, - "Error: ZDD node has illegal Then or Else pointers\n"); - cuddPrintNode(f,table->err); + "Error: wrong number of total nodes in ZDD\n"); flag = 1; } - - f = f->next; - } /* for each element of the collision list */ - } /* for each subtable slot */ - - if ((unsigned) totalNode != table->subtableZ[i].keys) { - fprintf(table->err, - "Error: wrong number of total nodes in ZDD\n"); - flag = 1; - } - if ((unsigned) deadNode != table->subtableZ[i].dead) { - fprintf(table->err, - "Error: wrong number of dead nodes in ZDD\n"); - flag = 1; - } - } /* for each ZDD subtable */ + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ /* Check the constant table. */ nodelist = table->constants.nodelist; @@ -349,50 +378,50 @@ Cudd_DebugCheck( totalNode = 0; deadNode = 0; for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != NULL) { - totalNode++; - if (f->ref != 0) { - if (f->index != CUDD_CONST_INDEX) { - fprintf(table->err,"Error: node has illegal index\n"); + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); #if SIZEOF_VOID_P == 8 - fprintf(table->err, - " node 0x%lx, id = %d, ref = %d, value = %g\n", - (unsigned long)f,f->index,f->ref,cuddV(f)); + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); #else - fprintf(table->err, - " node 0x%x, id = %d, ref = %d, value = %g\n", - (unsigned)f,f->index,f->ref,cuddV(f)); + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); #endif - flag = 1; - } - } else { - deadNode++; + flag = 1; + } + } else { + deadNode++; + } + f = f->next; } - f = f->next; - } } if ((unsigned) totalNode != table->constants.keys) { - (void) fprintf(table->err, - "Error: wrong number of total nodes in constants\n"); - flag = 1; + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; } if ((unsigned) deadNode != table->constants.dead) { - (void) fprintf(table->err, - "Error: wrong number of dead nodes in constants\n"); - flag = 1; + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; } gen = st_init_gen(edgeTable); - while (st_gen(gen,(const char **)&f,(char **)&count)) { - if (count > (int)(f->ref) && f->ref != DD_MAXREF) { + while (st_gen(gen, (const char **)&f, (char **)&count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { #if SIZEOF_VOID_P == 8 - fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n",(unsigned long)f,count,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #else - fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",(unsigned)f,count,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #endif - debugFindParent(table,f); - flag = 1; - } + debugFindParent(table,f); + flag = 1; + } } st_free_gen(gen); st_free_table(edgeTable); @@ -449,80 +478,80 @@ Cudd_CheckKeys( size = table->size; for (i = 0; i < size; i++) { - subtable = &(table->subtables[i]); - nodelist = subtable->nodelist; - keys = subtable->keys; - dead = subtable->dead; - totalKeys += keys; - slots = subtable->slots; - shift = subtable->shift; - logSlots = sizeof(int) * 8 - shift; - if (((slots >> logSlots) << logSlots) != slots) { - (void) fprintf(table->err, - "Unique table %d is not the right power of 2\n", i); - (void) fprintf(table->err, - " slots = %u shift = %d\n", slots, shift); - } - totalSlots += slots; - totalDead += dead; - for (j = 0; (unsigned) j < slots; j++) { - node = nodelist[j]; - if (node != sentinel) { - nonEmpty++; - } - while (node != sentinel) { - keys--; - if (node->ref == 0) { - dead--; + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); } - node = node->next; + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } } - } - if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ in unique table %d (difference=%d)\n", i, keys); - count++; - } - if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ in unique table no. %d (difference=%d)\n", i, dead); - } - } /* for each BDD/ADD subtable */ + } + } /* for each BDD/ADD subtable */ /* Check the ZDD subtables. */ size = table->sizeZ; for (i = 0; i < size; i++) { - subtable = &(table->subtableZ[i]); - nodelist = subtable->nodelist; - keys = subtable->keys; - dead = subtable->dead; - totalKeys += keys; - totalSlots += subtable->slots; - totalDead += dead; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - nonEmpty++; - } - while (node != NULL) { - keys--; - if (node->ref == 0) { - dead--; - } - node = node->next; + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } } - } - if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ in ZDD unique table no. %d (difference=%d)\n", i, keys); - count++; - } - if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ in ZDD unique table no. %d (difference=%d)\n", i, dead); - } - } /* for each ZDD subtable */ + } + } /* for each ZDD subtable */ /* Check the constant table. */ subtable = &(table->constants); @@ -533,43 +562,43 @@ in ZDD unique table no. %d (difference=%d)\n", i, dead); totalSlots += subtable->slots; totalDead += dead; for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - nonEmpty++; - } - while (node != NULL) { - keys--; - if (node->ref == 0) { - dead--; + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; } - node = node->next; - } } if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + (void) fprintf(table->err, "Wrong number of keys found \ in the constant table (difference=%d)\n", keys); - count++; + count++; } if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + (void) fprintf(table->err, "Wrong number of dead found \ in the constant table (difference=%d)\n", dead); } if ((unsigned) totalKeys != table->keys + table->keysZ) { - (void) fprintf(table->err, "Wrong number of total keys found \ -(difference=%d)\n", totalKeys-table->keys); + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); } if ((unsigned) totalSlots != table->slots) { - (void) fprintf(table->err, "Wrong number of total slots found \ -(difference=%d)\n", totalSlots-table->slots); + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); } if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { - (void) fprintf(table->err, "Wrong number of minimum dead found \ -(%d vs. %d)\n", table->minDead, - (unsigned) (table->gcFrac * (double) table->slots)); + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); } if ((unsigned) totalDead != table->dead + table->deadZ) { - (void) fprintf(table->err, "Wrong number of total dead found \ -(difference=%d)\n", totalDead-table->dead); + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); } (void)printf("Average length of non-empty lists = %g\n", (double) table->keys / (double) nonEmpty); @@ -612,51 +641,51 @@ cuddHeapProfile( { int ntables = dd->size; DdSubtable *subtables = dd->subtables; - int i, /* loop index */ - nodes, /* live nodes in i-th layer */ - retval, /* return value of fprintf */ - largest = -1, /* index of the table with most live nodes */ - maxnodes = -1, /* maximum number of live nodes in a table */ - nonempty = 0; /* number of tables with live nodes */ + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ /* Print header. */ #if SIZEOF_VOID_P == 8 retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", - (unsigned long) dd); + (ptruint) dd); #else retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", - (unsigned) dd); + (ptruint) dd); #endif if (retval == EOF) return 0; /* Print number of live nodes for each nonempty table. */ for (i=0; i<ntables; i++) { - nodes = subtables[i].keys - subtables[i].dead; - if (nodes) { - nonempty++; - retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes); - if (retval == EOF) return 0; - if (nodes > maxnodes) { - maxnodes = nodes; - largest = i; + nodes = subtables[i].keys - subtables[i].dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } } } - } nodes = dd->constants.keys - dd->constants.dead; if (nodes) { - nonempty++; - retval = fprintf(dd->out,"const: %5d nodes\n", nodes); - if (retval == EOF) return 0; - if (nodes > maxnodes) { - maxnodes = nodes; - largest = CUDD_CONST_INDEX; - } + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } } /* Print summary. */ retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", - ntables+1, nonempty, largest); + ntables+1, nonempty, largest); if (retval == EOF) return 0; retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); if (retval == EOF) return 0; @@ -684,9 +713,9 @@ cuddPrintNode( { f = Cudd_Regular(f); #if SIZEOF_VOID_P == 8 - (void) fprintf(fp," node 0x%lx, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n",(unsigned long)f,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #else - (void) fprintf(fp," node 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",(unsigned)f,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #endif } /* end of cuddPrintNode */ @@ -728,32 +757,32 @@ cuddPrintVarGroups( assert(root->younger == NULL || root->younger->elder == root); assert(root->elder == NULL || root->elder->younger == root); if (zdd) { - level = dd->permZ[root->index]; + level = dd->permZ[root->index]; } else { - level = dd->perm[root->index]; + level = dd->perm[root->index]; } if (!silent) (void) printf("(%d",level); if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { - if (!silent) (void) printf(","); + if (!silent) (void) printf(","); } else { - node = root->child; - while (node != NULL) { - assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); - assert(node->parent == root); - cuddPrintVarGroups(dd,node,zdd,silent); - node = node->younger; - } + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } } if (!silent) { - (void) printf("%d", level + root->size - 1); - if (root->flags != MTR_DEFAULT) { - (void) printf("|"); - if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); - if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); - if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); - } - (void) printf(")"); - if (root->parent == NULL) (void) printf("\n"); + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); } assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); return; @@ -783,29 +812,29 @@ debugFindParent( DdNode * node) { int i,j; - int slots; - DdNodePtr *nodelist; - DdNode *f; - + int slots; + DdNodePtr *nodelist; + DdNode *f; + for (i = 0; i < cuddI(table,node->index); i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; - for (j=0;j<slots;j++) { - f = nodelist[j]; - while (f != NULL) { - if (cuddT(f) == node || Cudd_Regular(cuddE(f)) == node) { + for (j=0;j<slots;j++) { + f = nodelist[j]; + while (f != NULL) { + if (cuddT(f) == node || Cudd_Regular(cuddE(f)) == node) { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out,"parent is at 0x%lx, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n", - (unsigned long)f,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + (void) fprintf(table->out,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #else - (void) fprintf(table->out,"parent is at 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n", - (unsigned)f,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #endif + } + f = f->next; + } } - f = f->next; - } - } } } /* end of debugFindParent */ @@ -830,27 +859,29 @@ debugCheckParent( DdNode * node) { int i,j; - int slots; - DdNode **nodelist,*f; - - for (i = 0; i < cuddI(table,node->index); i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + int slots; + DdNode **nodelist,*f; - for (j=0;j<slots;j++) { - f = nodelist[j]; - while (f != NULL) { - if ((Cudd_Regular(cuddE(f)) == node || cuddT(f) == node) && f->ref != 0) { - (void) fprintf(table->err, - "error with zero ref count\n"); - (void) fprintf(table->err,"parent is 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); - (void) fprintf(table->err,"child is 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); - } - f = f->next; + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;j<slots;j++) { + f = nodelist[j]; + while (f != NULL) { + if ((Cudd_Regular(cuddE(f)) == node || cuddT(f) == node) && f->ref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } } } - } } #endif + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddClip.c b/src/bdd/cudd/cuddClip.c index 23331339..028474fe 100644 --- a/src/bdd/cudd/cuddClip.c +++ b/src/bdd/cudd/cuddClip.c @@ -7,29 +7,56 @@ Synopsis [Clipping functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddClippingAnd() - <li> Cudd_bddClippingAndAbstract() - </ul> + <ul> + <li> Cudd_bddClippingAnd() + <li> Cudd_bddClippingAndAbstract() + </ul> Internal procedures included in this module: - <ul> - <li> cuddBddClippingAnd() - <li> cuddBddClippingAndAbstract() - </ul> + <ul> + <li> cuddBddClippingAnd() + <li> cuddBddClippingAndAbstract() + </ul> Static procedures included in this module: - <ul> - <li> cuddBddClippingAndRecur() - <li> cuddBddClipAndAbsRecur() - </ul> + <ul> + <li> cuddBddClippingAndRecur() + <li> cuddBddClipAndAbsRecur() + </ul> SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.8 2004/08/13 18:04:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -73,8 +101,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 w /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * cuddBddClippingAndRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, int distance, int direction)); -static DdNode * cuddBddClipAndAbsRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction)); +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); /**AutomaticEnd***************************************************************/ @@ -108,8 +136,8 @@ Cudd_bddClippingAnd( DdNode *res; do { - dd->reordered = 0; - res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); } while (dd->reordered == 1); return(res); @@ -143,8 +171,8 @@ Cudd_bddClippingAndAbstract( DdNode *res; do { - dd->reordered = 0; - res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); } while (dd->reordered == 1); return(res); @@ -248,7 +276,7 @@ cuddBddClippingAndRecur( DdNode *F, *ft, *fe, *G, *gt, *ge; DdNode *one, *zero, *r, *t, *e; unsigned int topf, topg, index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(manager); one = DD_ONE(manager); @@ -259,15 +287,15 @@ cuddBddClippingAndRecur( if (f == g || g == one) return(f); if (f == one) return(g); if (distance == 0) { - /* One last attempt at returning the right result. We sort of - ** cheat by calling Cudd_bddLeq. */ - if (Cudd_bddLeq(manager,f,g)) return(f); - if (Cudd_bddLeq(manager,g,f)) return(g); - if (direction == 1) { - if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || - Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); - } - return(Cudd_NotCond(one,(direction == 0))); + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); } /* At this point f and g are not constant. */ @@ -276,16 +304,16 @@ cuddBddClippingAndRecur( /* Check cache. Try to increase cache efficiency by sorting the ** pointers. */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } F = Cudd_Regular(f); G = Cudd_Regular(g); - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) - (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup2(manager, cacheOp, f, g); - if (r != NULL) return(r); + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); } /* Here we can skip the use of cuddI, because the operands are known @@ -296,27 +324,27 @@ cuddBddClippingAndRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg <= topf) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); @@ -324,35 +352,35 @@ cuddBddClippingAndRecur( cuddRef(t); e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); if (e == NULL) { - Cudd_RecursiveDeref(manager, t); - return(NULL); + Cudd_RecursiveDeref(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; + r = t; } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); - } - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(manager, cacheOp, f, g, r); + cuddCacheInsert2(manager, cacheOp, f, g, r); return(r); } /* end of cuddBddClippingAndRecur */ @@ -393,15 +421,15 @@ cuddBddClipAndAbsRecur( /* Terminal cases. */ if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); - if (f == one && g == one) return(one); + if (f == one && g == one) return(one); if (cube == one) { - return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); } if (f == one || f == g) { - return (cuddBddExistAbstractRecur(manager, g, cube)); + return (cuddBddExistAbstractRecur(manager, g, cube)); } if (g == one) { - return (cuddBddExistAbstractRecur(manager, f, cube)); + return (cuddBddExistAbstractRecur(manager, f, cube)); } if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); @@ -410,19 +438,19 @@ cuddBddClipAndAbsRecur( /* Check cache. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } F = Cudd_Regular(f); G = Cudd_Regular(g); cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : - DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup(manager, cacheTag, - f, g, cube); - if (r != NULL) { - return(r); - } + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } } /* Here we can skip the use of cuddI, because the operands are known @@ -434,39 +462,39 @@ cuddBddClipAndAbsRecur( topcube = manager->perm[cube->index]; if (topcube < top) { - return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), - distance, direction)); + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); } /* Now, topcube >= top. */ if (topf == top) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg == top) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } if (topcube == top) { - Cube = cuddT(cube); + Cube = cuddT(cube); } else { - Cube = cube; + Cube = cube; } t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); @@ -476,61 +504,63 @@ cuddBddClipAndAbsRecur( ** the else branch if t is 1. */ if (t == one && topcube == top) { - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, cacheTag, f, g, cube, one); - return(one); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); } cuddRef(t); e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); if (e == NULL) { - Cudd_RecursiveDeref(manager, t); - return(NULL); - } - cuddRef(e); - - if (topcube == top) { /* abstract */ - r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), - distance, (direction == 0)); - if (r == NULL) { Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); return(NULL); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - cuddDeref(r); - } else if (t == e) { - r = t; - cuddDeref(t); - cuddDeref(e); - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); } r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(r); Cudd_RecursiveDeref(manager, t); Cudd_RecursiveDeref(manager, e); - return(NULL); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } } - } - cuddDeref(e); - cuddDeref(t); + cuddDeref(e); + cuddDeref(t); } if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, cacheTag, f, g, cube, r); + cuddCacheInsert(manager, cacheTag, f, g, cube, r); return (r); } /* end of cuddBddClipAndAbsRecur */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCof.c b/src/bdd/cudd/cuddCof.c index 26ff330d..004689c2 100644 --- a/src/bdd/cudd/cuddCof.c +++ b/src/bdd/cudd/cuddCof.c @@ -7,34 +7,62 @@ Synopsis [Cofactoring functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_Cofactor() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddGetBranches() - <li> cuddCheckCube() - <li> cuddCofactorRecur() - </ul> - ] + <ul> + <li> Cudd_Cofactor() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddGetBranches() + <li> cuddCheckCube() + <li> cuddCofactorRecur() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -55,7 +83,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -101,13 +129,13 @@ Cudd_Cofactor( zero = Cudd_Not(DD_ONE(dd)); if (g == zero || g == DD_ZERO(dd)) { - (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } do { - dd->reordered = 0; - res = cuddCofactorRecur(dd,f,g); + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -136,13 +164,13 @@ cuddGetBranches( DdNode ** g1, DdNode ** g0) { - DdNode *G = Cudd_Regular(g); + DdNode *G = Cudd_Regular(g); *g1 = cuddT(G); *g0 = cuddE(G); if (Cudd_IsComplement(g)) { - *g1 = Cudd_Not(*g1); - *g0 = Cudd_Not(*g0); + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); } } /* end of cuddGetBranches */ @@ -224,7 +252,7 @@ cuddCofactorRecur( comple = f != F; r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } topf = dd->perm[F->index]; @@ -237,57 +265,57 @@ cuddCofactorRecur( ** remembers whether we have to complement the result or not. */ if (topf <= topg) { - f1 = cuddT(F); f0 = cuddE(F); + f1 = cuddT(F); f0 = cuddE(F); } else { - f1 = f0 = F; + f1 = f0 = F; } if (topg <= topf) { - g1 = cuddT(G); g0 = cuddE(G); - if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } } else { - g1 = g0 = g; + g1 = g0 = g; } zero = Cudd_Not(one); if (topf >= topg) { - if (g0 == zero || g0 == DD_ZERO(dd)) { - r = cuddCofactorRecur(dd, f1, g1); - } else if (g1 == zero || g1 == DD_ZERO(dd)) { - r = cuddCofactorRecur(dd, f0, g0); - } else { - (void) fprintf(dd->out, - "Cudd_Cofactor: Invalid restriction 2\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); - } - if (r == NULL) return(NULL); + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); } else /* if (topf < topg) */ { - t = cuddCofactorRecur(dd, f1, g); - if (t == NULL) return(NULL); + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); cuddRef(t); e = cuddCofactorRecur(dd, f0, g); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - cuddRef(e); - - if (t == e) { - r = t; - } else if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); - if (r != NULL) - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(dd,(int)F->index,t,e); - } - if (r == NULL) { - Cudd_RecursiveDeref(dd ,e); - Cudd_RecursiveDeref(dd ,t); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); @@ -301,5 +329,7 @@ cuddCofactorRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCompose.c b/src/bdd/cudd/cuddCompose.c index 6fc4fa48..e3b2e556 100644 --- a/src/bdd/cudd/cuddCompose.c +++ b/src/bdd/cudd/cuddCompose.c @@ -7,38 +7,38 @@ Synopsis [Functional composition and variable permutation of DDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddCompose() - <li> Cudd_addCompose() - <li> Cudd_addPermute() - <li> Cudd_addSwapVariables() - <li> Cudd_bddPermute() - <li> Cudd_bddVarMap() - <li> Cudd_SetVarMap() - <li> Cudd_bddSwapVariables() - <li> Cudd_bddAdjPermuteX() - <li> Cudd_addVectorCompose() - <li> Cudd_addGeneralVectorCompose() - <li> Cudd_addNonSimCompose() - <li> Cudd_bddVectorCompose() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddComposeRecur() - <li> cuddAddComposeRecur() - </ul> - Static procedures included in this module: - <ul> - <li> cuddAddPermuteRecur() - <li> cuddBddPermuteRecur() - <li> cuddBddVarMapRecur() - <li> cuddAddVectorComposeRecur() - <li> cuddAddGeneralVectorComposeRecur() - <li> cuddAddNonSimComposeRecur() - <li> cuddBddVectorComposeRecur() - <li> ddIsIthAddVar() - <li> ddIsIthAddVarPair() - </ul> + <ul> + <li> Cudd_bddCompose() + <li> Cudd_addCompose() + <li> Cudd_addPermute() + <li> Cudd_addSwapVariables() + <li> Cudd_bddPermute() + <li> Cudd_bddVarMap() + <li> Cudd_SetVarMap() + <li> Cudd_bddSwapVariables() + <li> Cudd_bddAdjPermuteX() + <li> Cudd_addVectorCompose() + <li> Cudd_addGeneralVectorCompose() + <li> Cudd_addNonSimCompose() + <li> Cudd_bddVectorCompose() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddComposeRecur() + <li> cuddAddComposeRecur() + </ul> + Static procedures included in this module: + <ul> + <li> cuddAddPermuteRecur() + <li> cuddBddPermuteRecur() + <li> cuddBddVarMapRecur() + <li> cuddAddVectorComposeRecur() + <li> cuddAddGeneralVectorComposeRecur() + <li> cuddAddNonSimComposeRecur() + <li> cuddBddVectorComposeRecur() + <li> ddIsIthAddVar() + <li> ddIsIthAddVarPair() + </ul> The permutation functions use a local cache because the results to be remembered depend on the permutation being applied. Since the permutation is just an array, it cannot be stored in the global @@ -48,10 +48,37 @@ Author [Fabio Somenzi and Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -62,6 +89,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -79,7 +107,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.45 2004/08/13 18:04:47 fabio Exp $"; #endif #ifdef DD_DEBUG @@ -102,16 +130,16 @@ static int addGeneralVectorComposeHits; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * cuddAddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddVarMapRecur ARGS((DdManager *manager, DdNode *f)); -static DdNode * cuddAddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -static DdNode * cuddAddNonSimComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub)); -static DdNode * cuddBddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -DD_INLINE static int ddIsIthAddVar ARGS((DdManager *dd, DdNode *f, unsigned int i)); +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); -static DdNode * cuddAddGeneralVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest)); -DD_INLINE static int ddIsIthAddVarPair ARGS((DdManager *dd, DdNode *f, DdNode *g, unsigned int i)); +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); /**AutomaticEnd***************************************************************/ @@ -145,12 +173,12 @@ Cudd_bddCompose( DdNode *proj, *res; /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); + if (v < 0 || v >= dd->size) return(NULL); proj = dd->vars[v]; do { - dd->reordered = 0; - res = cuddBddComposeRecur(dd,f,g,proj); + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); } while (dd->reordered == 1); return(res); @@ -182,12 +210,12 @@ Cudd_addCompose( DdNode *proj, *res; /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); + if (v < 0 || v >= dd->size) return(NULL); proj = dd->vars[v]; do { - dd->reordered = 0; - res = cuddAddComposeRecur(dd,f,g,proj); + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); } while (dd->reordered == 1); return(res); @@ -216,18 +244,18 @@ Cudd_addPermute( DdNode * node, int * permut) { - DdHashTable *table; - DdNode *res; + DdHashTable *table; + DdNode *res; do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - /* Recursively solve the problem. */ - res = cuddAddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (manager->reordered == 1); if (res != NULL) cuddDeref(res); @@ -260,20 +288,20 @@ Cudd_addSwapVariables( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_addPermute(dd,f,permut); @@ -306,17 +334,17 @@ Cudd_bddPermute( DdNode * node, int * permut) { - DdHashTable *table; - DdNode *res; + DdHashTable *table; + DdNode *res; do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - res = cuddBddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (manager->reordered == 1); @@ -350,8 +378,8 @@ Cudd_bddVarMap( if (manager->map == NULL) return(NULL); do { - manager->reordered = 0; - res = cuddBddVarMapRecur(manager, f); + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); } while (manager->reordered == 1); return(res); @@ -394,23 +422,23 @@ Cudd_SetVarMap ( int i; if (manager->map != NULL) { - cuddCacheFlush(manager); + cuddCacheFlush(manager); } else { - manager->map = ABC_ALLOC(int,manager->maxSize); - if (manager->map == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(0); - } - manager->memused += sizeof(int) * manager->maxSize; + manager->map = ABC_ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; } /* Initialize the map to the identity. */ for (i = 0; i < manager->size; i++) { - manager->map[i] = i; + manager->map[i] = i; } /* Create the map. */ for (i = 0; i < n; i++) { - manager->map[x[i]->index] = y[i]->index; - manager->map[y[i]->index] = x[i]->index; + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; } return(1); @@ -441,20 +469,20 @@ Cudd_bddSwapVariables( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_bddPermute(dd,f,permut); @@ -488,20 +516,20 @@ Cudd_bddAdjPermuteX( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n-2; i += 3) { - j = x[i]->index; - k = x[i+1]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_bddPermute(dd,B,permut); @@ -537,31 +565,31 @@ Cudd_addVectorCompose( DdNode * f, DdNode ** vector) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVar(dd,vector[i],i)) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -596,32 +624,32 @@ Cudd_addGeneralVectorCompose( DdNode ** vectorOn, DdNode ** vectorOff) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, - vectorOff,deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -656,9 +684,9 @@ Cudd_addNonSimCompose( DdNode * f, DdNode ** vector) { - DdNode *cube, *key, *var, *tmp, *piece; - DdNode *res; - int i, lastsub; + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; /* The cache entry for this function is composed of three parts: ** f itself, the replacement relation, and the cube of the @@ -675,61 +703,61 @@ Cudd_addNonSimCompose( cube = DD_ONE(dd); cuddRef(cube); for (i = (int) dd->size - 1; i >= 0; i--) { - if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { - continue; - } - var = Cudd_addIthVar(dd,i); - if (var == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(var); - /* Update cube. */ - tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,key); + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; - /* Update replacement relation. */ - piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); - if (piece == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(piece); - Cudd_RecursiveDeref(dd,var); - tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); - if (tmp == NULL) { + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,key); Cudd_RecursiveDeref(dd,piece); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,piece); - key = tmp; + key = tmp; } /* Now try composition, until no reordering occurs. */ do { - /* Find real substitution with largest index. */ - for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { - if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { - break; + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } } - } - /* Recursively solve the problem. */ - dd->reordered = 0; - res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); } while (dd->reordered == 1); @@ -765,31 +793,31 @@ Cudd_bddVectorCompose( DdNode * f, DdNode ** vector) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (vector[i] != dd->vars[i]) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -825,9 +853,9 @@ cuddBddComposeRecur( DdNode * g, DdNode * proj) { - DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; unsigned int v, topf, topg, topindex; - int comple; + int comple; statLine(dd); v = dd->perm[proj->index]; @@ -845,60 +873,60 @@ cuddBddComposeRecur( /* Check cache. */ r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } if (topf == v) { - /* Compose. */ - f1 = cuddT(F); - f0 = cuddE(F); - r = cuddBddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - G = Cudd_Regular(g); - topg = cuddI(dd,G->index); - if (topf > topg) { - topindex = G->index; - f1 = f0 = F; - } else { - topindex = F->index; + /* Compose. */ f1 = cuddT(F); f0 = cuddE(F); - } - if (topg > topf) { - g1 = g0 = g; + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); } else { - g1 = cuddT(G); - g0 = cuddE(G); - if (g != G) { - g1 = Cudd_Not(g1); - g0 = Cudd_Not(g0); + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); } - } - /* Recursive step. */ - t = cuddBddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddBddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - cuddRef(e); + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); - r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ Cudd_IterDerefBdd(dd, e); - return(NULL); - } - cuddRef(r); - Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ - Cudd_IterDerefBdd(dd, e); - cuddDeref(r); + cuddDeref(r); } cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); @@ -940,57 +968,57 @@ cuddAddComposeRecur( /* Check cache. */ r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); if (r != NULL) { - return(r); + return(r); } if (topf == v) { - /* Compose. */ - f1 = cuddT(f); - f0 = cuddE(f); - r = cuddAddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - topg = cuddI(dd,g->index); - if (topf > topg) { - topindex = g->index; - f1 = f0 = f; - } else { - topindex = f->index; + /* Compose. */ f1 = cuddT(f); f0 = cuddE(f); - } - if (topg > topf) { - g1 = g0 = g; - } else { - g1 = cuddT(g); - g0 = cuddE(g); - } - /* Recursive step. */ - t = cuddAddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddAddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - cuddRef(e); - - if (t == e) { - r = t; + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); } else { - r = cuddUniqueInter(dd, (int) topindex, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); } - } - cuddDeref(t); - cuddDeref(e); + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); @@ -1032,22 +1060,22 @@ cuddAddPermuteRecur( DdNode * node /* ADD to be reordered */, int * permut /* permutation array */) { - DdNode *T,*E; - DdNode *res,*var; - int index; + DdNode *T,*E; + DdNode *res,*var; + int index; statLine(manager); /* Check for terminal case of constant node. */ if (cuddIsConstant(node)) { - return(node); + return(node); } /* If problem already solved, look up answer and return. */ if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { #ifdef DD_DEBUG - addPermuteRecurHits++; + addPermuteRecurHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ @@ -1056,8 +1084,8 @@ cuddAddPermuteRecur( cuddRef(T); E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); if (E == NULL) { - Cudd_RecursiveDeref(manager, T); - return(NULL); + Cudd_RecursiveDeref(manager, T); + return(NULL); } cuddRef(E); @@ -1071,10 +1099,10 @@ cuddAddPermuteRecur( cuddRef(var); res = cuddAddIteRecur(manager,var,T,E); if (res == NULL) { - Cudd_RecursiveDeref(manager,var); - Cudd_RecursiveDeref(manager, T); - Cudd_RecursiveDeref(manager, E); - return(NULL); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,var); @@ -1085,12 +1113,12 @@ cuddAddPermuteRecur( ** it will not be visited again. */ if (node->ref != 1) { - ptrint fanout = (ptrint) node->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,node,res,fanout)) { - Cudd_RecursiveDeref(manager, res); - return(NULL); - } + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1125,24 +1153,24 @@ cuddBddPermuteRecur( DdNode * node /* BDD to be reordered */, int * permut /* permutation array */) { - DdNode *N,*T,*E; - DdNode *res; - int index; + DdNode *N,*T,*E; + DdNode *res; + int index; statLine(manager); N = Cudd_Regular(node); /* Check for terminal case of constant node. */ if (cuddIsConstant(N)) { - return(node); + return(node); } /* If problem already solved, look up answer and return. */ if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { #ifdef DD_DEBUG - bddPermuteRecurHits++; + bddPermuteRecurHits++; #endif - return(Cudd_NotCond(res,N != node)); + return(Cudd_NotCond(res,N != node)); } /* Split and recur on children of this node. */ @@ -1151,8 +1179,8 @@ cuddBddPermuteRecur( cuddRef(T); E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); if (E == NULL) { - Cudd_IterDerefBdd(manager, T); - return(NULL); + Cudd_IterDerefBdd(manager, T); + return(NULL); } cuddRef(E); @@ -1163,9 +1191,9 @@ cuddBddPermuteRecur( index = permut[N->index]; res = cuddBddIteRecur(manager,manager->vars[index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(manager, T); - Cudd_IterDerefBdd(manager, E); - return(NULL); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(manager, T); @@ -1175,12 +1203,12 @@ cuddBddPermuteRecur( ** it will not be visited again. */ if (N->ref != 1) { - ptrint fanout = (ptrint) N->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,N,res,fanout)) { - Cudd_IterDerefBdd(manager, res); - return(NULL); - } + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } } cuddDeref(res); return(Cudd_NotCond(res,N != node)); @@ -1205,22 +1233,22 @@ cuddBddVarMapRecur( DdManager *manager /* DD manager */, DdNode *f /* BDD to be remapped */) { - DdNode *F, *T, *E; - DdNode *res; - int index; + DdNode *F, *T, *E; + DdNode *res; + int index; statLine(manager); F = Cudd_Regular(f); /* Check for terminal case of constant node. */ if (cuddIsConstant(F)) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ if (F->ref != 1 && - (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { - return(Cudd_NotCond(res,F != f)); + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); } /* Split and recur on children of this node. */ @@ -1229,8 +1257,8 @@ cuddBddVarMapRecur( cuddRef(T); E = cuddBddVarMapRecur(manager,cuddE(F)); if (E == NULL) { - Cudd_IterDerefBdd(manager, T); - return(NULL); + Cudd_IterDerefBdd(manager, T); + return(NULL); } cuddRef(E); @@ -1241,9 +1269,9 @@ cuddBddVarMapRecur( index = manager->map[F->index]; res = cuddBddIteRecur(manager,manager->vars[index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(manager, T); - Cudd_IterDerefBdd(manager, E); - return(NULL); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(manager, T); @@ -1253,7 +1281,7 @@ cuddBddVarMapRecur( ** it will not be visited again. */ if (F->ref != 1) { - cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); } cuddDeref(res); return(Cudd_NotCond(res,F != f)); @@ -1280,20 +1308,20 @@ cuddAddVectorComposeRecur( DdNode ** vector /* functions to substitute */, int deepest /* depth of deepest substitution */) { - DdNode *T,*E; - DdNode *res; + DdNode *T,*E; + DdNode *res; statLine(dd); /* If we are past the deepest substitution, return f. */ if (cuddI(dd,f->index) > deepest) { - return(f); + return(f); } if ((res = cuddHashTableLookup1(table,f)) != NULL) { #ifdef DD_DEBUG - addVectorComposeHits++; + addVectorComposeHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ @@ -1302,8 +1330,8 @@ cuddAddVectorComposeRecur( cuddRef(T); E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); @@ -1312,9 +1340,9 @@ cuddAddVectorComposeRecur( */ res = cuddAddIteRecur(dd,vector[f->index],T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, T); @@ -1324,12 +1352,12 @@ cuddAddVectorComposeRecur( ** it will not be visited again */ if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1357,31 +1385,31 @@ cuddAddGeneralVectorComposeRecur( DdNode ** vectorOff /* functions to substitute for x_i' */, int deepest /* depth of deepest substitution */) { - DdNode *T,*E,*t,*e; - DdNode *res; + DdNode *T,*E,*t,*e; + DdNode *res; /* If we are past the deepest substitution, return f. */ if (cuddI(dd,f->index) > deepest) { - return(f); + return(f); } if ((res = cuddHashTableLookup1(table,f)) != NULL) { #ifdef DD_DEBUG - addGeneralVectorComposeHits++; + addGeneralVectorComposeHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), - vectorOn,vectorOff,deepest); + vectorOn,vectorOff,deepest); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), - vectorOn,vectorOff,deepest); + vectorOn,vectorOff,deepest); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); @@ -1421,12 +1449,12 @@ cuddAddGeneralVectorComposeRecur( ** it will not be visited again */ if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1466,13 +1494,13 @@ cuddAddNonSimComposeRecur( statLine(dd); /* If we are past the deepest substitution, return f. */ if (cube == DD_ONE(dd) || cuddIsConstant(f)) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); if (r != NULL) { - return(r); + return(r); } /* Find top variable. we just need to look at f, key, and cube, @@ -1487,69 +1515,69 @@ cuddAddNonSimComposeRecur( /* Compute the cofactors. */ if (topf == top) { - f1 = cuddT(f); - f0 = cuddE(f); + f1 = cuddT(f); + f0 = cuddE(f); } else { - f1 = f0 = f; + f1 = f0 = f; } if (topc == top) { - cube1 = cuddT(cube); - /* We want to eliminate vector[index] from key. Otherwise - ** cache performance is severely affected. Hence we - ** existentially quantify the variable with index "index" from key. - */ - var = Cudd_addIthVar(dd, (int) index); - if (var == NULL) { - return(NULL); - } - cuddRef(var); - key1 = cuddAddExistAbstractRecur(dd, key, var); - if (key1 == NULL) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(key1); - Cudd_RecursiveDeref(dd,var); - key0 = key1; + key0 = key1; } else { - cube1 = cube; - if (topk == top) { - key1 = cuddT(key); - key0 = cuddE(key); - } else { - key1 = key0 = key; - } - cuddRef(key1); + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); } /* Allocate two new vectors for the cofactors of vector. */ vect1 = ABC_ALLOC(DdNode *,lastsub); if (vect1 == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd,key1); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); } vect0 = ABC_ALLOC(DdNode *,lastsub); if (vect0 == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd,key1); - ABC_FREE(vect1); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + ABC_FREE(vect1); + return(NULL); } /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because ** we do not need them. */ for (i = 0; i < lastsub; i++) { - DdNode *gi = vector[i]; - if (gi == NULL) { - vect1[i] = vect0[i] = NULL; - } else if (gi->index == index) { - vect1[i] = cuddT(gi); - vect0[i] = cuddE(gi); - } else { - vect1[i] = vect0[i] = gi; - } + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } } vect1[index] = vect0[index] = NULL; @@ -1557,17 +1585,17 @@ cuddAddNonSimComposeRecur( T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); ABC_FREE(vect1); if (T == NULL) { - Cudd_RecursiveDeref(dd,key1); - ABC_FREE(vect0); - return(NULL); + Cudd_RecursiveDeref(dd,key1); + ABC_FREE(vect0); + return(NULL); } cuddRef(T); E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); ABC_FREE(vect0); if (E == NULL) { - Cudd_RecursiveDeref(dd,key1); - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); Cudd_RecursiveDeref(dd,key1); @@ -1577,9 +1605,9 @@ cuddAddNonSimComposeRecur( */ r = cuddAddIteRecur(dd,vector[index],T,E); if (r == NULL) { - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddRef(r); Cudd_RecursiveDeref(dd,T); @@ -1613,23 +1641,23 @@ cuddBddVectorComposeRecur( DdNode ** vector /* functions to be composed */, int deepest /* depth of the deepest substitution */) { - DdNode *F,*T,*E; - DdNode *res; + DdNode *F,*T,*E; + DdNode *res; statLine(dd); F = Cudd_Regular(f); /* If we are past the deepest substitution, return f. */ if (cuddI(dd,F->index) > deepest) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ if ((res = cuddHashTableLookup1(table,F)) != NULL) { #ifdef DD_DEBUG - bddVectorComposeHits++; + bddVectorComposeHits++; #endif - return(Cudd_NotCond(res,F != f)); + return(Cudd_NotCond(res,F != f)); } /* Split and recur on children of this node. */ @@ -1638,8 +1666,8 @@ cuddBddVectorComposeRecur( cuddRef(T); E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); if (E == NULL) { - Cudd_IterDerefBdd(dd, T); - return(NULL); + Cudd_IterDerefBdd(dd, T); + return(NULL); } cuddRef(E); @@ -1648,24 +1676,24 @@ cuddBddVectorComposeRecur( */ res = cuddBddIteRecur(dd,vector[F->index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); - return(NULL); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); + Cudd_IterDerefBdd(dd, E); /* Do not keep the result if the reference count is only 1, since ** it will not be visited again. */ if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,F,res,fanout)) { - Cudd_IterDerefBdd(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } } cuddDeref(res); return(Cudd_NotCond(res,F != f)); @@ -1719,9 +1747,11 @@ ddIsIthAddVarPair( unsigned int i) { return(f->index == i && g->index == i && - cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && - cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); } /* end of ddIsIthAddVarPair */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddDecomp.c b/src/bdd/cudd/cuddDecomp.c index 95a00536..34eaef0c 100644 --- a/src/bdd/cudd/cuddDecomp.c +++ b/src/bdd/cudd/cuddDecomp.c @@ -7,30 +7,57 @@ Synopsis [Functions for BDD decomposition.] Description [External procedures included in this file: - <ul> - <li> Cudd_bddApproxConjDecomp() - <li> Cudd_bddApproxDisjDecomp() - <li> Cudd_bddIterConjDecomp() - <li> Cudd_bddIterDisjDecomp() - <li> Cudd_bddGenConjDecomp() - <li> Cudd_bddGenDisjDecomp() - <li> Cudd_bddVarConjDecomp() - <li> Cudd_bddVarDisjDecomp() - </ul> - Static procedures included in this module: - <ul> - <li> cuddConjunctsAux() - <li> CreateBotDist() - <li> BuildConjuncts() - <li> ConjunctsFree() - </ul>] + <ul> + <li> Cudd_bddApproxConjDecomp() + <li> Cudd_bddApproxDisjDecomp() + <li> Cudd_bddIterConjDecomp() + <li> Cudd_bddIterDisjDecomp() + <li> Cudd_bddGenConjDecomp() + <li> Cudd_bddGenDisjDecomp() + <li> Cudd_bddVarConjDecomp() + <li> Cudd_bddVarDisjDecomp() + </ul> + Static procedures included in this module: + <ul> + <li> cuddConjunctsAux() + <li> CreateBotDist() + <li> BuildConjuncts() + <li> ConjunctsFree() + </ul>] Author [Kavita Ravi, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -78,10 +106,10 @@ typedef struct NodeStat { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.44 2004/08/13 18:04:47 fabio Exp $"; #endif -static DdNode *one, *zero; +static DdNode *one, *zero; long lastTimeG; /*---------------------------------------------------------------------------*/ @@ -101,16 +129,16 @@ long lastTimeG; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static NodeStat * CreateBotDist ARGS((DdNode * node, st_table * distanceTable)); -static double CountMinterms ARGS((DdNode * node, double max, st_table * mintermTable, FILE *fp)); -static void ConjunctsFree ARGS((DdManager * dd, Conjuncts * factors)); -static int PairInTables ARGS((DdNode * g, DdNode * h, st_table * ghTable)); -static Conjuncts * CheckTablesCacheAndReturn ARGS((DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable)); -static Conjuncts * PickOnePair ARGS((DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable)); -static Conjuncts * CheckInTables ARGS((DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem)); -static Conjuncts * ZeroCase ARGS((DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched)); -static Conjuncts * BuildConjuncts ARGS((DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable)); -static int cuddConjunctsAux ARGS((DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2)); +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); /**AutomaticEnd***************************************************************/ @@ -158,8 +186,8 @@ Cudd_bddApproxConjDecomp( cuddRef(superset1); superset2 = Cudd_bddSqueeze(dd,f,superset1); if (superset2 == NULL) { - Cudd_RecursiveDeref(dd,superset1); - return(0); + Cudd_RecursiveDeref(dd,superset1); + return(0); } cuddRef(superset2); Cudd_RecursiveDeref(dd,superset1); @@ -167,8 +195,8 @@ Cudd_bddApproxConjDecomp( /* Compute the second factor by minimization. */ hlocal = Cudd_bddLICompaction(dd,f,superset2); if (hlocal == NULL) { - Cudd_RecursiveDeref(dd,superset2); - return(0); + Cudd_RecursiveDeref(dd,superset2); + return(0); } cuddRef(hlocal); @@ -176,47 +204,47 @@ Cudd_bddApproxConjDecomp( ** step guarantees that g will be 1. */ glocal = Cudd_bddLICompaction(dd,superset2,hlocal); if (glocal == NULL) { - Cudd_RecursiveDeref(dd,superset2); - Cudd_RecursiveDeref(dd,hlocal); - return(0); + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); } cuddRef(glocal); Cudd_RecursiveDeref(dd,superset2); if (glocal != DD_ONE(dd)) { - if (hlocal != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddApproxConjDecomp */ @@ -251,7 +279,7 @@ Cudd_bddApproxDisjDecomp( result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -298,59 +326,59 @@ Cudd_bddIterConjDecomp( sizeOld = Cudd_SharingSize(old,2); do { - /* Find a tentative first factor by overapproximation and - ** minimization. */ - superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); - if (superset1 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(superset1); - superset2 = Cudd_bddSqueeze(dd,old[1],superset1); - if (superset2 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); Cudd_RecursiveDeref(dd,superset1); - return(0); - } - cuddRef(superset2); - Cudd_RecursiveDeref(dd,superset1); - res[0] = Cudd_bddAnd(dd,old[0],superset2); - if (res[0] == NULL) { + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); Cudd_RecursiveDeref(dd,superset2); - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(res[0]); - Cudd_RecursiveDeref(dd,superset2); - if (res[0] == old[0]) { - Cudd_RecursiveDeref(dd,res[0]); - break; /* avoid infinite loop */ - } - - /* Compute the second factor by minimization. */ - res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); - if (res[1] == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(res[1]); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } - sizeNew = Cudd_SharingSize(res,2); - if (sizeNew <= sizeOld) { - Cudd_RecursiveDeref(dd,old[0]); - old[0] = res[0]; - Cudd_RecursiveDeref(dd,old[1]); - old[1] = res[1]; - sizeOld = sizeNew; - } else { - Cudd_RecursiveDeref(dd,res[0]); - Cudd_RecursiveDeref(dd,res[1]); - break; - } + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } } while (1); @@ -358,48 +386,48 @@ Cudd_bddIterConjDecomp( ** be f, this step guarantees that g will be 1. */ superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); if (superset1 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); } cuddRef(superset1); Cudd_RecursiveDeref(dd,old[0]); old[0] = superset1; if (old[0] != DD_ONE(dd)) { - if (old[1] != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (old[1] != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); } - (*conjuncts)[0] = old[0]; - (*conjuncts)[1] = old[1]; - return(2); } else { - Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,old[0]); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = old[0]; + (*conjuncts)[0] = old[1]; return(1); } - } else { - Cudd_RecursiveDeref(dd,old[0]); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[1]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = old[1]; - return(1); - } } /* end of Cudd_bddIterConjDecomp */ @@ -434,7 +462,7 @@ Cudd_bddIterDisjDecomp( result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -477,48 +505,48 @@ Cudd_bddGenConjDecomp( zero = Cudd_Not(one); do { - dd->reordered = 0; - result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); } while (dd->reordered == 1); if (result == 0) { - return(0); + return(0); } if (glocal != one) { - if (hlocal != one) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != one) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddGenConjDecomp */ @@ -553,7 +581,7 @@ Cudd_bddGenDisjDecomp( result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -597,30 +625,30 @@ Cudd_bddVarConjDecomp( support = Cudd_Support(dd,f); if (support == NULL) return(0); if (Cudd_IsConstant(support)) { - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = f; - cuddRef((*conjuncts)[0]); - return(1); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); } cuddRef(support); min = 1000000000; best = -1; scan = support; while (!Cudd_IsConstant(scan)) { - int i = scan->index; - int est1 = Cudd_EstimateCofactor(dd,f,i,1); - int est0 = Cudd_EstimateCofactor(dd,f,i,0); - /* Minimize the size of the larger of the two cofactors. */ - int est = (est1 > est0) ? est1 : est0; - if (est < min) { - min = est; - best = i; - } - scan = cuddT(scan); + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); } #ifdef DD_DEBUG assert(best >= 0 && best < dd->size); @@ -630,50 +658,50 @@ Cudd_bddVarConjDecomp( var = Cudd_bddIthVar(dd,best); glocal = Cudd_bddOr(dd,f,var); if (glocal == NULL) { - return(0); + return(0); } cuddRef(glocal); hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); if (hlocal == NULL) { - Cudd_RecursiveDeref(dd,glocal); - return(0); + Cudd_RecursiveDeref(dd,glocal); + return(0); } cuddRef(hlocal); if (glocal != DD_ONE(dd)) { - if (hlocal != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddVarConjDecomp */ @@ -711,7 +739,7 @@ Cudd_bddVarDisjDecomp( result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -751,15 +779,15 @@ CreateBotDist( #if 0 if (Cudd_IsConstant(node)) { - return(0); + return(0); } #endif /* Return the entry in the table if found. */ N = Cudd_Regular(node); - if (st_lookup(distanceTable, (char *)N, (char **)&nodeStat)) { - nodeStat->localRef++; - return(nodeStat); + if (st_lookup(distanceTable, (const char *)N, (char **)&nodeStat)) { + nodeStat->localRef++; + return(nodeStat); } Nv = cuddT(N); @@ -782,14 +810,14 @@ CreateBotDist( nodeStat = ABC_ALLOC(NodeStat, 1); if (nodeStat == NULL) { - return(0); + return(0); } nodeStat->distance = distance; nodeStat->localRef = 1; if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == - ST_OUT_OF_MEM) { - return(0); + ST_OUT_OF_MEM) { + return(0); } return(nodeStat); @@ -823,17 +851,17 @@ CountMinterms( N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == zero) { - return(0); - } else { - return(max); - } + if (node == zero) { + return(0); + } else { + return(max); + } } /* Return the entry in the table if found. */ - if (st_lookup(mintermTable, (char *)node, (char **)&dummy)) { - min = *dummy; - return(min); + if (st_lookup(mintermTable, (const char *)node, (char **)&dummy)) { + min = *dummy; + return(min); } Nv = cuddT(N); @@ -854,7 +882,7 @@ CountMinterms( if (dummy == NULL) return(-1.0); *dummy = min; if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { - (void) fprintf(fp, "st table insert failed\n"); + (void) fprintf(fp, "st table insert failed\n"); } return(min); @@ -928,21 +956,21 @@ PairInTables( if (!gPresent && !hPresent) return(NONE); if (!hPresent) { - if (valueG & 1) return(G_ST); - if (valueG & 2) return(G_CR); + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); } if (!gPresent) { - if (valueH & 1) return(H_CR); - if (valueH & 2) return(H_ST); + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); } /* both in tables */ if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); if (valueG & 1) { - return(BOTH_G); + return(BOTH_G); } else { - return(BOTH_H); + return(BOTH_H); } } /* end of PairInTables */ @@ -984,74 +1012,74 @@ CheckTablesCacheAndReturn( factors = ABC_ALLOC(Conjuncts, 1); if (factors == NULL) return(NULL); if ((pairValue == BOTH_H) || (pairValue == H_ST)) { - if (g != one) { - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { - value |= 1; - } else { - value = 1; - } - if (st_insert(ghTable, (char *)Cudd_Regular(g), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { - if (h != one) { - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { - value |= 2; - } else { - value = 2; - } - if (st_insert(ghTable, (char *)Cudd_Regular(h), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } else if (pairValue == H_CR) { - if (g != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == G_CR) { - if (h != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == PAIR_CR) { /* pair exists in table */ - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == PAIR_ST) { - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } - + /* cache the result for this node */ if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + ABC_FREE(factors); + return(NULL); } return(factors); } /* end of CheckTablesCacheAndReturn */ - + /**Function******************************************************************** Synopsis [Check the tables for the existence of pair and return one @@ -1086,29 +1114,29 @@ PickOnePair( /* count the number of pointers to pair 2 */ if (h2 == one) { - twoRef = (Cudd_Regular(g2))->ref; + twoRef = (Cudd_Regular(g2))->ref; } else if (g2 == one) { - twoRef = (Cudd_Regular(h2))->ref; + twoRef = (Cudd_Regular(h2))->ref; } else { - twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; } /* count the number of pointers to pair 1 */ if (h1 == one) { - oneRef = (Cudd_Regular(g1))->ref; + oneRef = (Cudd_Regular(g1))->ref; } else if (g1 == one) { - oneRef = (Cudd_Regular(h1))->ref; + oneRef = (Cudd_Regular(h1))->ref; } else { - oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; } /* pick the pair with higher reference count */ if (oneRef >= twoRef) { - factors->g = g1; - factors->h = h1; + factors->g = g1; + factors->h = h1; } else { - factors->g = g2; - factors->h = h2; + factors->g = g2; + factors->h = h2; } /* @@ -1116,54 +1144,54 @@ PickOnePair( * recombination. */ if (factors->g != one) { - /* insert g in htable */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { - if (value == 2) { - value |= 1; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); - } - } - } else { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } } } - } if (factors->h != one) { - /* insert h in htable */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { - if (value == 1) { - value |= 2; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); - } - } - } else { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } } } - } /* Store factors in cache table for later use. */ if (st_insert(cacheTable, (char *)node, (char *)factors) == - ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); } return(factors); @@ -1208,192 +1236,192 @@ CheckInTables( /* if none of the 4 exist in the gh tables, return NULL */ if ((pairValue1 == NONE) && (pairValue2 == NONE)) { - return NULL; + return NULL; } factors = ABC_ALLOC(Conjuncts, 1); if (factors == NULL) { - *outOfMem = 1; - return NULL; + *outOfMem = 1; + return NULL; } /* pairs that already exist in the table get preference. */ if (pairValue1 == PAIR_ST) { - factors->g = g1; - factors->h = h1; + factors->g = g1; + factors->h = h1; } else if (pairValue2 == PAIR_ST) { - factors->g = g2; - factors->h = h2; + factors->g = g2; + factors->h = h2; } else if (pairValue1 == PAIR_CR) { - factors->g = h1; - factors->h = g1; + factors->g = h1; + factors->h = g1; } else if (pairValue2 == PAIR_CR) { - factors->g = h2; - factors->h = g2; + factors->g = h2; + factors->h = g2; } else if (pairValue1 == G_ST) { - /* g exists in the table, h is not found in either table */ - factors->g = g1; - factors->h = h1; - if (h1 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == BOTH_G) { - /* g and h are found in the g table */ - factors->g = g1; - factors->h = h1; - if (h1 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == H_ST) { - /* h exists in the table, g is not found in either table */ - factors->g = g1; - factors->h = h1; - if (g1 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == BOTH_H) { - /* g and h are found in the h table */ - factors->g = g1; - factors->h = h1; - if (g1 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == G_ST) { - /* g exists in the table, h is not found in either table */ - factors->g = g2; - factors->h = h2; - if (h2 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == BOTH_G) { - /* g and h are found in the g table */ - factors->g = g2; - factors->h = h2; - if (h2 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == H_ST) { - /* h exists in the table, g is not found in either table */ - factors->g = g2; - factors->h = h2; - if (g2 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == BOTH_H) { - /* g and h are found in the h table */ - factors->g = g2; - factors->h = h2; - if (g2 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == G_CR) { - /* g found in h table and h in none */ - factors->g = h1; - factors->h = g1; - if (h1 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == H_CR) { - /* h found in g table and g in none */ - factors->g = h1; - factors->h = g1; - if (g1 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == G_CR) { - /* g found in h table and h in none */ - factors->g = h2; - factors->h = g2; - if (h2 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == H_CR) { - /* h found in g table and g in none */ - factors->g = h2; - factors->h = g2; - if (g2 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } } - } /* Store factors in cache table for later use. */ if (st_insert(cacheTable, (char *)node, (char *)factors) == - ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); } return factors; } /* end of CheckInTables */ @@ -1440,69 +1468,69 @@ ZeroCase( /* Seprate variable and child */ if (factorsNv->g == one) { - Cudd_RecursiveDeref(dd, factorsNv->g); - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - return(NULL); - } - factors->g = x; - factors->h = factorsNv->h; - /* cache the result*/ - if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - ABC_FREE(factors); - return NULL; - } - - /* store x in g table, the other node is already in the table */ - if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { - value |= 1; - } else { - value = 1; - } - if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - return NULL; - } - return(factors); + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + ABC_FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); } /* Seprate variable and child */ if (factorsNv->h == one) { - Cudd_RecursiveDeref(dd, factorsNv->h); - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - return(NULL); - } - factors->g = factorsNv->g; - factors->h = x; - /* cache the result. */ - if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - ABC_FREE(factors); - return(NULL); - } - /* store x in h table, the other node is already in the table */ - if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { - value |= 2; - } else { - value = 2; - } - if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - return NULL; - } - return(factors); + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + ABC_FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); } G = Cudd_Regular(factorsNv->g); @@ -1512,29 +1540,29 @@ ZeroCase( Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); /* if the child below is a variable */ if ((Gv == zero) || (Gnv == zero)) { - h = factorsNv->h; - g = cuddBddAndRecur(dd, x, factorsNv->g); - if (g != NULL) cuddRef(g); - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - if (g == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - return NULL; - } - /* CheckTablesCacheAndReturn responsible for allocating - * factors structure., g,h referenced for cache store the - */ - factors = CheckTablesCacheAndReturn(node, - g, - h, - ghTable, - cacheTable); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g); - Cudd_RecursiveDeref(dd, h); - } - return(factors); + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); } H = Cudd_Regular(factorsNv->h); @@ -1544,29 +1572,29 @@ ZeroCase( Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); /* if the child below is a variable */ if ((Hv == zero) || (Hnv == zero)) { - g = factorsNv->g; - h = cuddBddAndRecur(dd, x, factorsNv->h); - if (h!= NULL) cuddRef(h); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - if (h == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - return NULL; - } - /* CheckTablesCacheAndReturn responsible for allocating - * factors structure.g,h referenced for table store - */ - factors = CheckTablesCacheAndReturn(node, - g, - h, - ghTable, - cacheTable); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g); - Cudd_RecursiveDeref(dd, h); - } - return(factors); + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); } /* build g1 = x*g; h1 = h */ @@ -1576,60 +1604,60 @@ ZeroCase( g1 = cuddBddAndRecur(dd, x, factorsNv->g); if (g1 != NULL) cuddRef(g1); if (g1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - return NULL; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; } g2 = factorsNv->g; h2 = cuddBddAndRecur(dd, x, factorsNv->h); if (h2 != NULL) cuddRef(h2); if (h2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNv->g); - return NULL; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; } /* check whether any pair is in tables */ factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); if (outOfMem) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - return NULL; - } - if (factors != NULL) { - if ((factors->g == g1) || (factors->g == h1)) { - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { + dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd, g1); Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; } - return factors; + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; } /* check for each pair in tables and choose one */ factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { - /* now free what was created and not used */ - if ((factors->g == g1) || (factors->g == h1)) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); Cudd_RecursiveDeref(dd, g2); Cudd_RecursiveDeref(dd, h2); } else { - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - } + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } } - + return(factors); } /* end of ZeroCase */ @@ -1665,8 +1693,7 @@ BuildConjuncts( st_table * mintermTable) { int topid, distance; - Conjuncts *factorsNv = NULL, *factorsNnv = NULL; // Suppress "might be used uninitialized" - Conjuncts *factors; + Conjuncts *factorsNv, *factorsNnv, *factors; Conjuncts *dummy; DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; double minNv = 0.0, minNnv = 0.0; @@ -1679,82 +1706,82 @@ BuildConjuncts( /* if f is constant, return (f,f) */ if (Cudd_IsConstant(node)) { - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - factors->g = node; - factors->h = node; - return(FactorsComplement(factors)); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); } /* If result (a pair of conjuncts) in cache, return the factors. */ - if (st_lookup(cacheTable, (char *)node, (char **)&dummy)) { - factors = dummy; - return(factors); + if (st_lookup(cacheTable, (const char *)node, (char **)&dummy)) { + factors = dummy; + return(factors); } /* check distance and local reference count of this node */ N = Cudd_Regular(node); - if (!st_lookup(distanceTable, (char *)N, (char **)&nodeStat)) { - (void) fprintf(dd->err, "Not in table, Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(distanceTable, (const char *)N, (char **)&nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } distance = nodeStat->distance; /* at or below decomposition point, return (f, 1) */ if (((nodeStat->localRef > maxLocalRef*2/3) && - (distance < approxDistance*2/3)) || - (distance <= approxDistance/4)) { - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - /* alternate assigning (f,1) */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { - if (value == 3) { - if (!lastTimeG) { + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { factors->g = node; factors->h = one; lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(factors); + return NULL; + } } else { factors->g = one; factors->h = node; - lastTimeG = 0; - } - } else if (value == 1) { - factors->g = node; - factors->h = one; - } else { - factors->g = one; - factors->h = node; - } - } else if (!lastTimeG) { - factors->g = node; - factors->h = one; - lastTimeG = 1; - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(factors); - return NULL; - } - } else { - factors->g = one; - factors->h = node; - lastTimeG = 0; - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(factors); - return NULL; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(factors); + return NULL; + } } - } - return(FactorsComplement(factors)); + return(FactorsComplement(factors)); } /* get the children and recur */ @@ -1767,87 +1794,87 @@ BuildConjuncts( * minterms. We go first where there are more minterms. */ if (!Cudd_IsConstant(Nv)) { - if (!st_lookup(mintermTable, (char *)Nv, (char **)&doubleDummy)) { - (void) fprintf(dd->err, "Not in table: Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - minNv = *doubleDummy; + if (!st_lookup(mintermTable, (const char *)Nv, (char **)&doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; } if (!Cudd_IsConstant(Nnv)) { - if (!st_lookup(mintermTable, (char *)Nnv, (char **)&doubleDummy)) { - (void) fprintf(dd->err, "Not in table: Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - minNnv = *doubleDummy; + if (!st_lookup(mintermTable, (const char *)Nnv, (char **)&doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; } if (minNv < minNnv) { - temp = Nv; - Nv = Nnv; - Nnv = temp; - switched = 1; + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; } /* build gt, ht recursively */ if (Nv != zero) { - factorsNv = BuildConjuncts(dd, Nv, distanceTable, - cacheTable, approxDistance, maxLocalRef, - ghTable, mintermTable); - if (factorsNv == NULL) return(NULL); - freeNv = FactorsNotStored(factorsNv); - factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; - cuddRef(factorsNv->g); - cuddRef(factorsNv->h); - - /* Deal with the zero case */ - if (Nnv == zero) { - /* is responsible for freeing factorsNv */ - factors = ZeroCase(dd, node, factorsNv, ghTable, - cacheTable, switched); - if (freeNv) ABC_FREE(factorsNv); - return(factors); - } + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) ABC_FREE(factorsNv); + return(factors); + } } /* build ge, he recursively */ if (Nnv != zero) { - factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, - cacheTable, approxDistance, maxLocalRef, - ghTable, mintermTable); - if (factorsNnv == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - if (freeNv) ABC_FREE(factorsNv); - return(NULL); - } - freeNnv = FactorsNotStored(factorsNnv); - factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; - cuddRef(factorsNnv->g); - cuddRef(factorsNnv->h); - - /* Deal with the zero case */ - if (Nv == zero) { - /* is responsible for freeing factorsNv */ - factors = ZeroCase(dd, node, factorsNnv, ghTable, - cacheTable, switched); - if (freeNnv) ABC_FREE(factorsNnv); - return(factors); - } + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) ABC_FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) ABC_FREE(factorsNnv); + return(factors); + } } /* construct the 2 pairs */ /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ if (switched) { - factors = factorsNnv; - factorsNnv = factorsNv; - factorsNv = factors; - freeTemp = freeNv; - freeNv = freeNnv; - freeNnv = freeTemp; + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; } /* Build the factors for this node. */ @@ -1856,42 +1883,42 @@ BuildConjuncts( g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); if (g1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(g1); h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); if (h1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(h1); g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); if (g2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(g2); Cudd_RecursiveDeref(dd, factorsNv->g); @@ -1899,16 +1926,16 @@ BuildConjuncts( h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); if (h2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(h2); Cudd_RecursiveDeref(dd, factorsNv->h); @@ -1919,43 +1946,43 @@ BuildConjuncts( /* check for each pair in tables and choose one */ factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); if (outOfMem) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - return(NULL); - } - if (factors != NULL) { - if ((factors->g == g1) || (factors->g == h1)) { - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { + dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd, g1); Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); } - return(factors); + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); } /* if not in tables, pick one pair */ factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { - /* now free what was created and not used */ - if ((factors->g == g1) || (factors->g == h1)) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); Cudd_RecursiveDeref(dd, g2); Cudd_RecursiveDeref(dd, h2); } else { - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - } + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } } - + return(factors); } /* end of BuildConjuncts */ @@ -1999,7 +2026,7 @@ cuddConjunctsAux( *c2 = NULL; /* initialize distances table */ - distanceTable = st_init_table(st_ptrcmp, st_ptrhash);; + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); if (distanceTable == NULL) goto outOfMem; /* make the entry for the constant */ @@ -2008,7 +2035,7 @@ cuddConjunctsAux( nodeStat->distance = 0; nodeStat->localRef = 1; if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { - goto outOfMem; + goto outOfMem; } /* Count node distances from constant. */ @@ -2020,18 +2047,18 @@ cuddConjunctsAux( distance = nodeStat->distance; if (distance < approxDistance) { - /* Too small to bother. */ - *c1 = f; - *c2 = DD_ONE(dd); - cuddRef(*c1); cuddRef(*c2); - stGen = st_init_gen(distanceTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(distanceTable); - return(1); + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); } /* record the maximum local reference count */ @@ -2039,16 +2066,16 @@ cuddConjunctsAux( stGen = st_init_gen(distanceTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - nodeStat = (NodeStat *)value; - maxLocalRef = (nodeStat->localRef > maxLocalRef) ? - nodeStat->localRef : maxLocalRef; + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; } st_free_gen(stGen); stGen = NULL; - + /* Count minterms for each node. */ max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ - mintermTable = st_init_table(st_ptrcmp, st_ptrhash);; + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); if (mintermTable == NULL) goto outOfMem; minterms = CountMinterms(f, max, mintermTable, dd->err); if (minterms == -1.0) goto outOfMem; @@ -2061,14 +2088,14 @@ cuddConjunctsAux( /* Build conjuncts. */ factors = BuildConjuncts(dd, f, distanceTable, cacheTable, - approxDistance, maxLocalRef, ghTable, mintermTable); + approxDistance, maxLocalRef, ghTable, mintermTable); if (factors == NULL) goto outOfMem; - /* Free up tables */ + /* free up tables */ stGen = st_init_gen(distanceTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); + ABC_FREE(value); } st_free_gen(stGen); stGen = NULL; st_free_table(distanceTable); distanceTable = NULL; @@ -2077,7 +2104,7 @@ cuddConjunctsAux( stGen = st_init_gen(mintermTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); + ABC_FREE(value); } st_free_gen(stGen); stGen = NULL; st_free_table(mintermTable); mintermTable = NULL; @@ -2085,33 +2112,33 @@ cuddConjunctsAux( freeFactors = FactorsNotStored(factors); factors = (freeFactors) ? FactorsUncomplement(factors) : factors; if (factors != NULL) { - *c1 = factors->g; - *c2 = factors->h; - cuddRef(*c1); - cuddRef(*c2); - if (freeFactors) ABC_FREE(factors); - + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) ABC_FREE(factors); + #if 0 - if ((*c1 == f) && (!Cudd_IsConstant(f))) { - assert(*c2 == one); - } - if ((*c2 == f) && (!Cudd_IsConstant(f))) { - assert(*c1 == one); - } - - if ((*c1 != one) && (!Cudd_IsConstant(f))) { - assert(!Cudd_bddLeq(dd, *c2, *c1)); - } - if ((*c2 != one) && (!Cudd_IsConstant(f))) { - assert(!Cudd_bddLeq(dd, *c1, *c2)); - } + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } #endif } stGen = st_init_gen(cacheTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ConjunctsFree(dd, (Conjuncts *)value); + ConjunctsFree(dd, (Conjuncts *)value); } st_free_gen(stGen); stGen = NULL; @@ -2121,36 +2148,38 @@ cuddConjunctsAux( outOfMem: if (distanceTable != NULL) { - stGen = st_init_gen(distanceTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(distanceTable); distanceTable = NULL; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; } if (mintermTable != NULL) { - stGen = st_init_gen(mintermTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(mintermTable); mintermTable = NULL; + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; } if (ghTable != NULL) st_free_table(ghTable); if (cacheTable != NULL) { - stGen = st_init_gen(cacheTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ConjunctsFree(dd, (Conjuncts *)value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(cacheTable); cacheTable = NULL; + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; } dd->errorCode = CUDD_MEMORY_OUT; return(0); } /* end of cuddConjunctsAux */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddEssent.c b/src/bdd/cudd/cuddEssent.c index 2d82019c..b3264715 100644 --- a/src/bdd/cudd/cuddEssent.c +++ b/src/bdd/cudd/cuddEssent.c @@ -7,21 +7,67 @@ Synopsis [Functions for the detection of essential variables.] Description [External procedures included in this file: - <ul> - <li> Cudd_FindEssential() - <li> Cudd_bddIsVarEssential() - </ul> - Static procedures included in this module: - <ul> - <li> ddFindEssentialRecur() - </ul>] + <ul> + <li> Cudd_FindEssential() + <li> Cudd_bddIsVarEssential() + <li> Cudd_FindTwoLiteralClauses() + <li> Cudd_ReadIthClause() + <li> Cudd_PrintTwoLiteralClauses() + <li> Cudd_tlcInfoFree() + </ul> + Static procedures included in this module: + <ul> + <li> ddFindEssentialRecur() + <li> ddFindTwoLiteralClausesRecur() + <li> computeClauses() + <li> computeClausesWithUniverse() + <li> emptyClauseSet() + <li> sentinelp() + <li> equalp() + <li> beforep() + <li> oneliteralp() + <li> impliedp() + <li> bitVectorAlloc() + <li> bitVectorClear() + <li> bitVectorFree() + <li> bitVectorRead() + <li> bitVectorSet() + <li> tlcInfoAlloc() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -31,26 +77,84 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ +typedef long BitVector; +typedef struct TlClause TlClause; + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.24 2009/02/21 18:24:10 fabio Exp $"; #endif +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ @@ -61,7 +165,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * ddFindEssentialRecur ARGS((DdManager *dd, DdNode *f)); +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); /**AutomaticEnd***************************************************************/ @@ -94,8 +213,8 @@ Cudd_FindEssential( DdNode *res; do { - dd->reordered = 0; - res = ddFindEssentialRecur(dd,f); + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -123,24 +242,226 @@ Cudd_bddIsVarEssential( int id, int phase) { - DdNode *var; - int res; - DdNode *one, *zero; - - one = DD_ONE(manager); - zero = Cudd_Not(one); + DdNode *var; + int res; - var = cuddUniqueInter(manager, id, one, zero); + var = Cudd_bddIthVar(manager, id); var = Cudd_NotCond(var,phase == 0); - res = Cudd_bddIteConstant(manager, Cudd_Not(f), one, var) == one; + res = Cudd_bddLeq(manager, f, var); return(res); } /* end of Cudd_bddIsVarEssential */ +/**Function******************************************************************** + + Synopsis [Finds the two literal clauses of a DD.] + + Description [Returns the one- and two-literal clauses of a DD. + Returns a pointer to the structure holding the clauses if + successful; NULL otherwise. For a constant DD, the empty set of clauses + is returned. This is obviously correct for a non-zero constant. For the + constant zero, it is based on the assumption that only those clauses + containing variables in the support of the function are considered. Since + the support of a constant function is empty, no clauses are returned.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, (const char **)&node, (char **)&tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Accesses the i-th clause of a DD.] + + Description [Accesses the i-th clause of a DD given the clause set which + must be already computed. Returns 1 if successful; 0 if i is out of range, + or in case of error.] + + SideEffects [the four components of a clause are returned as side effects.] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**Function******************************************************************** + + Synopsis [Prints the two literal clauses of a DD.] + + Description [Prints the one- and two-literal clauses. Returns 1 if + successful; 0 otherwise. The argument "names" can be NULL, in which case + the variable indices are printed.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) ABC_FREE(t->vars); + if (t->phases != NULL) ABC_FREE(t->phases); + ABC_FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ @@ -166,10 +487,10 @@ ddFindEssentialRecur( DdManager * dd, DdNode * f) { - DdNode *T, *E, *F; - DdNode *essT, *essE, *res; - int index; - DdNode *one, *lzero, *azero; + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; one = DD_ONE(dd); F = Cudd_Regular(f); @@ -178,7 +499,7 @@ ddFindEssentialRecur( res = cuddCacheLookup1(dd,Cudd_FindEssential,f); if (res != NULL) { - return(res); + return(res); } lzero = Cudd_Not(one); @@ -187,98 +508,968 @@ ddFindEssentialRecur( T = cuddT(F); E = cuddE(F); if (Cudd_IsComplement(f)) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } index = F->index; if (Cudd_IsConstant(T) && T != lzero && T != azero) { - /* if E is zero, index is essential, otherwise there are no - ** essentials, because index is not essential and no other variable - ** can be, since setting index = 1 makes the function constant and - ** different from 0. - */ - if (E == lzero || E == azero) { - res = dd->vars[index]; - } else { - res = one; - } + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } } else if (T == lzero || T == azero) { - if (Cudd_IsConstant(E)) { /* E cannot be zero here */ - res = Cudd_Not(dd->vars[index]); - } else { /* E == non-constant */ - /* find essentials in the else branch */ - essE = ddFindEssentialRecur(dd,E); - if (essE == NULL) { - return(NULL); + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); } - cuddRef(essE); - - /* add index to the set with negative phase */ - res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essE); - return(NULL); + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; } - res = Cudd_Not(res); - cuddDeref(essE); } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, (const char *)f, (char **)&res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ABC_ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + ABC_FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + ABC_FREE(res->vars); + ABC_FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ABC_ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + ABC_FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + ABC_FREE(res->vars); + ABC_FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } } else { /* T == non-const */ - if (E == lzero || E == azero) { - /* find essentials in the then branch */ - essT = ddFindEssentialRecur(dd,T); - if (essT == NULL) { - return(NULL); + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); } - cuddRef(essT); + } - /* add index to the set with positive phase */ - /* use And because essT may be complemented */ - res = cuddBddAndRecur(dd,dd->vars[index],essT); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essT); - return(NULL); - } - cuddDeref(essT); - } else if (!Cudd_IsConstant(E)) { - /* if E is a non-zero constant there are no essentials - ** because T is non-constant. - */ - essT = ddFindEssentialRecur(dd,T); - if (essT == NULL) { + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + ABC_FREE(res); return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; } - if (essT == one) { - res = one; + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + ABC_FREE(tclauses); + tclauses = nextclause; } else { - cuddRef(essT); - essE = ddFindEssentialRecur(dd,E); - if (essE == NULL) { - Cudd_RecursiveDeref(dd,essT); - return(NULL); + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + ABC_FREE(eclauses); + eclauses = nextclause; } - cuddRef(essE); - - /* res = intersection(essT, essE) */ - res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essT); - Cudd_RecursiveDeref(dd,essE); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,essT); - Cudd_RecursiveDeref(dd,essE); - cuddDeref(res); + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + ABC_FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + ABC_FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ABC_ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + ABC_FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + ABC_FREE(nclauses); + nclauses = nextclause; } - } else { /* E is a non-zero constant */ - res = one; } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + ABC_FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + ABC_FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + ABC_FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + ABC_FREE(eclauses); + eclauses = nextclause; } - cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ABC_ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + return(res); -} /* end of ddFindEssentialRecur */ + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) ABC_FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ABC_ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ABC_ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + ABC_FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ABC_ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + ABC_FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ABC_ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddExact.c b/src/bdd/cudd/cuddExact.c index b9ed4676..19fcbcd4 100644 --- a/src/bdd/cudd/cuddExact.c +++ b/src/bdd/cudd/cuddExact.c @@ -7,36 +7,63 @@ Synopsis [Functions for exact variable reordering.] Description [External procedures included in this file: - <ul> - </ul> - Internal procedures included in this module: - <ul> - <li> cuddExact() - </ul> - Static procedures included in this module: - <ul> + <ul> + </ul> + Internal procedures included in this module: + <ul> + <li> cuddExact() + </ul> + Static procedures included in this module: + <ul> <li> getMaxBinomial() - <li> gcd() + <li> gcd() <li> getMatrix() - <li> freeMatrix() + <li> freeMatrix() <li> getLevelKeys() <li> ddShuffle() <li> ddSiftUp() - <li> updateUB() - <li> ddCountRoots() - <li> ddClearGlobal() - <li> computeLB() - <li> updateEntry() - <li> pushDown() - <li> initSymmInfo() + <li> updateUB() + <li> ddCountRoots() + <li> ddClearGlobal() + <li> computeLB() + <li> updateEntry() + <li> pushDown() + <li> initSymmInfo() </ul>] Author [Cheng Hua, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -46,6 +73,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $"; #endif #ifdef DD_STATS @@ -81,21 +109,20 @@ static int ddTotalShuffles; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int getMaxBinomial ARGS((int n)); -static int gcd ARGS((int x, int y)); -static DdHalfWord ** getMatrix ARGS((int rows, int cols)); -static void freeMatrix ARGS((DdHalfWord **matrix)); -static int getLevelKeys ARGS((DdManager *table, int l)); -static int ddShuffle ARGS((DdManager *table, DdHalfWord *permutation, int lower, int upper)); -static int ddSiftUp ARGS((DdManager *table, int x, int xLow)); -static int updateUB ARGS((DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)); -static int ddCountRoots ARGS((DdManager *table, int lower, int upper)); -static void ddClearGlobal ARGS((DdManager *table, int lower, int maxlevel)); -static int computeLB ARGS((DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)); -static int updateEntry ARGS((DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)); -static void pushDown ARGS((DdHalfWord *order, int j, int level)); -static DdHalfWord * initSymmInfo ARGS((DdManager *table, int lower, int upper)); -static int checkSymmInfo ARGS((DdManager *table, DdHalfWord *symmInfo, int index, int level)); +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); /**AutomaticEnd***************************************************************/ @@ -131,7 +158,7 @@ cuddExact( int k, i, j; int maxBinomial, oldSubsets, newSubsets; int subsetCost; - int size; /* number of variables to be reordered */ + int size; /* number of variables to be reordered */ int unused, nvars, level, result; int upperBound, lowerBound, cost; int roots; @@ -152,13 +179,13 @@ cuddExact( /* Restrict the range to be reordered by excluding unused variables ** at the two ends. */ while (table->subtables[lower].keys == 1 && - table->vars[table->invperm[lower]]->ref == 1 && - lower < upper) - lower++; + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; while (table->subtables[upper].keys == 1 && - table->vars[table->invperm[upper]]->ref == 1 && - lower < upper) - upper--; + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; if (lower == upper) return(1); /* trivial problem */ /* Apply symmetric sifting to get a good upper bound and to extract @@ -179,9 +206,9 @@ cuddExact( ** used to compute maxBinomial. */ unused = 0; for (i = lower + 1; i < upper; i++) { - if (table->subtables[i].keys == 1 && - table->vars[table->invperm[i]]->ref == 1) - unused++; + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; } /* Find the maximum number of subsets we may have to store. */ @@ -218,65 +245,65 @@ cuddExact( */ oldSubsets = 1; for (i = 0; i < size; i++) { - oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; } subsetCost = table->constants.keys; for (i = upper + 1; i < nvars; i++) - subsetCost += getLevelKeys(table,i); + subsetCost += getLevelKeys(table,i); oldCost[0] = subsetCost; /* The upper bound is initialized to the current size of the BDDs. */ upperBound = table->keys - table->isolated; /* Now consider subsets of increasing size. */ for (k = 1; k <= size; k++) { -#if DD_STATS - (void) fprintf(table->out,"Processing subsets of size %d\n", k); - fflush(table->out); +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); #endif - newSubsets = 0; - level = size - k; /* offset of first bottom variable */ - - for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ - order = oldOrder[i]; - cost = oldCost[i]; - lowerBound = computeLB(table, order, roots, cost, lower, upper, - level); - if (lowerBound >= upperBound) - continue; - /* Impose new order. */ - result = ddShuffle(table, order, lower, upper); - if (result == 0) goto cuddExactOutOfMem; - upperBound = updateUB(table,upperBound,bestOrder,lower,upper); - /* For each top bottom variable. */ - for (j = level; j >= 0; j--) { - /* Skip unused variables. */ - if (table->subtables[j+lower-1].keys == 1 && - table->vars[table->invperm[j+lower-1]]->ref == 1) continue; - /* Find cost under this order. */ - subsetCost = cost + getLevelKeys(table, lower + level); - newSubsets = updateEntry(table, order, level, subsetCost, - newOrder, newCost, newSubsets, mask, - lower, upper); - if (j == 0) - break; - if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) - continue; - pushDown(order,j-1,level); - /* Impose new order. */ - result = ddShuffle(table, order, lower, upper); - if (result == 0) goto cuddExactOutOfMem; - upperBound = updateUB(table,upperBound,bestOrder,lower,upper); - } /* for each bottom variable */ - } /* for each subset of size k */ - - /* New orders become old orders in preparation for next iteration. */ - tmpOrder = oldOrder; tmpCost = oldCost; - oldOrder = newOrder; oldCost = newCost; - newOrder = tmpOrder; newCost = tmpCost; + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; #ifdef DD_STATS - ddTotalSubsets += newSubsets; + ddTotalSubsets += newSubsets; #endif - oldSubsets = newSubsets; + oldSubsets = newSubsets; } result = ddShuffle(table, bestOrder, lower, upper); if (result == 0) goto cuddExactOutOfMem; @@ -285,9 +312,9 @@ cuddExact( (void) fprintf(table->out,"\n"); #endif (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", - ddTotalSubsets); + ddTotalSubsets); (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", - ddTotalShuffles); + ddTotalShuffles); #endif freeMatrix(newOrder); @@ -320,9 +347,12 @@ cuddExactOutOfMem: Description [Computes the maximum value of (n choose k) for a given n. The maximum value occurs for k = n/2 when n is even, or k = - (n-1)/2 when n is odd. The algorithm used in this procedure is - quite inefficient, but it avoids intermediate overflow problems. - Returns the computed value if successful; -1 otherwise.] + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity + <pre> + binomial(n,k) = n/k * binomial(n-1,k-1). + </pre> + Returns the computed value if successful; -1 if out of range.] SideEffects [None] @@ -331,42 +361,24 @@ cuddExactOutOfMem: ******************************************************************************/ static int getMaxBinomial( - int n) + int n) { - int *numerator; - int i, j, k, y, g, result; - - k = (n & ~1) >> 1; - - numerator = ABC_ALLOC(int,k); - if (numerator == NULL) return(-1); - - for (i = 0; i < k; i++) - numerator[i] = n - i; - - for (i = k; i > 1; i--) { - y = i; - for (j = 0; j < k; j++) { - if (numerator[j] == 1) continue; - g = gcd(numerator[j], y); - if (g != 1) { - numerator[j] /= g; - if (y == g) break; - y /= g; - } - } - } + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); - result = 1; - for (i = 0; i < k; i++) - result *= numerator[i]; + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } - ABC_FREE(numerator); - return(result); + return((int)result); -} /* end of getMaxBinomial */ +} /* end of getMaxBinomial */ +#if 0 /**Function******************************************************************** Synopsis [Returns the gcd of two integers.] @@ -393,33 +405,34 @@ gcd( if (y == 0) return(x); a = x; b = y; lsbMask = 1; - + /* Here both a and b are != 0. The iteration maintains this invariant. ** Hence, we only need to check for when they become equal. */ while (a != b) { - if (a & lsbMask) { - if (b & lsbMask) { /* both odd */ - if (a < b) { - b = (b - a) >> 1; + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } } else { - a = (a - b) >> 1; - } - } else { /* a odd, b even */ - b >>= 1; - } - } else { - if (b & lsbMask) { /* a even, b odd */ - a >>= 1; - } else { /* both even */ - lsbMask <<= 1; + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } } } - } return(a); } /* end of gcd */ +#endif /**Function******************************************************************** @@ -446,9 +459,12 @@ getMatrix( matrix = ABC_ALLOC(DdHalfWord *, rows); if (matrix == NULL) return(NULL); matrix[0] = ABC_ALLOC(DdHalfWord, cols*rows); - if (matrix[0] == NULL) return(NULL); + if (matrix[0] == NULL) { + ABC_FREE(matrix); + return(NULL); + } for (i = 1; i < rows; i++) { - matrix[i] = matrix[i-1] + cols; + matrix[i] = matrix[i-1] + cols; } return(matrix); @@ -528,18 +544,20 @@ ddShuffle( int lower, int upper) { - DdHalfWord index; - int level; - int position; - int numvars; - int result; + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; #ifdef DD_STATS - long localTime; - int initialSize; + long localTime; + int initialSize; #ifdef DD_VERBOSE - int finalSize; + int finalSize; #endif - int previousSize; + int previousSize; #endif #ifdef DD_STATS @@ -547,24 +565,24 @@ ddShuffle( initialSize = table->keys - table->isolated; #endif +#if 0 numvars = table->size; -#if 0 (void) fprintf(table->out,"%d:", ddTotalShuffles); for (level = 0; level < numvars; level++) { - (void) fprintf(table->out," %d", table->invperm[level]); + (void) fprintf(table->out," %d", table->invperm[level]); } (void) fprintf(table->out,"\n"); #endif for (level = 0; level <= upper - lower; level++) { - index = permutation[level]; - position = table->perm[index]; + index = permutation[level]; + position = table->perm[index]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftUp(table,position,level+lower); - if (!result) return(0); + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); } #ifdef DD_STATS @@ -572,11 +590,11 @@ ddShuffle( #ifdef DD_VERBOSE finalSize = table->keys - table->isolated; if (finalSize < initialSize) { - (void) fprintf(table->out,"-"); + (void) fprintf(table->out,"-"); } else if (finalSize > initialSize) { - (void) fprintf(table->out,"+"); + (void) fprintf(table->out,"+"); } else { - (void) fprintf(table->out,"="); + (void) fprintf(table->out,"="); } if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); fflush(table->out); @@ -612,12 +630,12 @@ ddSiftUp( y = cuddNextLow(table,x); while (y >= xLow) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -649,14 +667,14 @@ updateUB( if (newBound < oldBound) { #ifdef DD_STATS - (void) fprintf(table->out,"New upper bound = %d\n", newBound); - fflush(table->out); + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); #endif - for (i = lower; i <= upper; i++) - bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; - return(newBound); + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); } else { - return(oldBound); + return(oldBound); } } /* end of updateUB */ @@ -693,36 +711,36 @@ ddCountRoots( int maxlevel = lower; for (i = lower; i <= upper; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - /* A node is a root of the DAG if it cannot be - ** reached by nodes above it. If a node was never - ** reached during the previous depth-first searches, - ** then it is a root, and we start a new depth-first - ** search from it. - */ - if (!Cudd_IsComplement(f->next)) { - if (f != table->vars[f->index]) { - roots++; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); } } - if (!Cudd_IsConstant(cuddT(f))) { - cuddT(f)->next = Cudd_Complement(cuddT(f)->next); - if (table->perm[cuddT(f)->index] > maxlevel) - maxlevel = table->perm[cuddT(f)->index]; - } - if (!Cudd_IsConstant(cuddE(f))) { - Cudd_Regular(cuddE(f))->next = - Cudd_Complement(Cudd_Regular(cuddE(f))->next); - if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) - maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; - } - f = Cudd_Regular(f->next); - } - } } ddClearGlobal(table, lower, maxlevel); @@ -758,16 +776,16 @@ ddClearGlobal( int slots; for (i = lower; i <= maxlevel; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - f->next = Cudd_Regular(f->next); - f = f->next; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } } } - } } /* end of ddClearGlobal */ @@ -793,13 +811,13 @@ ddClearGlobal( ******************************************************************************/ static int computeLB( - DdManager * table /* manager */, - DdHalfWord * order /* optimal order for the subset */, - int roots /* roots between lower and upper */, - int cost /* minimum cost for the subset */, - int lower /* lower level to be reordered */, - int upper /* upper level to be reordered */, - int level /* offset for the current top bottom var */ + DdManager * table /* manager */, + DdHalfWord * order /* optimal order for the subset */, + int roots /* roots between lower and upper */, + int cost /* minimum cost for the subset */, + int lower /* lower level to be reordered */, + int upper /* upper level to be reordered */, + int level /* offset for the current top bottom var */ ) { int i; @@ -813,28 +831,28 @@ computeLB( ** Add their sizes to the lower bound. */ for (i = 0; i < lower; i++) { - lb += getLevelKeys(table,i); + lb += getLevelKeys(table,i); } /* If a variable is in the support, then there is going ** to be at least one node labeled by that variable. */ for (i = lower; i <= lower+level; i++) { - support = table->subtables[i].keys > 1 || - table->vars[order[i-lower]]->ref > 1; - lb1 += support; + support = table->subtables[i].keys > 1 || + table->vars[order[i-lower]]->ref > 1; + lb1 += support; } /* Estimate the number of nodes required to connect the roots to ** the nodes in the bottom part. */ if (lower+level+1 < table->size) { - if (lower+level < upper) - ref = table->vars[order[level+1]]->ref; - else - ref = table->vars[table->invperm[upper+1]]->ref; - lb2 = table->subtables[lower+level+1].keys - - (ref > (DdHalfWord) 1) - roots; + if (lower+level < upper) + ref = table->vars[order[level+1]]->ref; + else + ref = table->vars[table->invperm[upper+1]]->ref; + lb2 = table->subtables[lower+level+1].keys - + (ref > (DdHalfWord) 1) - roots; } else { - lb2 = 0; + lb2 = 0; } lb += lb1 > lb2 ? lb1 : lb2; @@ -876,25 +894,25 @@ updateEntry( /* Build a mask that says what variables are in this subset. */ for (i = lower; i <= upper; i++) - mask[table->invperm[i]] = 0; + mask[table->invperm[i]] = 0; for (i = level; i < size; i++) - mask[order[i]] = 1; + mask[order[i]] = 1; /* Check each subset until a match is found or all subsets are examined. */ for (i = 0; i < subsets; i++) { - DdHalfWord *subset = orders[i]; - for (j = level; j < size; j++) { - if (mask[subset[j]] == 0) - break; - } - if (j == size) /* no mismatches: success */ - break; + DdHalfWord *subset = orders[i]; + for (j = level; j < size; j++) { + if (mask[subset[j]] == 0) + break; + } + if (j == size) /* no mismatches: success */ + break; } - if (i == subsets || cost < costs[i]) { /* add or replace */ - for (j = 0; j < size; j++) - orders[i][j] = order[j]; - costs[i] = cost; - subsets += (i == subsets); + if (i == subsets || cost < costs[i]) { /* add or replace */ + for (j = 0; j < size; j++) + orders[i][j] = order[j]; + costs[i] = cost; + subsets += (i == subsets); } return(subsets); @@ -923,7 +941,7 @@ pushDown( tmp = order[j]; for (i = j; i < level; i++) { - order[i] = order[i+1]; + order[i] = order[i+1]; } order[level] = tmp; return; @@ -963,10 +981,10 @@ initSymmInfo( if (symmInfo == NULL) return(NULL); for (level = lower; level <= upper; level++) { - index = table->invperm[level]; - next = table->subtables[level].next; - nextindex = table->invperm[next]; - symmInfo[index] = nextindex; + index = table->invperm[level]; + next = table->subtables[level].next; + nextindex = table->invperm[next]; + symmInfo[index] = nextindex; } return(symmInfo); @@ -997,13 +1015,14 @@ checkSymmInfo( i = symmInfo[index]; while (i != index) { - if (index < i && table->perm[i] <= level) - return(0); - i = symmInfo[i]; + if (index < i && table->perm[i] <= level) + return(0); + i = symmInfo[i]; } return(1); } /* end of checkSymmInfo */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddExport.c b/src/bdd/cudd/cuddExport.c index cccf2465..3b2e989d 100644 --- a/src/bdd/cudd/cuddExport.c +++ b/src/bdd/cudd/cuddExport.c @@ -7,31 +7,58 @@ Synopsis [Export functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_DumpBlif() - <li> Cudd_DumpBlifBody() - <li> Cudd_DumpDot() - <li> Cudd_DumpDaVinci() - <li> Cudd_DumpDDcal() - <li> Cudd_DumpFactoredForm() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> ddDoDumpBlif() - <li> ddDoDumpDaVinci() - <li> ddDoDumpDDcal() - <li> ddDoDumpFactoredForm() - </ul>] + <ul> + <li> Cudd_DumpBlif() + <li> Cudd_DumpBlifBody() + <li> Cudd_DumpDot() + <li> Cudd_DumpDaVinci() + <li> Cudd_DumpDDcal() + <li> Cudd_DumpFactoredForm() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> ddDoDumpBlif() + <li> ddDoDumpDaVinci() + <li> ddDoDumpDDcal() + <li> ddDoDumpFactoredForm() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -41,6 +68,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,7 +86,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.22 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -71,10 +99,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddDoDumpBlif ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names)); -static int ddDoDumpDaVinci ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)); -static int ddDoDumpDDcal ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)); -static int ddDoDumpFactoredForm ARGS((DdManager *dd, DdNode *f, FILE *fp, char **names)); +static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, int mv); +static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names); /**AutomaticEnd***************************************************************/ @@ -112,20 +140,21 @@ Cudd_DumpBlif( char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, char * mname /* model name (or NULL) */, - FILE * fp /* pointer to the dump file */) + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; - int retval; - int i; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + int retval; + int i; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -135,28 +164,31 @@ Cudd_DumpBlif( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ /* Write the header (.model .inputs .outputs). */ if (mname == NULL) { - retval = fprintf(fp,".model DD\n.inputs"); + retval = fprintf(fp,".model DD\n.inputs"); } else { - retval = fprintf(fp,".model %s\n.inputs",mname); + retval = fprintf(fp,".model %s\n.inputs",mname); + } + if (retval == EOF) { + ABC_FREE(sorted); + return(0); } - if (retval == EOF) return(0); /* Write the input list by scanning the support array. */ for (i = 0; i < nvars; i++) { if (sorted[i]) { - if (inames == NULL) { - retval = fprintf(fp," %d", i); - } else { - retval = fprintf(fp," %s", inames[i]); - } + if (inames == NULL) { + retval = fprintf(fp," %d", i); + } else { + retval = fprintf(fp," %s", inames[i]); + } if (retval == EOF) goto failure; } } @@ -167,17 +199,17 @@ Cudd_DumpBlif( retval = fprintf(fp,"\n.outputs"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp," f%d", i); - } else { - retval = fprintf(fp," %s", onames[i]); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp," f%d", i); + } else { + retval = fprintf(fp," %s", onames[i]); + } + if (retval == EOF) goto failure; } retval = fprintf(fp,"\n"); if (retval == EOF) goto failure; - retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp); + retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); if (retval == 0) goto failure; /* Write trailer and return. */ @@ -199,11 +231,12 @@ failure: Synopsis [Writes a blif body representing the argument BDDs.] Description [Writes a blif body representing the argument BDDs as a - network of multiplexers. One multiplexer is written for each BDD - node. It returns 1 in case of success; 0 otherwise (e.g., + network of multiplexers. No header (.model, .inputs, and .outputs) and + footer (.end) are produced by this function. One multiplexer is written + for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different - from 0 and 1). Cudd_DumpBlif does not close the file: This is the - caller responsibility. Cudd_DumpBlif uses a minimal unique subset of + from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the + caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. This function prints out only @@ -211,7 +244,7 @@ failure: SideEffects [None] - SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm] ******************************************************************************/ @@ -222,11 +255,12 @@ Cudd_DumpBlifBody( DdNode ** f /* array of output nodes to be dumped */, char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, - FILE * fp /* pointer to the dump file */) + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) { st_table *visited = NULL; - int retval; - int i; + int retval; + int i; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -234,8 +268,8 @@ Cudd_DumpBlifBody( /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames); - if (retval == 0) goto failure; + retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); + if (retval == 0) goto failure; } /* To account for the possible complement on the root, @@ -243,28 +277,28 @@ Cudd_DumpBlifBody( ** the multiplexer representing the top node. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, + if (onames == NULL) { + retval = fprintf(fp, #if SIZEOF_VOID_P == 8 - ".names %lx f%d\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i); + ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #else - ".names %x f%d\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), i); + ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #endif - } else { - retval = fprintf(fp, + } else { + retval = fprintf(fp, #if SIZEOF_VOID_P == 8 - ".names %lx %s\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), onames[i]); + ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); #else - ".names %x %s\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), onames[i]); + ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); #endif - } - if (retval == EOF) goto failure; - if (Cudd_IsComplement(f[i])) { - retval = fprintf(fp,"0 1\n"); - } else { - retval = fprintf(fp,"1 1\n"); - } - if (retval == EOF) goto failure; + } + if (retval == EOF) goto failure; + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); + } else { + retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); + } + if (retval == EOF) goto failure; } st_free_table(visited); @@ -315,23 +349,23 @@ Cudd_DumpDot( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; st_table *visited = NULL; st_generator *gen = NULL; - int retval; - int i, j; - int slots; - DdNodePtr *nodelist; - long refAddr, diff, mask; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -341,8 +375,8 @@ Cudd_DumpDot( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ @@ -353,8 +387,8 @@ Cudd_DumpDot( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -373,22 +407,22 @@ Cudd_DumpDot( diff = 0; gen = st_init_gen(visited); if (gen == NULL) goto failure; - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (long) scan; } st_free_gen(gen); gen = NULL; /* Choose the mask. */ for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + mask = (1 << i) - 1; + if (diff <= mask) break; } /* Write the header and the global attributes. */ retval = fprintf(fp,"digraph \"DD\" {\n"); if (retval == EOF) return(0); retval = fprintf(fp, - "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); if (retval == EOF) return(0); /* Write the input name subgraph by scanning the support array. */ @@ -403,11 +437,11 @@ Cudd_DumpDot( if (retval == EOF) goto failure; for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); - } else { - retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); - } + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; } } @@ -418,63 +452,63 @@ Cudd_DumpDot( retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - if (i == n - 1) { - retval = fprintf(fp,"; }\n"); - } else { - retval = fprintf(fp," -> "); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; } /* Write rank info: All nodes with the same index have the same rank. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - retval = fprintf(fp,"{ rank = same; "); - if (retval == EOF) goto failure; - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); - } else { - retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); - } + retval = fprintf(fp,"{ rank = same; "); if (retval == EOF) goto failure; - nodelist = dd->subtables[i].nodelist; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%lx\";\n", ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; - } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; } - retval = fprintf(fp,"}\n"); - if (retval == EOF) goto failure; - } } /* All constants have the same rank. */ retval = fprintf(fp, - "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); if (retval == EOF) goto failure; nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%lx\";\n", ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } retval = fprintf(fp,"}\n}\n"); if (retval == EOF) goto failure; @@ -482,69 +516,64 @@ Cudd_DumpDot( /* Write edge info. */ /* Edges from the output nodes. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - /* Account for the possible complement on the root. */ - if (Cudd_IsComplement(f[i])) { - retval = fprintf(fp," -> \"%lx\" [style = dotted];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - } else { - retval = fprintf(fp," -> \"%lx\" [style = solid];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + /* Account for the possible complement on the root. */ + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp," -> \"%lx\" [style = dotted];\n", ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } else { + retval = fprintf(fp," -> \"%lx\" [style = solid];\n", ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; } /* Edges from internal nodes. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - nodelist = dd->subtables[i].nodelist; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\";\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddT(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; - if (Cudd_IsComplement(cuddE(scan))) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dotted];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - } else { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dashed];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - } - if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, "\"%lx\" -> \"%lx\";\n", + ((mask & (ptrint) scan) / sizeof(DdNode)), + ((mask & (ptrint) cuddT(scan)) / sizeof(DdNode))); + if (retval == EOF) goto failure; + if (Cudd_IsComplement(cuddE(scan))) { + retval = fprintf(fp,"\"%lx\" -> \"%lx\" [style = dotted];\n", + ((mask & (ptrint) scan) / sizeof(DdNode)), + ((mask & (ptrint) cuddE(scan)) / sizeof(DdNode))); + } else { + retval = fprintf(fp, "\"%lx\" -> \"%lx\" [style = dashed];\n", + ((mask & (ptrint) scan) / sizeof(DdNode)), + ((mask & (ptrint) cuddE(scan)) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; } - } - } } /* Write constant labels. */ nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", - (mask & (long) scan) / sizeof(DdNode), cuddV(scan)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", + ((mask & (ptrint) scan) / sizeof(DdNode)), cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } /* Write trailer and return. */ @@ -591,13 +620,13 @@ Cudd_DumpDaVinci( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - st_table *visited = NULL; - int retval; - int i; - st_generator *gen; - long refAddr, diff, mask; + DdNode *support = NULL; + DdNode *scan; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -605,8 +634,8 @@ Cudd_DumpDaVinci( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -621,18 +650,18 @@ Cudd_DumpDaVinci( */ /* Find the bits that are different. */ - refAddr = (long) Cudd_Regular(f[0]); + refAddr = (ptruint) Cudd_Regular(f[0]); diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; } st_free_gen(gen); /* Choose the mask. */ - for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; } st_free_table(visited); @@ -644,23 +673,23 @@ Cudd_DumpDaVinci( if (retval == EOF) goto failure; /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, - "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", - i,i); - } else { - retval = fprintf(fp, - "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", - onames[i], onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", - Cudd_IsComplement(f[i]) ? "red" : "blue"); - if (retval == EOF) goto failure; - retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); - if (retval == 0) goto failure; - retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp, + "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", + i,i); + } else { + retval = fprintf(fp, + "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", + onames[i], onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(f[i]) ? "red" : "blue"); + if (retval == EOF) goto failure; + retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); + if (retval == EOF) goto failure; } /* Write trailer and return. */ @@ -705,15 +734,15 @@ Cudd_DumpDDcal( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; - st_table *visited = NULL; - int retval; - int i; - st_generator *gen; - long refAddr, diff, mask; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -721,8 +750,8 @@ Cudd_DumpDDcal( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -737,26 +766,26 @@ Cudd_DumpDDcal( */ /* Find the bits that are different. */ - refAddr = (long) Cudd_Regular(f[0]); + refAddr = (ptruint) Cudd_Regular(f[0]); diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; } st_free_gen(gen); /* Choose the mask. */ - for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; } st_free_table(visited); /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -766,22 +795,22 @@ Cudd_DumpDDcal( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"v%d", dd->invperm[i]); - } else { - retval = fprintf(fp,"%s", inames[dd->invperm[i]]); - } + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"v%d", dd->invperm[i]); + } else { + retval = fprintf(fp,"%s", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; } - retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); - if (retval == EOF) goto failure; + retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); + if (retval == EOF) goto failure; } ABC_FREE(sorted); sorted = NULL; @@ -792,31 +821,32 @@ Cudd_DumpDDcal( /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); - if (retval == 0) goto failure; - if (onames == NULL) { - retval = fprintf(fp, "f%d = ", i); - } else { - retval = fprintf(fp, "%s = ", onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp, "n%lx%s\n", - ((long) f[i] & mask) / sizeof(DdNode), - Cudd_IsComplement(f[i]) ? "'" : ""); - if (retval == EOF) goto failure; + retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "n%p%s\n", + (void *) (((ptruint) f[i] & mask) / + (ptruint) sizeof(DdNode)), + Cudd_IsComplement(f[i]) ? "'" : ""); + if (retval == EOF) goto failure; } /* Write trailer and return. */ retval = fprintf(fp, "["); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, "f%d", i); - } else { - retval = fprintf(fp, "%s", onames[i]); - } - retval = fprintf(fp, "%s", i == n-1 ? "" : " "); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d", i); + } else { + retval = fprintf(fp, "%s", onames[i]); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : " "); + if (retval == EOF) goto failure; } retval = fprintf(fp, "]\n"); if (retval == EOF) goto failure; @@ -862,34 +892,34 @@ Cudd_DumpFactoredForm( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - int retval; - int i; + int retval; + int i; /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, "f%d = ", i); - } else { - retval = fprintf(fp, "%s = ", onames[i]); - } - if (retval == EOF) return(0); - if (f[i] == DD_ONE(dd)) { - retval = fprintf(fp, "CONST1"); - if (retval == EOF) return(0); - } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { - retval = fprintf(fp, "CONST0"); - if (retval == EOF) return(0); - } else { - retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); - if (retval == 0) return(0); - retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (f[i] == DD_ONE(dd)) { + retval = fprintf(fp, "CONST1"); + if (retval == EOF) return(0); + } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { + retval = fprintf(fp, "CONST0"); + if (retval == EOF) return(0); + } else { + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); + if (retval == 0) return(0); + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (retval == EOF) return(0); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); if (retval == EOF) return(0); } - retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); - if (retval == EOF) return(0); - } return(1); @@ -926,10 +956,11 @@ ddDoDumpBlif( DdNode * f, FILE * fp, st_table * visited, - char ** names) + char ** names, + int mv) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -950,9 +981,9 @@ ddDoDumpBlif( /* Check for special case: If constant node, generate constant 1. */ if (f == DD_ONE(dd)) { #if SIZEOF_VOID_P == 8 - retval = fprintf(fp, ".names %lx\n1\n",(unsigned long) f / (unsigned long) sizeof(DdNode)); + retval = fprintf(fp, ".names %lx\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); #else - retval = fprintf(fp, ".names %x\n1\n",(unsigned) f / (unsigned) sizeof(DdNode)); + retval = fprintf(fp, ".names %x\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); #endif if (retval == EOF) { return(0); @@ -966,9 +997,13 @@ ddDoDumpBlif( */ if (f == DD_ZERO(dd)) { #if SIZEOF_VOID_P == 8 - retval = fprintf(fp, ".names %lx\n",(unsigned long) f / (unsigned long) sizeof(DdNode)); + retval = fprintf(fp, ".names %lx\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); #else - retval = fprintf(fp, ".names %x\n",(unsigned) f / (unsigned) sizeof(DdNode)); + retval = fprintf(fp, ".names %x\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); #endif if (retval == EOF) { return(0); @@ -977,48 +1012,80 @@ ddDoDumpBlif( } } if (cuddIsConstant(f)) - return(0); + return(0); /* Recursive calls. */ T = cuddT(f); - retval = ddDoDumpBlif(dd,T,fp,visited,names); + retval = ddDoDumpBlif(dd,T,fp,visited,names,mv); if (retval != 1) return(retval); E = Cudd_Regular(cuddE(f)); - retval = ddDoDumpBlif(dd,E,fp,visited,names); + retval = ddDoDumpBlif(dd,E,fp,visited,names,mv); if (retval != 1) return(retval); /* Write multiplexer taking complement arc into account. */ if (names != NULL) { - retval = fprintf(fp,".names %s", names[f->index]); + retval = fprintf(fp,".names %s", names[f->index]); } else { - retval = fprintf(fp,".names %d", f->index); +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp,".names %u", f->index); +#else + retval = fprintf(fp,".names %hu", f->index); +#endif } if (retval == EOF) - return(0); + return(0); #if SIZEOF_VOID_P == 8 - if (Cudd_IsComplement(cuddE(f))) { - retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", - (unsigned long) T / (unsigned long) sizeof(DdNode), - (unsigned long) E / (unsigned long) sizeof(DdNode), - (unsigned long) f / (unsigned long) sizeof(DdNode)); + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } else { - retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", - (unsigned long) T / (unsigned long) sizeof(DdNode), - (unsigned long) E / (unsigned long) sizeof(DdNode), - (unsigned long) f / (unsigned long) sizeof(DdNode)); + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } #else - if (Cudd_IsComplement(cuddE(f))) { - retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", - (unsigned) T / (unsigned) sizeof(DdNode), - (unsigned) E / (unsigned) sizeof(DdNode), - (unsigned) f / (unsigned) sizeof(DdNode)); + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } else { - retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", - (unsigned) T / (unsigned) sizeof(DdNode), - (unsigned) E / (unsigned) sizeof(DdNode), - (unsigned) f / (unsigned) sizeof(DdNode)); + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } #endif if (retval == EOF) { @@ -1051,21 +1118,21 @@ ddDoDumpDaVinci( FILE * fp, st_table * visited, char ** names, - long mask) + ptruint mask) { - DdNode *T, *E; - int retval; - long id; + DdNode *T, *E; + int retval; + ptruint id; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); #endif - id = ((long) f & mask) / sizeof(DdNode); + id = ((ptruint) f & mask) / sizeof(DdNode); /* If already visited, insert a reference. */ if (st_is_member(visited, (char *) f) == 1) { - retval = fprintf(fp,"r(\"%lx\")", id); + retval = fprintf(fp,"r(\"%p\")", (void *) id); if (retval == EOF) { return(0); } else { @@ -1083,7 +1150,9 @@ ddDoDumpDaVinci( /* Check for special case: If constant node, generate constant 1. */ if (Cudd_IsConstant(f)) { - retval = fprintf(fp, "l(\"%lx\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", id, cuddV(f)); + retval = fprintf(fp, + "l(\"%p\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", + (void *) id, cuddV(f)); if (retval == EOF) { return(0); } else { @@ -1093,13 +1162,17 @@ ddDoDumpDaVinci( /* Recursive calls. */ if (names != NULL) { - retval = fprintf(fp, - "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", - id, names[f->index]); + retval = fprintf(fp, + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", + (void *) id, names[f->index]); } else { - retval = fprintf(fp, - "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%d\"),", - id, f->index); + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%u\"),", +#else + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%hu\"),", +#endif + (void *) id, f->index); } retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],"); if (retval == EOF) return(0); @@ -1107,7 +1180,7 @@ ddDoDumpDaVinci( retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask); if (retval != 1) return(retval); retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", - Cudd_IsComplement(cuddE(f)) ? "red" : "green"); + Cudd_IsComplement(cuddE(f)) ? "red" : "green"); if (retval == EOF) return(0); E = Cudd_Regular(cuddE(f)); retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask); @@ -1144,21 +1217,21 @@ ddDoDumpDDcal( FILE * fp, st_table * visited, char ** names, - long mask) + ptruint mask) { - DdNode *T, *E; - int retval; - long id, idT, idE; + DdNode *T, *E; + int retval; + ptruint id, idT, idE; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); #endif - id = ((long) f & mask) / sizeof(DdNode); + id = ((ptruint) f & mask) / sizeof(DdNode); /* If already visited, do nothing. */ if (st_is_member(visited, (char *) f) == 1) { - return(1); + return(1); } /* Check for abnormal condition that should never happen. */ @@ -1171,9 +1244,9 @@ ddDoDumpDDcal( /* Check for special case: If constant node, assign constant. */ if (Cudd_IsConstant(f)) { - if (f != DD_ONE(dd) && f != DD_ZERO(dd)) - return(0); - retval = fprintf(fp, "n%lx = %g\n", id, cuddV(f)); + if (f != DD_ONE(dd) && f != DD_ZERO(dd)) + return(0); + retval = fprintf(fp, "n%p = %g\n", (void *) id, cuddV(f)); if (retval == EOF) { return(0); } else { @@ -1188,16 +1261,22 @@ ddDoDumpDDcal( E = Cudd_Regular(cuddE(f)); retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask); if (retval != 1) return(retval); - idT = ((long) T & mask) / sizeof(DdNode); - idE = ((long) E & mask) / sizeof(DdNode); + idT = ((ptruint) T & mask) / sizeof(DdNode); + idE = ((ptruint) E & mask) / sizeof(DdNode); if (names != NULL) { - retval = fprintf(fp, "n%lx = %s * n%lx + %s' * n%lx%s\n", - id, names[f->index], idT, names[f->index], - idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + retval = fprintf(fp, "n%p = %s * n%p + %s' * n%p%s\n", + (void *) id, names[f->index], + (void *) idT, names[f->index], + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); } else { - retval = fprintf(fp, "n%lx = v%d * n%lx + v%d' * n%lx%s\n", - id, f->index, idT, f->index, - idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, "n%p = v%u * n%p + v%u' * n%p%s\n", +#else + retval = fprintf(fp, "n%p = v%hu * n%p + v%hu' * n%p%s\n", +#endif + (void *) id, f->index, + (void *) idT, f->index, + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); } if (retval == EOF) { return(0); @@ -1232,8 +1311,8 @@ ddDoDumpFactoredForm( FILE * fp, char ** names) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -1248,47 +1327,56 @@ ddDoDumpFactoredForm( T = cuddT(f); E = cuddE(f); if (T != DD_ZERO(dd)) { - if (E != DD_ONE(dd)) { + if (E != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "x%u", f->index); +#else + retval = fprintf(fp, "x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (T != DD_ONE(dd)) { + retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,T,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); + retval = fprintf(fp, " + "); + if (retval == EOF) return(0); + } + E = Cudd_Regular(E); + if (T != DD_ONE(dd)) { if (names != NULL) { - retval = fprintf(fp, "%s", names[f->index]); + retval = fprintf(fp, "!%s", names[f->index]); } else { - retval = fprintf(fp, "x%d", f->index); +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "!x%u", f->index); +#else + retval = fprintf(fp, "!x%hu", f->index); +#endif } if (retval == EOF) return(0); } - if (T != DD_ONE(dd)) { - retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (E != DD_ONE(dd)) { + retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", + E != cuddE(f) ? "!" : ""); if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,T,fp,names); + retval = ddDoDumpFactoredForm(dd,E,fp,names); if (retval != 1) return(retval); retval = fprintf(fp, ")"); if (retval == EOF) return(0); } - if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); - retval = fprintf(fp, " + "); - if (retval == EOF) return(0); - } - E = Cudd_Regular(E); - if (T != DD_ONE(dd)) { - if (names != NULL) { - retval = fprintf(fp, "!%s", names[f->index]); - } else { - retval = fprintf(fp, "!x%d", f->index); - } - if (retval == EOF) return(0); - } - if (E != DD_ONE(dd)) { - retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", - E != cuddE(f) ? "!" : ""); - if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,E,fp,names); - if (retval != 1) return(retval); - retval = fprintf(fp, ")"); - if (retval == EOF) return(0); - } return(1); } /* end of ddDoDumpFactoredForm */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddGenCof.c b/src/bdd/cudd/cuddGenCof.c index 93e15da0..35c380c0 100644 --- a/src/bdd/cudd/cuddGenCof.c +++ b/src/bdd/cudd/cuddGenCof.c @@ -7,42 +7,71 @@ Synopsis [Generalized cofactors for BDDs and ADDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddConstrain() - <li> Cudd_bddRestrict() - <li> Cudd_addConstrain() - <li> Cudd_bddConstrainDecomp() - <li> Cudd_addRestrict() - <li> Cudd_bddCharToVect() - <li> Cudd_bddLICompaction() - <li> Cudd_bddSqueeze() - <li> Cudd_SubsetCompress() - <li> Cudd_SupersetCompress() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddConstrainRecur() - <li> cuddBddRestrictRecur() - <li> cuddAddConstrainRecur() - <li> cuddAddRestrictRecur() - <li> cuddBddLICompaction() - </ul> - Static procedures included in this module: - <ul> - <li> cuddBddConstrainDecomp() - <li> cuddBddCharToVect() - <li> cuddBddLICMarkEdges() - <li> cuddBddLICBuildResult() - <li> cuddBddSqueeze() - </ul> - ] + <ul> + <li> Cudd_bddConstrain() + <li> Cudd_bddRestrict() + <li> Cudd_bddNPAnd() + <li> Cudd_addConstrain() + <li> Cudd_bddConstrainDecomp() + <li> Cudd_addRestrict() + <li> Cudd_bddCharToVect() + <li> Cudd_bddLICompaction() + <li> Cudd_bddSqueeze() + <li> Cudd_SubsetCompress() + <li> Cudd_SupersetCompress() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddConstrainRecur() + <li> cuddBddRestrictRecur() + <li> cuddBddNPAndRecur() + <li> cuddAddConstrainRecur() + <li> cuddAddRestrictRecur() + <li> cuddBddLICompaction() + </ul> + Static procedures included in this module: + <ul> + <li> cuddBddConstrainDecomp() + <li> cuddBddCharToVect() + <li> cuddBddLICMarkEdges() + <li> cuddBddLICBuildResult() + <li> cuddBddSqueeze() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -53,6 +82,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -85,13 +115,16 @@ typedef struct MarkCacheKey { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.38 2005/05/14 17:27:11 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -99,17 +132,20 @@ static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddBddConstrainDecomp ARGS((DdManager *dd, DdNode *f, DdNode **decomp)); -static DdNode * cuddBddCharToVect ARGS((DdManager *dd, DdNode *f, DdNode *x)); -static int cuddBddLICMarkEdges ARGS((DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache)); -static DdNode * cuddBddLICBuildResult ARGS((DdManager *dd, DdNode *f, st_table *cache, st_table *table)); -static int MarkCacheHash ARGS((const char *ptr, int modulus)); -static int MarkCacheCompare ARGS((const char *ptr1, const char *ptr2)); -static enum st_retval MarkCacheCleanUp ARGS((char *key, char *value, char *arg)); -static DdNode * cuddBddSqueeze ARGS((DdManager *dd, DdNode *l, DdNode *u)); +static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp); +static DdNode * cuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x); +static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache); +static DdNode * cuddBddLICBuildResult (DdManager *dd, DdNode *f, st_table *cache, st_table *table); +static int MarkCacheHash (const char *ptr, int modulus); +static int MarkCacheCompare (const char *ptr1, const char *ptr2); +static enum st_retval MarkCacheCleanUp (char *key, char *value, char *arg); +static DdNode * cuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -149,8 +185,8 @@ Cudd_bddConstrain( DdNode *res; do { - dd->reordered = 0; - res = cuddBddConstrainRecur(dd,f,c); + dd->reordered = 0; + res = cuddBddConstrainRecur(dd,f,c); } while (dd->reordered == 1); return(res); @@ -194,34 +230,34 @@ Cudd_bddRestrict( /* Check if supports intersect. */ retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); if (retval == 0) { - return(NULL); + return(NULL); } cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); Cudd_IterDerefBdd(dd,suppF); if (commonSupport == DD_ONE(dd)) { - Cudd_IterDerefBdd(dd,commonSupport); - Cudd_IterDerefBdd(dd,suppC); - return(f); + Cudd_IterDerefBdd(dd,commonSupport); + Cudd_IterDerefBdd(dd,suppC); + return(f); } Cudd_IterDerefBdd(dd,commonSupport); /* Abstract from c the variables that do not appear in f. */ cplus = Cudd_bddExistAbstract(dd, c, suppC); if (cplus == NULL) { - Cudd_IterDerefBdd(dd,suppC); - return(NULL); + Cudd_IterDerefBdd(dd,suppC); + return(NULL); } cuddRef(cplus); Cudd_IterDerefBdd(dd,suppC); do { - dd->reordered = 0; - res = cuddBddRestrictRecur(dd, f, cplus); + dd->reordered = 0; + res = cuddBddRestrictRecur(dd, f, cplus); } while (dd->reordered == 1); if (res == NULL) { - Cudd_IterDerefBdd(dd,cplus); - return(NULL); + Cudd_IterDerefBdd(dd,cplus); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,cplus); @@ -230,11 +266,11 @@ Cudd_bddRestrict( sizeF = Cudd_DagSize(f); sizeRes = Cudd_DagSize(res); if (sizeF <= sizeRes) { - Cudd_IterDerefBdd(dd, res); - return(f); + Cudd_IterDerefBdd(dd, res); + return(f); } else { - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } } /* end of Cudd_bddRestrict */ @@ -242,6 +278,42 @@ Cudd_bddRestrict( /**Function******************************************************************** + Synopsis [Computes f non-polluting-and g.] + + Description [Computes f non-polluting-and g. The non-polluting AND + of f and g is a hybrid of AND and Restrict. From Restrict, this + operation takes the idea of existentially quantifying the top + variable of the second operand if it does not appear in the first. + Therefore, the variables that appear in the result also appear in f. + For the rest, the function behaves like AND. Since the two operands + play different roles, non-polluting AND is not commutative. + + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddNPAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNPAnd */ + + +/**Function******************************************************************** + Synopsis [Computes f constrain c for ADDs.] Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 @@ -269,8 +341,8 @@ Cudd_addConstrain( DdNode *res; do { - dd->reordered = 0; - res = cuddAddConstrainRecur(dd,f,c); + dd->reordered = 0; + res = cuddAddConstrainRecur(dd,f,c); } while (dd->reordered == 1); return(res); @@ -307,33 +379,33 @@ Cudd_bddConstrainDecomp( /* Create an initialize decomposition array. */ decomp = ABC_ALLOC(DdNode *,dd->size); if (decomp == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) { - decomp[i] = NULL; + decomp[i] = NULL; } do { - dd->reordered = 0; - /* Clean up the decomposition array in case reordering took place. */ - for (i = 0; i < dd->size; i++) { - if (decomp[i] != NULL) { - Cudd_IterDerefBdd(dd, decomp[i]); - decomp[i] = NULL; + dd->reordered = 0; + /* Clean up the decomposition array in case reordering took place. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] != NULL) { + Cudd_IterDerefBdd(dd, decomp[i]); + decomp[i] = NULL; + } } - } - res = cuddBddConstrainDecomp(dd,f,decomp); + res = cuddBddConstrainDecomp(dd,f,decomp); } while (dd->reordered == 1); if (res == 0) { - ABC_FREE(decomp); - return(NULL); + ABC_FREE(decomp); + return(NULL); } /* Missing components are constant ones. */ for (i = 0; i < dd->size; i++) { - if (decomp[i] == NULL) { - decomp[i] = DD_ONE(dd); - cuddRef(decomp[i]); - } + if (decomp[i] == NULL) { + decomp[i] = DD_ONE(dd); + cuddRef(decomp[i]); + } } return(decomp); @@ -369,20 +441,20 @@ Cudd_addRestrict( /* Check if supports intersect. */ supp_f = Cudd_Support(dd, f); if (supp_f == NULL) { - return(NULL); + return(NULL); } cuddRef(supp_f); supp_c = Cudd_Support(dd, c); if (supp_c == NULL) { - Cudd_RecursiveDeref(dd,supp_f); - return(NULL); + Cudd_RecursiveDeref(dd,supp_f); + return(NULL); } cuddRef(supp_c); commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); if (commonSupport == NULL) { - Cudd_RecursiveDeref(dd,supp_f); - Cudd_RecursiveDeref(dd,supp_c); - return(NULL); + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + return(NULL); } cuddRef(commonSupport); Cudd_RecursiveDeref(dd,supp_f); @@ -391,21 +463,21 @@ Cudd_addRestrict( Cudd_RecursiveDeref(dd,commonSupport); if (intersection) { - do { - dd->reordered = 0; - res = cuddAddRestrictRecur(dd, f, c); - } while (dd->reordered == 1); - sizeF = Cudd_DagSize(f); - sizeRes = Cudd_DagSize(res); - if (sizeF <= sizeRes) { - cuddRef(res); - Cudd_RecursiveDeref(dd, res); - return(f); - } else { - return(res); - } + do { + dd->reordered = 0; + res = cuddAddRestrictRecur(dd, f, c); + } while (dd->reordered == 1); + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + cuddRef(res); + Cudd_RecursiveDeref(dd, res); + return(f); + } else { + return(res); + } } else { - return(f); + return(f); } } /* end of Cudd_addRestrict */ @@ -427,7 +499,7 @@ Cudd_addRestrict( otherwise. The size of the array equals the number of variables in the manager. The components of the solution have their reference counts already incremented (unlike the results of most other functions in - the package.] + the package).] SideEffects [None] @@ -447,28 +519,28 @@ Cudd_bddCharToVect( vect = ABC_ALLOC(DdNode *, dd->size); if (vect == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } do { - dd->reordered = 0; - for (i = 0; i < dd->size; i++) { - res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); - if (res == NULL) { - /* Clean up the vector array in case reordering took place. */ - for (j = 0; j < i; j++) { - Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); - } - break; + dd->reordered = 0; + for (i = 0; i < dd->size; i++) { + res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); + if (res == NULL) { + /* Clean up the vector array in case reordering took place. */ + for (j = 0; j < i; j++) { + Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); + } + break; + } + cuddRef(res); + vect[dd->invperm[i]] = res; } - cuddRef(res); - vect[dd->invperm[i]] = res; - } } while (dd->reordered == 1); if (res == NULL) { - ABC_FREE(vect); - return(NULL); + ABC_FREE(vect); + return(NULL); } return(vect); @@ -503,8 +575,8 @@ Cudd_bddLICompaction( DdNode *res; do { - dd->reordered = 0; - res = cuddBddLICompaction(dd,f,c); + dd->reordered = 0; + res = cuddBddLICompaction(dd,f,c); } while (dd->reordered == 1); return(res); @@ -536,8 +608,8 @@ Cudd_bddSqueeze( int sizeRes, sizeL, sizeU; do { - dd->reordered = 0; - res = cuddBddSqueeze(dd,l,u); + dd->reordered = 0; + res = cuddBddSqueeze(dd,l,u); } while (dd->reordered == 1); if (res == NULL) return(NULL); /* We now compare the result with the bounds and return the smallest. @@ -546,17 +618,17 @@ Cudd_bddSqueeze( sizeRes = Cudd_DagSize(res); sizeU = Cudd_DagSize(u); if (sizeU <= sizeRes) { - cuddRef(res); - Cudd_IterDerefBdd(dd,res); - res = u; - sizeRes = sizeU; + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = u; + sizeRes = sizeU; } sizeL = Cudd_DagSize(l); if (sizeL <= sizeRes) { - cuddRef(res); - Cudd_IterDerefBdd(dd,res); - res = l; - sizeRes = sizeL; + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = l; + sizeRes = sizeL; } return(res); @@ -595,8 +667,8 @@ Cudd_bddMinimize( cuddRef(cplus); res = Cudd_bddLICompaction(dd,f,cplus); if (res == NULL) { - Cudd_IterDerefBdd(dd,cplus); - return(NULL); + Cudd_IterDerefBdd(dd,cplus); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,cplus); @@ -638,15 +710,15 @@ Cudd_SubsetCompress( cuddRef(tmp1); tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0); if (tmp2 == NULL) { - Cudd_IterDerefBdd(dd,tmp1); - return(NULL); + Cudd_IterDerefBdd(dd,tmp1); + return(NULL); } cuddRef(tmp2); Cudd_IterDerefBdd(dd,tmp1); res = Cudd_bddSqueeze(dd,tmp2,f); if (res == NULL) { - Cudd_IterDerefBdd(dd,tmp2); - return(NULL); + Cudd_IterDerefBdd(dd,tmp2); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,tmp2); @@ -714,9 +786,9 @@ cuddBddConstrainRecur( DdNode * c) { DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; - DdNode *one, *zero; + DdNode *one, *zero; unsigned int topf, topc; - int index; + int index; int comple = 0; statLine(dd); @@ -724,16 +796,16 @@ cuddBddConstrainRecur( zero = Cudd_Not(one); /* Trivial cases. */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); - if (f == Cudd_Not(c)) return(zero); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - comple = 1; + f = Cudd_Not(f); + comple = 1; } /* Now f is a regular pointer to a non-constant node; c is also ** non-constant, but may be complemented. @@ -742,78 +814,78 @@ cuddBddConstrainRecur( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Recursive step. */ topf = dd->perm[f->index]; topc = dd->perm[Cudd_Regular(c)->index]; if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = Cudd_Regular(c)->index; - Fv = Fnv = f; + index = Cudd_Regular(c)->index; + Fv = Fnv = f; } if (topc <= topf) { - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddBddConstrainRecur(dd, Fv, Cv); - if (t == NULL) - return(NULL); + t = cuddBddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return Fnv @ Cnv */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddBddConstrainRecur(dd, Fnv, Cnv); - if (r == NULL) - return(NULL); - } - return(Cudd_NotCond(r,comple)); + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(Cudd_NotCond(r,comple)); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddBddConstrainRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return Fv @ Cv previously computed */ - cuddDeref(t); - return(Cudd_NotCond(t,comple)); + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -842,26 +914,26 @@ cuddBddRestrictRecur( DdNode * f, DdNode * c) { - DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; unsigned int topf, topc; - int index; - int comple = 0; + int index; + int comple = 0; statLine(dd); one = DD_ONE(dd); zero = Cudd_Not(one); /* Trivial cases */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); - if (f == Cudd_Not(c)) return(zero); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - comple = 1; + f = Cudd_Not(f); + comple = 1; } /* Now f is a regular pointer to a non-constant node; c is also ** non-constant, but may be complemented. @@ -870,100 +942,100 @@ cuddBddRestrictRecur( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } topf = dd->perm[f->index]; topc = dd->perm[Cudd_Regular(c)->index]; - if (topc < topf) { /* abstract top variable from c */ - DdNode *d, *s1, *s2; + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; - /* Find complements of cofactors of c. */ - if (Cudd_IsComplement(c)) { - s1 = cuddT(Cudd_Regular(c)); - s2 = cuddE(Cudd_Regular(c)); - } else { - s1 = Cudd_Not(cuddT(c)); - s2 = Cudd_Not(cuddE(c)); - } - /* Take the OR by applying DeMorgan. */ - d = cuddBddAndRecur(dd, s1, s2); - if (d == NULL) return(NULL); - d = Cudd_Not(d); - cuddRef(d); - r = cuddBddRestrictRecur(dd, f, d); - if (r == NULL) { + /* Find complements of cofactors of c. */ + if (Cudd_IsComplement(c)) { + s1 = cuddT(Cudd_Regular(c)); + s2 = cuddE(Cudd_Regular(c)); + } else { + s1 = Cudd_Not(cuddT(c)); + s2 = Cudd_Not(cuddE(c)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(dd, s1, s2); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(dd, d); + return(NULL); + } + cuddRef(r); Cudd_IterDerefBdd(dd, d); - return(NULL); - } - cuddRef(r); - Cudd_IterDerefBdd(dd, d); - cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); - cuddDeref(r); - return(Cudd_NotCond(r,comple)); + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + cuddDeref(r); + return(Cudd_NotCond(r,comple)); } /* Recursive step. Here topf <= topc. */ index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (topc == topf) { - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddBddRestrictRecur(dd, Fv, Cv); - if (t == NULL) return(NULL); + t = cuddBddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return(Fnv @ Cnv) */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddBddRestrictRecur(dd, Fnv, Cnv); - if (r == NULL) return(NULL); - } - return(Cudd_NotCond(r,comple)); + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(Cudd_NotCond(r,comple)); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddBddRestrictRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ - cuddDeref(t); - return(Cudd_NotCond(t,comple)); + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -976,6 +1048,147 @@ cuddBddRestrictRecur( /**Function******************************************************************** + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNPAnd] + +******************************************************************************/ +DdNode * +cuddBddNPAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(one); + else return(Cudd_Not(one)); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + if (F == one) { + return(f); + } + + /* At this point f and g are not constant. */ + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + if (topg < topf) { /* abstract top variable from g */ + DdNode *d; + + /* Find complements of cofactors of g. */ + if (Cudd_IsComplement(g)) { + gt = cuddT(G); + ge = cuddE(G); + } else { + gt = Cudd_Not(cuddT(g)); + ge = Cudd_Not(cuddE(g)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(manager, gt, ge); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddNPAndRecur(manager, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(manager, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(manager, d); + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + cuddDeref(r); + return(r); + } + + /* Compute cofactors. */ + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + + if (topg == topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddAndRecur(manager, ft, gt); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fe, ge); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + return(r); + +} /* end of cuddBddNPAndRecur */ + + +/**Function******************************************************************** + Synopsis [Performs the recursive step of Cudd_addConstrain.] Description [Performs the recursive step of Cudd_addConstrain. @@ -993,81 +1206,81 @@ cuddAddConstrainRecur( DdNode * c) { DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; - DdNode *one, *zero; + DdNode *one, *zero; unsigned int topf, topc; - int index; + int index; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); /* Trivial cases. */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); /* Now f and c are non-constant. */ /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c); if (r != NULL) { - return(r); + return(r); } /* Recursive step. */ topf = dd->perm[f->index]; topc = dd->perm[c->index]; if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = c->index; - Fv = Fnv = f; + index = c->index; + Fv = Fnv = f; } if (topc <= topf) { - Cv = cuddT(c); Cnv = cuddE(c); + Cv = cuddT(c); Cnv = cuddE(c); } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddAddConstrainRecur(dd, Fv, Cv); - if (t == NULL) - return(NULL); + t = cuddAddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return Fnv @ Cnv */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddAddConstrainRecur(dd, Fnv, Cnv); - if (r == NULL) - return(NULL); - } - return(r); + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(r); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddAddConstrainRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + e = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return Fv @ Cv previously computed */ - cuddDeref(t); - return(t); + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(t); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -1096,97 +1309,97 @@ cuddAddRestrictRecur( DdNode * f, DdNode * c) { - DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; unsigned int topf, topc; - int index; + int index; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); /* Trivial cases */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); /* Now f and c are non-constant. */ /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c); if (r != NULL) { - return(r); + return(r); } topf = dd->perm[f->index]; topc = dd->perm[c->index]; - if (topc < topf) { /* abstract top variable from c */ - DdNode *d, *s1, *s2; - - /* Find cofactors of c. */ - s1 = cuddT(c); - s2 = cuddE(c); - /* Take the OR by applying DeMorgan. */ - d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); - if (d == NULL) return(NULL); - cuddRef(d); - r = cuddAddRestrictRecur(dd, f, d); - if (r == NULL) { + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find cofactors of c. */ + s1 = cuddT(c); + s2 = cuddE(c); + /* Take the OR by applying DeMorgan. */ + d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); + if (d == NULL) return(NULL); + cuddRef(d); + r = cuddAddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_RecursiveDeref(dd, d); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(dd, d); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(dd, d); - cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); - cuddDeref(r); - return(r); + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + cuddDeref(r); + return(r); } /* Recursive step. Here topf <= topc. */ index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (topc == topf) { - Cv = cuddT(c); Cnv = cuddE(c); + Cv = cuddT(c); Cnv = cuddE(c); } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddAddRestrictRecur(dd, Fv, Cv); - if (t == NULL) return(NULL); + t = cuddAddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return(Fnv @ Cnv) */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddAddRestrictRecur(dd, Fnv, Cnv); - if (r == NULL) return(NULL); - } - return(r); + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(r); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddAddRestrictRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + e = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ - cuddDeref(t); - return(t); + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(t); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -1240,27 +1453,27 @@ cuddBddLICompaction( ** appears. Hence, the same node and constrain may give different results ** in successive invocations. */ - marktable = st_init_table(st_ptrcmp, st_ptrhash);; + marktable = st_init_table(st_ptrcmp,st_ptrhash); if (marktable == NULL) { - return(NULL); + return(NULL); } markcache = st_init_table(MarkCacheCompare,MarkCacheHash); if (markcache == NULL) { - st_free_table(marktable); - return(NULL); + st_free_table(marktable); + return(NULL); } if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) { - st_foreach(markcache, (ST_PFSR)MarkCacheCleanUp, NULL); - st_free_table(marktable); - st_free_table(markcache); - return(NULL); + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(marktable); + st_free_table(markcache); + return(NULL); } - st_foreach(markcache, (ST_PFSR)MarkCacheCleanUp, NULL); + st_foreach(markcache, MarkCacheCleanUp, NULL); st_free_table(markcache); - buildcache = st_init_table(st_ptrcmp, st_ptrhash);; + buildcache = st_init_table(st_ptrcmp,st_ptrhash); if (buildcache == NULL) { - st_free_table(marktable); - return(NULL); + st_free_table(marktable); + return(NULL); } res = cuddBddLICBuildResult(dd,f,buildcache,marktable); st_free_table(buildcache); @@ -1304,13 +1517,13 @@ cuddBddConstrainDecomp( fv = cuddT(F); fvn = cuddE(F); if (F == f) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); } /* Compute abstraction of top variable. */ fAbs = cuddBddAndRecur(dd, fv, fvn); if (fAbs == NULL) { - return(0); + return(0); } cuddRef(fAbs); fAbs = Cudd_Not(fAbs); @@ -1318,15 +1531,15 @@ cuddBddConstrainDecomp( ** decomposition. */ ok = cuddBddConstrainDecomp(dd, fAbs, decomp); if (ok == 0) { - Cudd_IterDerefBdd(dd,fAbs); - return(0); + Cudd_IterDerefBdd(dd,fAbs); + return(0); } /* Compute the component of the decomposition corresponding to the ** top variable and store it in the decomposition array. */ result = cuddBddConstrainRecur(dd, f, fAbs); if (result == NULL) { - Cudd_IterDerefBdd(dd,fAbs); - return(0); + Cudd_IterDerefBdd(dd,fAbs); + return(0); } cuddRef(result); decomp[F->index] = result; @@ -1365,7 +1578,7 @@ cuddBddCharToVect( /* Check the cache. */ res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x); if (res != NULL) { - return(res); + return(res); } F = Cudd_Regular(f); @@ -1383,9 +1596,9 @@ cuddBddCharToVect( fE = Cudd_NotCond(cuddE(F),comple); if (topf == level) { - if (fT == zero) return(zero); - if (fE == zero) return(one); - return(x); + if (fT == zero) return(zero); + if (fE == zero) return(one); + return(x); } /* Here topf < level. */ @@ -1394,20 +1607,20 @@ cuddBddCharToVect( T = cuddBddCharToVect(dd, fT, x); if (T == NULL) { - return(NULL); + return(NULL); } cuddRef(T); E = cuddBddCharToVect(dd, fE, x); if (E == NULL) { - Cudd_IterDerefBdd(dd,T); - return(NULL); + Cudd_IterDerefBdd(dd,T); + return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd, dd->vars[F->index], T, E); if (res == NULL) { - Cudd_IterDerefBdd(dd,T); - Cudd_IterDerefBdd(dd,E); - return(NULL); + Cudd_IterDerefBdd(dd,T); + Cudd_IterDerefBdd(dd,E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -1441,7 +1654,6 @@ cuddBddLICMarkEdges( DdNode *Fv, *Fnv, *Cv, *Cnv; DdNode *one, *zero; unsigned int topf, topc; - int index; int comple; int resT, resE, res, retval; char **slot; @@ -1465,75 +1677,73 @@ cuddBddLICMarkEdges( /* Check the cache. */ key = ABC_ALLOC(MarkCacheKey, 1); if (key == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } key->f = f; key->c = c; - if (st_lookup(cache, (char *)key, (char **)&res)) { - ABC_FREE(key); - if (comple) { - if (res == DD_LIC_0) res = DD_LIC_1; - else if (res == DD_LIC_1) res = DD_LIC_0; - } - return(res); + if (st_lookup_int(cache, (char *)key, &res)) { + ABC_FREE(key); + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); } /* Recursive step. */ topf = dd->perm[f->index]; topc = cuddI(dd,Cudd_Regular(c)->index); if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = Cudd_Regular(c)->index; - Fv = Fnv = f; + Fv = Fnv = f; } if (topc <= topf) { - /* We know that c is not constant because f is not. */ - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + /* We know that c is not constant because f is not. */ + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache); if (resT == CUDD_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache); if (resE == CUDD_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } /* Update edge markings. */ if (topf <= topc) { - retval = st_find_or_add(table, (char *)f, (char ***)&slot); - if (retval == 0) { - *slot = (char *) (ptrint)((resT << 2) | resE); - } else if (retval == 1) { - *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); - } else { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); - } + retval = st_find_or_add(table, (char *)f, (char ***)&slot); + if (retval == 0) { + *slot = (char *) (ptrint)((resT << 2) | resE); + } else if (retval == 1) { + *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); + } else { + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); + } } /* Cache result. */ res = resT | resE; if (st_insert(cache, (char *)key, (char *)(ptrint)res) == ST_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } /* Take into account possible complementation. */ if (comple) { - if (res == DD_LIC_0) res = DD_LIC_1; - else if (res == DD_LIC_1) res = DD_LIC_0; + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; } return(res); @@ -1561,8 +1771,7 @@ cuddBddLICBuildResult( { DdNode *Fv, *Fnv, *r, *t, *e; DdNode *one, *zero; - unsigned int topf; - int index; + int index; int comple; int markT, markE, markings; @@ -1575,75 +1784,74 @@ cuddBddLICBuildResult( f = Cudd_Regular(f); /* Check the cache. */ - if (st_lookup(cache, (char *)f, (char **)&r)) { - return(Cudd_NotCond(r,comple)); + if (st_lookup(cache, (const char *)f, (char **)&r)) { + return(Cudd_NotCond(r,comple)); } /* Retrieve the edge markings. */ - if (st_lookup(table, (char *)f, (char **)&markings) == 0) - return(NULL); + if (st_lookup_int(table, (char *)f, &markings) == 0) + return(NULL); markT = markings >> 2; markE = markings & 3; - topf = dd->perm[f->index]; index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (markT == DD_LIC_NL) { - t = cuddBddLICBuildResult(dd,Fv,cache,table); - if (t == NULL) { - return(NULL); - } + t = cuddBddLICBuildResult(dd,Fv,cache,table); + if (t == NULL) { + return(NULL); + } } else if (markT == DD_LIC_1) { - t = one; + t = one; } else { - t = zero; + t = zero; } cuddRef(t); if (markE == DD_LIC_NL) { - e = cuddBddLICBuildResult(dd,Fnv,cache,table); - if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); - } + e = cuddBddLICBuildResult(dd,Fnv,cache,table); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } } else if (markE == DD_LIC_1) { - e = one; + e = one; } else { - e = zero; + e = zero; } cuddRef(e); if (markT == DD_LIC_DC && markE != DD_LIC_DC) { - r = e; + r = e; } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } } - } cuddDeref(t); cuddDeref(e); if (st_insert(cache, (char *)f, (char *)r) == ST_OUT_OF_MEM) { - cuddRef(r); - Cudd_IterDerefBdd(dd,r); - return(NULL); + cuddRef(r); + Cudd_IterDerefBdd(dd,r); + return(NULL); } return(Cudd_NotCond(r,comple)); @@ -1669,9 +1877,9 @@ MarkCacheHash( int modulus) { int val = 0; - const MarkCacheKey *entry; + MarkCacheKey *entry; - entry = (const MarkCacheKey *) ptr; + entry = (MarkCacheKey *) ptr; val = (int) (ptrint) entry->f; val = val * 997 + (int) (ptrint) entry->c; @@ -1771,7 +1979,7 @@ cuddBddSqueeze( statLine(dd); if (l == u) { - return(l); + return(l); } one = DD_ONE(dd); zero = Cudd_Not(one); @@ -1785,11 +1993,11 @@ cuddBddSqueeze( /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(u)) { - DdNode *temp; - temp = Cudd_Not(l); - l = Cudd_Not(u); - u = temp; - comple = 1; + DdNode *temp; + temp = Cudd_Not(l); + l = Cudd_Not(u); + u = temp; + comple = 1; } /* At this point u is regular and non-constant; l is non-constant, but ** may be complemented. */ @@ -1799,89 +2007,89 @@ cuddBddSqueeze( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Recursive step. */ topu = dd->perm[u->index]; topl = dd->perm[Cudd_Regular(l)->index]; if (topu <= topl) { - index = u->index; - ut = cuddT(u); ue = cuddE(u); + index = u->index; + ut = cuddT(u); ue = cuddE(u); } else { - index = Cudd_Regular(l)->index; - ut = ue = u; + index = Cudd_Regular(l)->index; + ut = ue = u; } if (topl <= topu) { - lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); - if (Cudd_IsComplement(l)) { - lt = Cudd_Not(lt); - le = Cudd_Not(le); - } + lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); + if (Cudd_IsComplement(l)) { + lt = Cudd_Not(lt); + le = Cudd_Not(le); + } } else { - lt = le = l; + lt = le = l; } /* If one interval is contained in the other, use the smaller ** interval. This corresponds to one-sided matching. */ if ((lt == zero || Cudd_bddLeq(dd,lt,le)) && - (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ - r = cuddBddSqueeze(dd, le, ue); - if (r == NULL) - return(NULL); - return(Cudd_NotCond(r,comple)); + (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ + r = cuddBddSqueeze(dd, le, ue); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) && - (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ - r = cuddBddSqueeze(dd, lt, ut); - if (r == NULL) - return(NULL); - return(Cudd_NotCond(r,comple)); + (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ + r = cuddBddSqueeze(dd, lt, ut); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) && - (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ - t = cuddBddSqueeze(dd, lt, ut); - cuddRef(t); - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(dd, index, Cudd_Not(t), t); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); + (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ + t = cuddBddSqueeze(dd, lt, ut); + cuddRef(t); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd, index, Cudd_Not(t), t); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } - } - cuddDeref(t); - if (r == NULL) - return(NULL); - cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); - return(Cudd_NotCond(r,comple)); + cuddDeref(t); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) && - (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ - e = cuddBddSqueeze(dd, le, ue); - cuddRef(e); - if (Cudd_IsComplement(e)) { - r = cuddUniqueInter(dd, index, Cudd_Not(e), e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - return(NULL); + (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ + e = cuddBddSqueeze(dd, le, ue); + cuddRef(e); + if (Cudd_IsComplement(e)) { + r = cuddUniqueInter(dd, index, Cudd_Not(e), e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } else { + r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + r = Cudd_Not(r); } - } else { - r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - return(NULL); - } - r = Cudd_Not(r); - } - cuddDeref(e); - if (r == NULL) - return(NULL); - cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); - return(Cudd_NotCond(r,comple)); + cuddDeref(e); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); } #if 0 @@ -1891,61 +2099,61 @@ cuddBddSqueeze( ** This approach corresponds to two-sided matching, and is very ** expensive. */ if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) { - DdNode *au, *al; - au = cuddBddAndRecur(dd,ut,ue); - if (au == NULL) - return(NULL); - cuddRef(au); - al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); - if (al == NULL) { - Cudd_IterDerefBdd(dd,au); - return(NULL); - } - cuddRef(al); - al = Cudd_Not(al); - ar = cuddBddSqueeze(dd, al, au); - if (ar == NULL) { + DdNode *au, *al; + au = cuddBddAndRecur(dd,ut,ue); + if (au == NULL) + return(NULL); + cuddRef(au); + al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); + if (al == NULL) { + Cudd_IterDerefBdd(dd,au); + return(NULL); + } + cuddRef(al); + al = Cudd_Not(al); + ar = cuddBddSqueeze(dd, al, au); + if (ar == NULL) { + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + return(NULL); + } + cuddRef(ar); Cudd_IterDerefBdd(dd,au); Cudd_IterDerefBdd(dd,al); - return(NULL); - } - cuddRef(ar); - Cudd_IterDerefBdd(dd,au); - Cudd_IterDerefBdd(dd,al); } else { - ar = NULL; + ar = NULL; } #endif t = cuddBddSqueeze(dd, lt, ut); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = cuddBddSqueeze(dd, le, ue); if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); + Cudd_IterDerefBdd(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -1955,12 +2163,12 @@ cuddBddSqueeze( ** it is better than the one obtained by recursion. */ cuddRef(r); if (ar != NULL) { - if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { - Cudd_IterDerefBdd(dd, r); - r = ar; - } else { - Cudd_IterDerefBdd(dd, ar); - } + if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { + Cudd_IterDerefBdd(dd, r); + r = ar; + } else { + Cudd_IterDerefBdd(dd, ar); + } } cuddDeref(r); #endif @@ -1969,5 +2177,7 @@ cuddBddSqueeze( return(Cudd_NotCond(r,comple)); } /* end of cuddBddSqueeze */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddGenetic.c b/src/bdd/cudd/cuddGenetic.c index d2739c85..8c168440 100644 --- a/src/bdd/cudd/cuddGenetic.c +++ b/src/bdd/cudd/cuddGenetic.c @@ -7,23 +7,23 @@ Synopsis [Genetic algorithm for variable reordering.] Description [Internal procedures included in this file: - <ul> - <li> cuddGa() - </ul> - Static procedures included in this module: - <ul> - <li> make_random() - <li> sift_up() - <li> build_dd() - <li> largest() - <li> rand_int() - <li> array_hash() - <li> array_compare() - <li> find_best() - <li> find_average_fitness() - <li> PMX() - <li> roulette() - </ul> + <ul> + <li> cuddGa() + </ul> + Static procedures included in this module: + <ul> + <li> make_random() + <li> sift_up() + <li> build_dd() + <li> largest() + <li> rand_int() + <li> array_hash() + <li> array_compare() + <li> find_best() + <li> find_average_fitness() + <li> PMX() + <li> roulette() + </ul> The genetic algorithm implemented here is as follows. We start with the current DD order. We sift this order and use this as the @@ -46,10 +46,37 @@ Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -59,6 +86,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -76,11 +104,11 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.28 2004/08/13 18:04:48 fabio Exp $"; #endif -static int popsize; /* the size of the population */ -static int numvars; /* the number of input variables in the ckt. */ +static int popsize; /* the size of the population */ +static int numvars; /* the number of input variables in the ckt. */ /* storedd stores the population orders and sizes. This table has two ** extra rows and one extras column. The two extra rows are used for the ** offspring produced by a crossover. Each row stores one order and its @@ -90,12 +118,12 @@ static int numvars; /* the number of input variables in the ckt. */ ** it is a two-dimensional structure. */ static int *storedd; -static st_table *computed; /* hash table to identify existing orders */ -static int *repeat; /* how many times an order is present */ -static int large; /* stores the index of the population with - ** the largest number of nodes in the DD */ +static st_table *computed; /* hash table to identify existing orders */ +static int *repeat; /* how many times an order is present */ +static int large; /* stores the index of the population with + ** the largest number of nodes in the DD */ static int result; -static int cross; /* the number of crossovers to perform */ +static int cross; /* the number of crossovers to perform */ /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -106,6 +134,9 @@ static int cross; /* the number of crossovers to perform */ */ #define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)] +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -113,20 +144,25 @@ static int cross; /* the number of crossovers to perform */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int make_random ARGS((DdManager *table, int lower)); -static int sift_up ARGS((DdManager *table, int x, int x_low)); -static int build_dd ARGS((DdManager *table, int num, int lower, int upper)); -static int largest ARGS(()); -static int rand_int ARGS((int a)); -static int array_hash ARGS((const char *array, int modulus)); -static int array_compare ARGS((const char *array1, const char *array2)); -static int find_best ARGS(()); -static double find_average_fitness ARGS(()); -static int PMX ARGS((int maxvar)); -static int roulette ARGS((int *p1, int *p2)); +static int make_random (DdManager *table, int lower); +static int sift_up (DdManager *table, int x, int x_low); +static int build_dd (DdManager *table, int num, int lower, int upper); +static int largest (void); +static int rand_int (int a); +static int array_hash (const char *array, int modulus); +static int array_compare (const char *array1, const char *array2); +static int find_best (void); +#ifdef DD_STATS +static double find_average_fitness (void); +#endif +static int PMX (int maxvar); +static int roulette (int *p1, int *p2); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -158,10 +194,12 @@ cuddGa( int lower /* lowest level to be reordered */, int upper /* highest level to be reorderded */) { - int i,n,m; /* dummy/loop vars */ - int index; - double average_fitness; - int small; /* index of smallest DD in population */ + int i,n,m; /* dummy/loop vars */ + int index; +#ifdef DD_STATS + double average_fitness; +#endif + int small; /* index of smallest DD in population */ /* Do an initial sifting to produce at least one reasonable individual. */ if (!cuddSifting(table,lower,upper)) return(0); @@ -169,20 +207,20 @@ cuddGa( /* Get the initial values. */ numvars = upper - lower + 1; /* number of variables to be reordered */ if (table->populationSize == 0) { - popsize = 3 * numvars; /* population size is 3 times # of vars */ - if (popsize > 120) { - popsize = 120; /* Maximum population size is 120 */ - } + popsize = 3 * numvars; /* population size is 3 times # of vars */ + if (popsize > 120) { + popsize = 120; /* Maximum population size is 120 */ + } } else { - popsize = table->populationSize; /* user specified value */ + popsize = table->populationSize; /* user specified value */ } - if (popsize < 4) popsize = 4; /* enforce minimum population size */ + if (popsize < 4) popsize = 4; /* enforce minimum population size */ /* Allocate population table. */ storedd = ABC_ALLOC(int,(popsize+2)*(numvars+1)); if (storedd == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } /* Initialize the computed table. This table is made up of two data @@ -195,39 +233,39 @@ cuddGa( */ repeat = ABC_ALLOC(int,popsize); if (repeat == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(storedd); + return(0); } for (i = 0; i < popsize; i++) { - repeat[i] = 0; + repeat[i] = 0; } computed = st_init_table(array_compare,array_hash); if (computed == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(storedd); + ABC_FREE(repeat); + return(0); } /* Copy the current DD and its size to the population table. */ for (i = 0; i < numvars; i++) { - STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ + STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ } STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ /* Store the initial order in the computed table. */ if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); } repeat[0]++; /* Insert the reverse order as second element of the population. */ for (i = 0; i < numvars; i++) { - STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ + STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ } /* Now create the random orders. make_random fills the population @@ -236,32 +274,32 @@ cuddGa( ** the results in the computed table. */ if (!make_random(table,lower)) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - for (i = 1; i < popsize; i++) { - result = build_dd(table,i,lower,upper); /* build and sift order */ - if (!result) { + table->errorCode = CUDD_MEMORY_OUT; ABC_FREE(storedd); ABC_FREE(repeat); st_free_table(computed); return(0); } - if (st_lookup(computed,(char *)&STOREDD(i,0),(char **)&index)) { - repeat[index]++; - } else { - if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == - ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + for (i = 1; i < popsize; i++) { + result = build_dd(table,i,lower,upper); /* build and sift order */ + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == + ST_OUT_OF_MEM) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[i]++; } - repeat[i]++; - } } #if 0 @@ -269,104 +307,104 @@ cuddGa( /* Print the initial population. */ (void) fprintf(table->out,"Initial population after sifting\n"); for (m = 0; m < popsize; m++) { - for (i = 0; i < numvars; i++) { - (void) fprintf(table->out," %2d",STOREDD(m,i)); - } - (void) fprintf(table->out," : %3d (%d)\n", - STOREDD(m,numvars),repeat[m]); + for (i = 0; i < numvars; i++) { + (void) fprintf(table->out," %2d",STOREDD(m,i)); + } + (void) fprintf(table->out," : %3d (%d)\n", + STOREDD(m,numvars),repeat[m]); } #endif #endif small = find_best(); - average_fitness = find_average_fitness(); #ifdef DD_STATS + average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Decide how many crossovers should be tried. */ if (table->numberXovers == 0) { - cross = 3*numvars; - if (cross > 60) { /* do a maximum of 50 crossovers */ - cross = 60; - } + cross = 3*numvars; + if (cross > 60) { /* do a maximum of 50 crossovers */ + cross = 60; + } } else { - cross = table->numberXovers; /* use user specified value */ + cross = table->numberXovers; /* use user specified value */ } /* Perform the crossovers to get the best order. */ for (m = 0; m < cross; m++) { - if (!PMX(table->size)) { /* perform one crossover */ - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - /* The offsprings are left in the last two entries of the - ** population table. These are now considered in turn. - */ - for (i = popsize; i <= popsize+1; i++) { - result = build_dd(table,i,lower,upper); /* build and sift child */ - if (!result) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - large = largest(); /* find the largest DD in population */ - - /* If the new child is smaller than the largest DD in the current - ** population, enter it into the population in place of the - ** largest DD. - */ - if (STOREDD(i,numvars) < STOREDD(large,numvars)) { - /* Look up the largest DD in the computed table. - ** Decrease its repetition count. If the repetition count - ** goes to 0, remove the largest DD from the computed table. - */ - result = st_lookup(computed,(char *)&STOREDD(large,0),(char - **)&index); - if (!result) { + if (!PMX(table->size)) { /* perform one crossover */ + table->errorCode = CUDD_MEMORY_OUT; ABC_FREE(storedd); ABC_FREE(repeat); st_free_table(computed); return(0); } - repeat[index]--; - if (repeat[index] == 0) { - int *pointer = &STOREDD(index,0); - result = st_delete(computed, (const char **)&pointer,NULL); + /* The offsprings are left in the last two entries of the + ** population table. These are now considered in turn. + */ + for (i = popsize; i <= popsize+1; i++) { + result = build_dd(table,i,lower,upper); /* build and sift child */ if (!result) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); } - } - /* Copy the new individual to the entry of the - ** population table just made available and update the - ** computed table. - */ - for (n = 0; n <= numvars; n++) { - STOREDD(large,n) = STOREDD(i,n); - } - if (st_lookup(computed,(char *)&STOREDD(large,0),(char - **)&index)) { - repeat[index]++; - } else { - if (st_insert(computed,(char *)&STOREDD(large,0), - (char *)(long)large) == ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + large = largest(); /* find the largest DD in population */ + + /* If the new child is smaller than the largest DD in the current + ** population, enter it into the population in place of the + ** largest DD. + */ + if (STOREDD(i,numvars) < STOREDD(large,numvars)) { + /* Look up the largest DD in the computed table. + ** Decrease its repetition count. If the repetition count + ** goes to 0, remove the largest DD from the computed table. + */ + result = st_lookup_int(computed,(char *)&STOREDD(large,0), + &index); + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[index]--; + if (repeat[index] == 0) { + int *pointer = &STOREDD(index,0); + result = st_delete(computed, (const char **)&pointer, NULL); + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + } + /* Copy the new individual to the entry of the + ** population table just made available and update the + ** computed table. + */ + for (n = 0; n <= numvars; n++) { + STOREDD(large,n) = STOREDD(i,n); + } + if (st_lookup_int(computed,(char *)&STOREDD(large,0), + &index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(large,0), + (char *)(long)large) == ST_OUT_OF_MEM) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[large]++; + } } - repeat[large]++; - } } } - } /* Find the smallest DD in the population and build it; ** that will be the result. @@ -412,47 +450,47 @@ make_random( DdManager * table, int lower) { - int i,j; /* loop variables */ - int *used; /* is a number already in a permutation */ - int next; /* next random number without repetitions */ + int i,j; /* loop variables */ + int *used; /* is a number already in a permutation */ + int next; /* next random number without repetitions */ used = ABC_ALLOC(int,numvars); if (used == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } #if 0 #ifdef DD_STATS (void) fprintf(table->out,"Initial population before sifting\n"); for (i = 0; i < 2; i++) { - for (j = 0; j < numvars; j++) { - (void) fprintf(table->out," %2d",STOREDD(i,j)); - } - (void) fprintf(table->out,"\n"); + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); } #endif #endif for (i = 2; i < popsize; i++) { - for (j = 0; j < numvars; j++) { - used[j] = 0; - } - /* Generate a permutation of {0...numvars-1} and use it to - ** permute the variables in the layesr from lower to upper. - */ - for (j = 0; j < numvars; j++) { - do { - next = rand_int(numvars-1); - } while (used[next] != 0); - used[next] = 1; - STOREDD(i,j) = table->invperm[next+lower]; - } + for (j = 0; j < numvars; j++) { + used[j] = 0; + } + /* Generate a permutation of {0...numvars-1} and use it to + ** permute the variables in the layesr from lower to upper. + */ + for (j = 0; j < numvars; j++) { + do { + next = rand_int(numvars-1); + } while (used[next] != 0); + used[next] = 1; + STOREDD(i,j) = table->invperm[next+lower]; + } #if 0 #ifdef DD_STATS - /* Print the order just generated. */ - for (j = 0; j < numvars; j++) { - (void) fprintf(table->out," %2d",STOREDD(i,j)); - } - (void) fprintf(table->out,"\n"); + /* Print the order just generated. */ + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); #endif #endif } @@ -486,12 +524,12 @@ sift_up( y = cuddNextLow(table,x); while (y >= x_low) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -518,21 +556,21 @@ build_dd( int lower, int upper) { - int i,j; /* loop vars */ - int position; - int index; - int limit; /* how large the DD for this order can grow */ - int size; + int i,j; /* loop vars */ + int position; + int index; + int limit; /* how large the DD for this order can grow */ + int size; /* Check the computed table. If the order already exists, it ** suffices to copy the size from the existing entry. */ - if (computed && st_lookup(computed,(char *)&STOREDD(num,0),(char **)&index)) { - STOREDD(num,numvars) = STOREDD(index,numvars); + if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { + STOREDD(num,numvars) = STOREDD(index,numvars); #ifdef DD_STATS - (void) fprintf(table->out,"\nCache hit for index %d", index); + (void) fprintf(table->out,"\nCache hit for index %d", index); #endif - return(1); + return(1); } /* Stop if the DD grows 20 times larges than the reference size. */ @@ -544,12 +582,12 @@ build_dd( ** up to the second position, and so on. */ for (j = 0; j < numvars; j++) { - i = STOREDD(num,j); - position = table->perm[i]; - result = sift_up(table,position,j+lower); - if (!result) return(0); - size = table->keys - table->isolated; - if (size > limit) break; + i = STOREDD(num,j); + position = table->perm[i]; + result = sift_up(table,position,j+lower); + if (!result) return(0); + size = table->keys - table->isolated; + if (size > limit) break; } /* Sift the DD just built. */ @@ -561,7 +599,7 @@ build_dd( /* Copy order and size to table. */ for (j = 0; j < numvars; j++) { - STOREDD(num,j) = table->invperm[lower+j]; + STOREDD(num,j) = table->invperm[lower+j]; } STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ return(1); @@ -583,18 +621,17 @@ build_dd( ******************************************************************************/ static int -largest( - ) +largest(void) { - int i; /* loop var */ + int i; /* loop var */ int big; /* temporary holder to return result */ big = 0; while (repeat[big] > 1) big++; for (i = big + 1; i < popsize; i++) { - if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { - big = i; - } + if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { + big = i; + } } return(big); @@ -640,12 +677,12 @@ array_hash( { int val = 0; int i; - const int *intarray; + int *intarray; - intarray = (const int *) array; + intarray = (int *) array; for (i = 0; i < numvars; i++) { - val = val * 997 + intarray[i]; + val = val * 997 + intarray[i]; } return ((val < 0) ? -val : val) % modulus; @@ -677,7 +714,7 @@ array_compare( intarray2 = (int *) array2; for (i = 0; i < numvars; i++) { - if (intarray1[i] != intarray2[i]) return(1); + if (intarray1[i] != intarray2[i]) return(1); } return(0); @@ -696,16 +733,15 @@ array_compare( ******************************************************************************/ static int -find_best( - ) +find_best(void) { int i,small; small = 0; for (i = 1; i < popsize; i++) { - if (STOREDD(i,numvars) < STOREDD(small,numvars)) { - small = i; - } + if (STOREDD(i,numvars) < STOREDD(small,numvars)) { + small = i; + } } return(small); @@ -723,21 +759,22 @@ find_best( SeeAlso [] ******************************************************************************/ +#ifdef DD_STATS static double -find_average_fitness( - ) +find_average_fitness(void) { int i; int total_fitness = 0; double average_fitness; for (i = 0; i < popsize; i++) { - total_fitness += STOREDD(i,numvars); + total_fitness += STOREDD(i,numvars); } average_fitness = (double) total_fitness / (double) popsize; return(average_fitness); } /* end of find_average_fitness */ +#endif /**Function******************************************************************** @@ -757,28 +794,28 @@ static int PMX( int maxvar) { - int cut1,cut2; /* the two cut positions (random) */ - int mom,dad; /* the two randomly chosen parents */ - int *inv1; /* inverse permutations for repair algo */ - int *inv2; - int i; /* loop vars */ - int u,v; /* aux vars */ + int cut1,cut2; /* the two cut positions (random) */ + int mom,dad; /* the two randomly chosen parents */ + int *inv1; /* inverse permutations for repair algo */ + int *inv2; + int i; /* loop vars */ + int u,v; /* aux vars */ inv1 = ABC_ALLOC(int,maxvar); if (inv1 == NULL) { - return(0); + return(0); } inv2 = ABC_ALLOC(int,maxvar); if (inv2 == NULL) { - ABC_FREE(inv1); - return(0); + ABC_FREE(inv1); + return(0); } /* Choose two orders from the population using roulette wheel. */ if (!roulette(&mom,&dad)) { - ABC_FREE(inv1); - ABC_FREE(inv2); - return(0); + ABC_FREE(inv1); + ABC_FREE(inv2); + return(0); } /* Choose two random cut positions. A cut in position i means that @@ -788,68 +825,68 @@ PMX( */ cut1 = rand_int(numvars-1); do { - cut2 = rand_int(numvars-1); + cut2 = rand_int(numvars-1); } while (cut1 == cut2); #if 0 /* Print out the parents. */ (void) fprintf(table->out, - "Crossover of %d (mom) and %d (dad) between %d and %d\n", - mom,dad,cut1,cut2); + "Crossover of %d (mom) and %d (dad) between %d and %d\n", + mom,dad,cut1,cut2); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); } (void) fprintf(table->out,"\n"); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); } (void) fprintf(table->out,"\n"); #endif /* Initialize the inverse permutations: -1 means yet undetermined. */ for (i = 0; i < maxvar; i++) { - inv1[i] = -1; - inv2[i] = -1; + inv1[i] = -1; + inv2[i] = -1; } /* Copy the portions whithin the cuts. */ for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) { - STOREDD(popsize,i) = STOREDD(dad,i); - inv1[STOREDD(popsize,i)] = i; - STOREDD(popsize+1,i) = STOREDD(mom,i); - inv2[STOREDD(popsize+1,i)] = i; + STOREDD(popsize,i) = STOREDD(dad,i); + inv1[STOREDD(popsize,i)] = i; + STOREDD(popsize+1,i) = STOREDD(mom,i); + inv2[STOREDD(popsize+1,i)] = i; } /* Now apply the repair algorithm outside the cuts. */ for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) { - v = i; - do { - u = STOREDD(mom,v); - v = inv1[u]; - } while (v != -1); - STOREDD(popsize,i) = u; - inv1[u] = i; - v = i; - do { - u = STOREDD(dad,v); - v = inv2[u]; - } while (v != -1); - STOREDD(popsize+1,i) = u; - inv2[u] = i; + v = i; + do { + u = STOREDD(mom,v); + v = inv1[u]; + } while (v != -1); + STOREDD(popsize,i) = u; + inv1[u] = i; + v = i; + do { + u = STOREDD(dad,v); + v = inv2[u]; + } while (v != -1); + STOREDD(popsize+1,i) = u; + inv2[u] = i; } #if 0 /* Print the results of crossover. */ for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); } (void) fprintf(table->out,"\n"); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); } (void) fprintf(table->out,"\n"); #endif @@ -884,14 +921,14 @@ roulette( wheel = ABC_ALLOC(double,popsize); if (wheel == NULL) { - return(0); + return(0); } /* The fitness of an individual is the reciprocal of its size. */ wheel[0] = 1.0 / (double) STOREDD(0,numvars); for (i = 1; i < popsize; i++) { - wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); + wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); } /* Get a random number between 0 and wheel[popsize-1] (that is, @@ -902,7 +939,7 @@ roulette( /* Find the lucky element by scanning the wheel. */ for (i = 0; i < popsize; i++) { - if (spin <= wheel[i]) break; + if (spin <= wheel[i]) break; } *p1 = i; @@ -910,10 +947,10 @@ roulette( ** distinct from the first. */ do { - spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; - for (i = 0; i < popsize; i++) { - if (spin <= wheel[i]) break; - } + spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } } while (i == *p1); *p2 = i; @@ -922,5 +959,7 @@ roulette( } /* end of roulette */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddGroup.c b/src/bdd/cudd/cuddGroup.c index 8e637603..fc848259 100644 --- a/src/bdd/cudd/cuddGroup.c +++ b/src/bdd/cudd/cuddGroup.c @@ -7,45 +7,72 @@ Synopsis [Functions for group sifting.] Description [External procedures included in this file: - <ul> - <li> Cudd_MakeTreeNode() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddTreeSifting() - </ul> - Static procedures included in this module: - <ul> - <li> ddTreeSiftingAux() - <li> ddCountInternalMtrNodes() - <li> ddReorderChildren() - <li> ddFindNodeHiLo() - <li> ddUniqueCompareGroup() - <li> ddGroupSifting() - <li> ddCreateGroup() - <li> ddGroupSiftingAux() - <li> ddGroupSiftingUp() - <li> ddGroupSiftingDown() - <li> ddGroupMove() - <li> ddGroupMoveBackward() - <li> ddGroupSiftingBackward() - <li> ddMergeGroups() - <li> ddDissolveGroup() - <li> ddNoCheck() - <li> ddSecDiffCheck() - <li> ddExtSymmCheck() - <li> ddVarGroupCheck() - <li> ddSetVarHandled() - <li> ddResetVarHandled() - <li> ddIsVarHandled() - </ul>] + <ul> + <li> Cudd_MakeTreeNode() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddTreeSifting() + </ul> + Static procedures included in this module: + <ul> + <li> ddTreeSiftingAux() + <li> ddCountInternalMtrNodes() + <li> ddReorderChildren() + <li> ddFindNodeHiLo() + <li> ddUniqueCompareGroup() + <li> ddGroupSifting() + <li> ddCreateGroup() + <li> ddGroupSiftingAux() + <li> ddGroupSiftingUp() + <li> ddGroupSiftingDown() + <li> ddGroupMove() + <li> ddGroupMoveBackward() + <li> ddGroupSiftingBackward() + <li> ddMergeGroups() + <li> ddDissolveGroup() + <li> ddNoCheck() + <li> ddSecDiffCheck() + <li> ddExtSymmCheck() + <li> ddVarGroupCheck() + <li> ddSetVarHandled() + <li> ddResetVarHandled() + <li> ddIsVarHandled() + </ul>] Author [Shipra Panda, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -55,17 +82,18 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ /* Constants for lazy sifting */ -#define DD_NORMAL_SIFT 0 -#define DD_LAZY_SIFT 1 +#define DD_NORMAL_SIFT 0 +#define DD_LAZY_SIFT 1 /* Constants for sifting up and down */ -#define DD_SIFT_DOWN 0 -#define DD_SIFT_UP 1 +#define DD_SIFT_DOWN 0 +#define DD_SIFT_UP 1 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -75,18 +103,26 @@ ABC_NAMESPACE_IMPL_START /* Type declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + typedef int (*DD_CHKFP)(DdManager *, int, int); +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.44 2009/02/21 18:24:10 fabio Exp $"; #endif -static int *entry; -extern int ddTotalNumberSwapping; +static int *entry; +extern int ddTotalNumberSwapping; #ifdef DD_STATS -extern int ddTotalNISwaps; +extern int ddTotalNISwaps; static int extsymmcalls; static int extsymm; static int secdiffcalls; @@ -94,49 +130,55 @@ static int secdiff; static int secdiffmisfire; #endif #ifdef DD_DEBUG -static int pr = 0; /* flag to enable printing while debugging */ - /* by depositing a 1 into it */ +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ #endif -static int originalSize; -static int originalLevel; +static unsigned int originalSize; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method, int TimeStop)); +static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); #ifdef DD_STATS -static int ddCountInternalMtrNodes ARGS((DdManager *table, MtrNode *treenode)); +static int ddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); #endif -static int ddReorderChildren ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method, int TimeStop)); -static void ddFindNodeHiLo ARGS((DdManager *table, MtrNode *treenode, int *lower, int *upper)); -static int ddUniqueCompareGroup ARGS((int *ptrX, int *ptrY)); -static int ddGroupSifting ARGS((DdManager *table, int lower, int upper, int (*checkFunction)(DdManager *, int, int), int lazyFlag)); -static void ddCreateGroup ARGS((DdManager *table, int x, int y)); -static int ddGroupSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh, int (*checkFunction)(DdManager *, int, int), int lazyFlag)); -static int ddGroupSiftingUp ARGS((DdManager *table, int y, int xLow, int (*checkFunction)(DdManager *, int, int), Move **moves)); -static int ddGroupSiftingDown ARGS((DdManager *table, int x, int xHigh, int (*checkFunction)(DdManager *, int, int), Move **moves)); -static int ddGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int ddGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int ddGroupSiftingBackward ARGS((DdManager *table, Move *moves, int size, int upFlag, int lazyFlag)); -static void ddMergeGroups ARGS((DdManager *table, MtrNode *treenode, int low, int high)); -static void ddDissolveGroup ARGS((DdManager *table, int x, int y)); -static int ddNoCheck ARGS((DdManager *table, int x, int y)); -static int ddSecDiffCheck ARGS((DdManager *table, int x, int y)); -static int ddExtSymmCheck ARGS((DdManager *table, int x, int y)); -static int ddVarGroupCheck ARGS((DdManager * table, int x, int y)); -static int ddSetVarHandled ARGS((DdManager *dd, int index)); -static int ddResetVarHandled ARGS((DdManager *dd, int index)); -static int ddIsVarHandled ARGS((DdManager *dd, int index)); +static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int ddUniqueCompareGroup (int *ptrX, int *ptrY); +static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag); +static void ddCreateGroup (DdManager *table, int x, int y); +static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag); +static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves); +static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves); +static int ddGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddGroupMoveBackward (DdManager *table, int x, int y); +static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag); +static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); +static void ddDissolveGroup (DdManager *table, int x, int y); +static int ddNoCheck (DdManager *table, int x, int y); +static int ddSecDiffCheck (DdManager *table, int x, int y); +static int ddExtSymmCheck (DdManager *table, int x, int y); +static int ddVarGroupCheck (DdManager * table, int x, int y); +static int ddSetVarHandled (DdManager *dd, int index); +static int ddResetVarHandled (DdManager *dd, int index); +static int ddIsVarHandled (DdManager *dd, int index); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -179,15 +221,15 @@ Cudd_MakeTreeNode( level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; if (level + size - 1> (int) MTR_MAXHIGH) - return(NULL); + return(NULL); /* If the tree does not exist yet, create it. */ tree = dd->tree; if (tree == NULL) { - dd->tree = tree = Mtr_InitGroupTree(0, dd->size); - if (tree == NULL) - return(NULL); - tree->index = dd->invperm[0]; + dd->tree = tree = Mtr_InitGroupTree(0, dd->size); + if (tree == NULL) + return(NULL); + tree->index = dd->invperm[0]; } /* Extend the upper bound of the tree if necessary. This allows the @@ -198,7 +240,7 @@ Cudd_MakeTreeNode( /* Create the group. */ group = Mtr_MakeGroup(tree, level, size, type); if (group == NULL) - return(NULL); + return(NULL); /* Initialize the index field to the index of the variable currently ** in position low. This field will be updated by the reordering @@ -231,8 +273,7 @@ Cudd_MakeTreeNode( int cuddTreeSifting( DdManager * table /* DD table */, - Cudd_ReorderingType method /* reordering method for the groups of leaves */, - int TimeStop) + Cudd_ReorderingType method /* reordering method for the groups of leaves */) { int i; int nvars; @@ -245,8 +286,8 @@ cuddTreeSifting( */ tempTree = table->tree == NULL; if (tempTree) { - table->tree = Mtr_InitGroupTree(0,table->size); - table->tree->index = table->invperm[0]; + table->tree = Mtr_InitGroupTree(0,table->size); + table->tree->index = table->invperm[0]; } nvars = table->size; @@ -264,8 +305,8 @@ cuddTreeSifting( (void) fprintf(table->out,"\n"); if (!tempTree) - (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", - ddCountInternalMtrNodes(table,table->tree)); + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + ddCountInternalMtrNodes(table,table->tree)); #endif /* Initialize the group of each subtable to itself. Initially @@ -277,25 +318,25 @@ cuddTreeSifting( /* Reorder. */ - result = ddTreeSiftingAux(table, table->tree, method, TimeStop); + result = ddTreeSiftingAux(table, table->tree, method); -#ifdef DD_STATS /* print stats */ +#ifdef DD_STATS /* print stats */ if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - (table->groupcheck == CUDD_GROUP_CHECK7 || - table->groupcheck == CUDD_GROUP_CHECK5)) { - (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); - (void) fprintf(table->out,"extsymm = %d",extsymm); + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); } if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - table->groupcheck == CUDD_GROUP_CHECK7) { - (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); - (void) fprintf(table->out,"secdiff = %d\n",secdiff); - (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); } #endif if (tempTree) - Cudd_FreeTree(table); + Cudd_FreeTree(table); return(result); } /* end of cuddTreeSifting */ @@ -320,8 +361,7 @@ static int ddTreeSiftingAux( DdManager * table, MtrNode * treenode, - Cudd_ReorderingType method, - int TimeStop) + Cudd_ReorderingType method) { MtrNode *auxnode; int res; @@ -333,24 +373,24 @@ ddTreeSiftingAux( auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - if (!ddTreeSiftingAux(table, auxnode->child, method, TimeStop)) - return(0); - saveCheck = table->groupcheck; - table->groupcheck = CUDD_NO_CHECK; - if (method != CUDD_REORDER_LAZY_SIFT) - res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT, TimeStop); - else - res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT, TimeStop); - table->groupcheck = saveCheck; - - if (res == 0) - return(0); - } else if (auxnode->size > 1) { - if (!ddReorderChildren(table, auxnode, method, TimeStop)) - return(0); - } - auxnode = auxnode->younger; + if (auxnode->child != NULL) { + if (!ddTreeSiftingAux(table, auxnode->child, method)) + return(0); + saveCheck = table->groupcheck; + table->groupcheck = CUDD_NO_CHECK; + if (method != CUDD_REORDER_LAZY_SIFT) + res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + else + res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT); + table->groupcheck = saveCheck; + + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!ddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; } return(1); @@ -381,12 +421,12 @@ ddCountInternalMtrNodes( nodeCount = 0; auxnode = treenode; while (auxnode != NULL) { - if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { - nodeCount++; - count = ddCountInternalMtrNodes(table,auxnode->child); - nodeCount += count; - } - auxnode = auxnode->younger; + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = ddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; } return(nodeCount); @@ -413,8 +453,7 @@ static int ddReorderChildren( DdManager * table, MtrNode * treenode, - Cudd_ReorderingType method, - int TimeStop) + Cudd_ReorderingType method) { int lower; int upper; @@ -424,125 +463,125 @@ ddReorderChildren( ddFindNodeHiLo(table,treenode,&lower,&upper); /* If upper == -1 these variables do not exist yet. */ if (upper == -1) - return(1); + return(1); if (treenode->flags == MTR_FIXED) { - result = 1; + result = 1; } else { #ifdef DD_STATS - (void) fprintf(table->out," "); + (void) fprintf(table->out," "); #endif - switch (method) { - case CUDD_REORDER_RANDOM: - case CUDD_REORDER_RANDOM_PIVOT: - result = cuddSwapping(table,lower,upper,method); - break; - case CUDD_REORDER_SIFT: - result = cuddSifting(table,lower,upper); - break; - case CUDD_REORDER_SIFT_CONVERGE: - do { - initialSize = table->keys - table->isolated; - result = cuddSifting(table,lower,upper); - if (initialSize <= table->keys - table->isolated) + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddSwapping(table,lower,upper,method); break; + case CUDD_REORDER_SIFT: + result = cuddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_SYMM_SIFT: - result = cuddSymmSifting(table,lower,upper,TimeStop); - break; - case CUDD_REORDER_SYMM_SIFT_CONV: - result = cuddSymmSiftingConv(table,lower,upper); - break; - case CUDD_REORDER_GROUP_SIFT: - if (table->groupcheck == CUDD_NO_CHECK) { - result = ddGroupSifting(table,lower,upper,ddNoCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK5) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK7) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else { - (void) fprintf(table->err, - "Unknown group ckecking method\n"); - result = 0; - } - break; - case CUDD_REORDER_GROUP_SIFT_CONV: - do { - initialSize = table->keys - table->isolated; - if (table->groupcheck == CUDD_NO_CHECK) { - result = ddGroupSifting(table,lower,upper,ddNoCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK5) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK7) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else { - (void) fprintf(table->err, - "Unknown group ckecking method\n"); - result = 0; - } + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } + break; + case CUDD_REORDER_GROUP_SIFT_CONV: + do { + initialSize = table->keys - table->isolated; + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif - result = cuddWindowReorder(table,lower,upper, - CUDD_REORDER_WINDOW4); - if (initialSize <= table->keys - table->isolated) - break; + result = cuddWindowReorder(table,lower,upper, + CUDD_REORDER_WINDOW4); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_WINDOW2: - case CUDD_REORDER_WINDOW3: - case CUDD_REORDER_WINDOW4: - case CUDD_REORDER_WINDOW2_CONV: - case CUDD_REORDER_WINDOW3_CONV: - case CUDD_REORDER_WINDOW4_CONV: - result = cuddWindowReorder(table,lower,upper,method); - break; - case CUDD_REORDER_ANNEALING: - result = cuddAnnealing(table,lower,upper); - break; - case CUDD_REORDER_GENETIC: - result = cuddGa(table,lower,upper); - break; - case CUDD_REORDER_LINEAR: - result = cuddLinearAndSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR_CONVERGE: - do { - initialSize = table->keys - table->isolated; - result = cuddLinearAndSifting(table,lower,upper); - if (initialSize <= table->keys - table->isolated) + } while (result != 0); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + result = cuddWindowReorder(table,lower,upper,method); break; + case CUDD_REORDER_ANNEALING: + result = cuddAnnealing(table,lower,upper); + break; + case CUDD_REORDER_GENETIC: + result = cuddGa(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddLinearAndSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddLinearAndSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_EXACT: - result = cuddExact(table,lower,upper); - break; - case CUDD_REORDER_LAZY_SIFT: - result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, - DD_LAZY_SIFT); - break; - default: - return(0); - } + } while (result != 0); + break; + case CUDD_REORDER_EXACT: + result = cuddExact(table,lower,upper); + break; + case CUDD_REORDER_LAZY_SIFT: + result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, + DD_LAZY_SIFT); + break; + default: + return(0); + } } /* Create a single group for all the variables that were sifted, @@ -589,42 +628,42 @@ ddFindNodeHiLo( ** the values of upper that no reordering is needed. */ if ((int) treenode->low >= table->size) { - *lower = table->size; - *upper = -1; - return; + *lower = table->size; + *upper = -1; + return; } *lower = low = (unsigned int) table->perm[treenode->index]; high = (int) (low + treenode->size - 1); if (high >= table->size) { - /* This is the case of a partially existing group. The aim is to - ** reorder as many variables as safely possible. If the tree - ** node is terminal, we just reorder the subset of the group - ** that is currently in existence. If the group has - ** subgroups, then we only reorder those subgroups that are - ** fully instantiated. This way we avoid breaking up a group. - */ - MtrNode *auxnode = treenode->child; - if (auxnode == NULL) { - *upper = (unsigned int) table->size - 1; - } else { - /* Search the subgroup that strands the table->size line. - ** If the first group starts at 0 and goes past table->size - ** upper will get -1, thus correctly signaling that no reordering - ** should take place. + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. */ - while (auxnode != NULL) { - int thisLower = table->perm[auxnode->low]; - int thisUpper = thisLower + auxnode->size - 1; - if (thisUpper >= table->size && thisLower < table->size) - *upper = (unsigned int) thisLower - 1; - auxnode = auxnode->younger; + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->size - 1; + } else { + /* Search the subgroup that strands the table->size line. + ** If the first group starts at 0 and goes past table->size + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->perm[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->size && thisLower < table->size) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } } - } } else { - /* Normal case: All the variables of the group exist. */ - *upper = (unsigned int) high; + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; } #ifdef DD_DEBUG @@ -656,7 +695,7 @@ ddUniqueCompareGroup( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -682,21 +721,21 @@ ddGroupSifting( DdManager * table, int lower, int upper, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, int lazyFlag) { - int *var; - int i,j,x,xInit; - int nvars; - int classes; - int result; - int *sifted; - int merged; - int dissolve; + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; + int merged; + int dissolve; #ifdef DD_STATS unsigned previousSize; #endif - int xindex; + int xindex; nvars = table->size; @@ -705,140 +744,140 @@ ddGroupSifting( sifted = NULL; var = ABC_ALLOC(int,nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } entry = ABC_ALLOC(int,nvars); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } sifted = ABC_ALLOC(int,nvars); if (sifted == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } /* Here we consider only one representative for each group. */ for (i = 0, classes = 0; i < nvars; i++) { - sifted[i] = 0; - x = table->perm[i]; - if ((unsigned) x >= table->subtables[x].next) { - entry[i] = table->subtables[x].keys; - var[classes] = i; - classes++; - } + sifted[i] = 0; + x = table->perm[i]; + if ((unsigned) x >= table->subtables[x].next) { + entry[i] = table->subtables[x].keys; + var[classes] = i; + classes++; + } } qsort((void *)var,classes,sizeof(int), - (int (*)(const void *, const void *)) ddUniqueCompareGroup); + (DD_QSFP) ddUniqueCompareGroup); if (lazyFlag) { - for (i = 0; i < nvars; i ++) { - ddResetVarHandled(table, i); - } + for (i = 0; i < nvars; i ++) { + ddResetVarHandled(table, i); + } } /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - xindex = var[i]; - if (sifted[xindex] == 1) /* variable already sifted as part of group */ - continue; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; x = table->perm[xindex]; /* find current level of this variable */ - if (x < lower || x > upper || table->subtables[x].bindVar == 1) - continue; + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtables[x].next); #endif - if ((unsigned) x == table->subtables[x].next) { - dissolve = 1; - result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, - lazyFlag); - } else { - dissolve = 0; - result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); - } - if (!result) goto ddGroupSiftingOutOfMem; - - /* check for aggregation */ - merged = 0; - if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { - x = table->perm[xindex]; /* find current level */ - if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ - if (x != upper && sifted[table->invperm[x+1]] == 0 && - (unsigned) x+1 == table->subtables[x+1].next) { - if (ddSecDiffCheck(table,x,x+1)) { - merged =1; - ddCreateGroup(table,x,x+1); - } + if ((unsigned) x == table->subtables[x].next) { + dissolve = 1; + result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, + lazyFlag); + } else { + dissolve = 0; + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); } - if (x != lower && sifted[table->invperm[x-1]] == 0 && - (unsigned) x-1 == table->subtables[x-1].next) { - if (ddSecDiffCheck(table,x-1,x)) { - merged =1; - ddCreateGroup(table,x-1,x); + if (!result) goto ddGroupSiftingOutOfMem; + + /* check for aggregation */ + merged = 0; + if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { + x = table->perm[xindex]; /* find current level */ + if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ + if (x != upper && sifted[table->invperm[x+1]] == 0 && + (unsigned) x+1 == table->subtables[x+1].next) { + if (ddSecDiffCheck(table,x,x+1)) { + merged =1; + ddCreateGroup(table,x,x+1); + } + } + if (x != lower && sifted[table->invperm[x-1]] == 0 && + (unsigned) x-1 == table->subtables[x-1].next) { + if (ddSecDiffCheck(table,x-1,x)) { + merged =1; + ddCreateGroup(table,x-1,x); + } + } } } - } - } - if (merged) { /* a group was created */ - /* move x to bottom of group */ - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - /* sift */ - result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); - if (!result) goto ddGroupSiftingOutOfMem; + if (merged) { /* a group was created */ + /* move x to bottom of group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + /* sift */ + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + if (!result) goto ddGroupSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < previousSize + table->isolated) { - (void) fprintf(table->out,"_"); - } else if (table->keys > previousSize + table->isolated) { - (void) fprintf(table->out,"^"); - } else { - (void) fprintf(table->out,"*"); - } - fflush(table->out); - } else { - if (table->keys < previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > previousSize + table->isolated) { - (void) fprintf(table->out,"+"); + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"_"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"^"); + } else { + (void) fprintf(table->out,"*"); + } + fflush(table->out); } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } - /* Mark variables in the group just sifted. */ - x = table->perm[xindex]; - if ((unsigned) x != table->subtables[x].next) { - xInit = x; - do { - j = table->invperm[x]; - sifted[j] = 1; - x = table->subtables[x].next; - } while (x != xInit); - - /* Dissolve the group if it was created. */ - if (lazyFlag == 0 && dissolve) { - do { - j = table->subtables[x].next; - table->subtables[x].next = x; - x = j; - } while (x != xInit); + /* Mark variables in the group just sifted. */ + x = table->perm[xindex]; + if ((unsigned) x != table->subtables[x].next) { + xInit = x; + do { + j = table->invperm[x]; + sifted[j] = 1; + x = table->subtables[x].next; + } while (x != xInit); + + /* Dissolve the group if it was created. */ + if (lazyFlag == 0 && dissolve) { + do { + j = table->subtables[x].next; + table->subtables[x].next = x; + x = j; + } while (x != xInit); + } } - } #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); + if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); #endif if (lazyFlag) ddSetVarHandled(table, xindex); @@ -851,9 +890,9 @@ ddGroupSifting( return(1); ddGroupSiftingOutOfMem: - if (entry != NULL) ABC_FREE(entry); + if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - if (sifted != NULL) ABC_FREE(sifted); + if (sifted != NULL) ABC_FREE(sifted); return(0); @@ -887,7 +926,7 @@ ddCreateGroup( /* Find bottom of second group. */ gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; /* Link groups. */ table->subtables[x].next = y; @@ -919,11 +958,11 @@ ddGroupSiftingAux( int x, int xLow, int xHigh, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, int lazyFlag) { Move *move; - Move *moves; /* list of moves */ + Move *moves; /* list of moves */ int initialSize; int result; int y; @@ -931,78 +970,76 @@ ddGroupSiftingAux( #ifdef DD_DEBUG if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); + "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */ #endif initialSize = table->keys - table->isolated; moves = NULL; - originalSize = initialSize; /* for lazy sifting */ + originalSize = initialSize; /* for lazy sifting */ /* If we have a singleton, we check for aggregation in both ** directions before we sift. */ if ((unsigned) x == table->subtables[x].next) { - /* Will go down first, unless x == xHigh: - ** Look for aggregation above x. - */ - for (y = x; y > xLow; y--) { - if (!checkFunction(table,y-1,y)) - break; - topbot = table->subtables[y-1].next; /* find top of y-1's group */ - table->subtables[y-1].next = y; - table->subtables[x].next = topbot; /* x is bottom of group so its */ - /* next is top of y-1's group */ - y = topbot + 1; /* add 1 for y--; new y is top of group */ - } - /* Will go up first unless x == xlow: - ** Look for aggregation below x. - */ - for (y = x; y < xHigh; y++) { - if (!checkFunction(table,y,y+1)) - break; - /* find bottom of y+1's group */ - topbot = y + 1; - while ((unsigned) topbot < table->subtables[topbot].next) { - topbot = table->subtables[topbot].next; + /* Will go down first, unless x == xHigh: + ** Look for aggregation above x. + */ + for (y = x; y > xLow; y--) { + if (!checkFunction(table,y-1,y)) + break; + topbot = table->subtables[y-1].next; /* find top of y-1's group */ + table->subtables[y-1].next = y; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of y-1's group */ + y = topbot + 1; /* add 1 for y--; new y is top of group */ + } + /* Will go up first unless x == xlow: + ** Look for aggregation below x. + */ + for (y = x; y < xHigh; y++) { + if (!checkFunction(table,y,y+1)) + break; + /* find bottom of y+1's group */ + topbot = y + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[y].next; + table->subtables[y].next = y + 1; + y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ } - table->subtables[topbot].next = table->subtables[y].next; - table->subtables[y].next = y + 1; - y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ - } } /* Now x may be in the middle of a group. ** Find bottom of x's group. */ while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - - originalLevel = x; /* for lazy sifting */ + x = table->subtables[x].next; if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtables[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_DOWN,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtables[x].next); #endif /* Find top of x's group */ @@ -1010,28 +1047,28 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xLow, unless early term */ + /* at this point x == xLow, unless early term */ - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_UP,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ /* Find top of group */ - if (moves) { - x = moves->y; - } - while ((unsigned) x < table->subtables[x].next) + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; x = table->subtables[x].next; - x = table->subtables[x].next; #ifdef DD_DEBUG /* x should be the top of a group */ assert((unsigned) x <= table->subtables[x].next); @@ -1040,11 +1077,11 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_UP,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; @@ -1054,13 +1091,13 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ if (moves) { - x = moves->x; - } - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; + x = moves->x; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; #ifdef DD_DEBUG /* x is bottom of a group */ assert((unsigned) x >= table->subtables[x].next); @@ -1069,18 +1106,18 @@ ddGroupSiftingAux( if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_DOWN,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -1089,7 +1126,7 @@ ddGroupSiftingAux( ddGroupSiftingAuxOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -1118,7 +1155,7 @@ ddGroupSiftingUp( DdManager * table, int y, int xLow, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, Move ** moves) { Move *move; @@ -1131,7 +1168,7 @@ ddGroupSiftingUp( int zindex; int z; int isolated; - int L; /* lower bound on DD size */ + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; #endif @@ -1150,99 +1187,97 @@ ddGroupSiftingUp( limitSize = L = table->keys - table->isolated; gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L -= table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } } - originalLevel = y; /* for lazy sifting */ - x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { #ifdef DD_DEBUG - gybot = y; - while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; - checkL = table->keys - table->isolated; - for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + if (pr > 0 && L != checkL) { + (void) fprintf(table->out, + "Inaccurate lower bound: L = %d checkL = %d\n", + L, checkL); } - } - if (pr > 0 && L != checkL) { - (void) fprintf(table->out, - "Inaccurate lower bound: L = %d checkL = %d\n", - L, checkL); - } #endif gxtop = table->subtables[x].next; if (checkFunction(table,x,y)) { - /* Group found, attach groups */ - table->subtables[x].next = y; - i = table->subtables[y].next; - while (table->subtables[i].next != (unsigned) y) - i = table->subtables[i].next; - table->subtables[i].next = gxtop; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddGroupSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->flags = MTR_NEWNODE; - move->size = table->keys - table->isolated; - move->next = *moves; - *moves = move; + /* Group found, attach groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { + table->subtables[y].next == (unsigned) y) { /* x and y are self groups */ - xindex = table->invperm[x]; + xindex = table->invperm[x]; size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtables[x].next == (unsigned) x); assert(table->subtables[y].next == (unsigned) y); #endif if (size == 0) goto ddGroupSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) goto ddGroupSiftingUpOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingUp (2 single groups):\n"); + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingUp (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } else { /* Group move */ size = ddGroupMove(table,x,y,moves); - if (size == 0) goto ddGroupSiftingUpOutOfMem; - /* Update the lower bound. */ - z = (*moves)->y; - do { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L += table->subtables[z].keys - isolated; - } - z = table->subtables[z].next; - } while (z != (int) (*moves)->y); + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + z = (*moves)->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) (*moves)->y); if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } y = gxtop; @@ -1254,7 +1289,7 @@ ddGroupSiftingUp( ddGroupSiftingUpOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1278,7 +1313,7 @@ ddGroupSiftingDown( DdManager * table, int x, int xHigh, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, Move ** moves) { Move *move; @@ -1286,7 +1321,7 @@ ddGroupSiftingDown( int size; int limitSize; int gxtop,gybot; - int R; /* upper bound on node decrease */ + int R; /* upper bound on node decrease */ int xindex, yindex; int isolated, allVars; int z; @@ -1303,71 +1338,69 @@ ddGroupSiftingDown( y = x; allVars = 1; do { - if (table->subtables[y].keys != 1) { - allVars = 0; - break; - } - y = table->subtables[y].next; + if (table->subtables[y].keys != 1) { + allVars = 0; + break; + } + y = table->subtables[y].next; } while (table->subtables[y].next != (unsigned) x); if (allVars) - return(1); - + return(1); + /* Initialize R. */ xindex = table->invperm[x]; gxtop = table->subtables[x].next; limitSize = size = table->keys - table->isolated; R = 0; for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } } - originalLevel = x; /* for lazy sifting */ - y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - gxtop = table->subtables[x].next; - checkR = 0; - for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - } - assert(R >= checkR); + assert(R >= checkR); #endif - /* Find bottom of y group. */ + /* Find bottom of y group. */ gybot = table->subtables[y].next; while (table->subtables[gybot].next != (unsigned) y) gybot = table->subtables[gybot].next; if (checkFunction(table,x,y)) { - /* Group found: attach groups and record move. */ - gxtop = table->subtables[x].next; - table->subtables[x].next = y; - table->subtables[gybot].next = gxtop; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddGroupSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->flags = MTR_NEWNODE; - move->size = table->keys - table->isolated; - move->next = *moves; - *moves = move; + /* Group found: attach groups and record move. */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { + table->subtables[y].next == (unsigned) y) { /* x and y are self groups */ - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtables[x].next == (unsigned) x); @@ -1375,19 +1408,19 @@ ddGroupSiftingDown( #endif if (size == 0) goto ddGroupSiftingDownOutOfMem; - /* Record move. */ + /* Record move. */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) goto ddGroupSiftingDownOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingDown (2 single groups):\n"); + "ddGroupSiftingDown (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) return(1); @@ -1396,32 +1429,32 @@ ddGroupSiftingDown( x = y; y = cuddNextHigh(table,x); } else { /* Group move */ - /* Update upper bound on node decrease: first phase. */ - gxtop = table->subtables[x].next; - z = gxtop + 1; - do { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R -= table->subtables[z].keys - isolated; - } - z++; - } while (z <= gybot); + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); size = ddGroupMove(table,x,y,moves); if (size == 0) goto ddGroupSiftingDownOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; - /* Update upper bound on node decrease: second phase. */ - gxtop = table->subtables[gybot].next; - for (z = gxtop + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } - } + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } } x = gybot; y = cuddNextHigh(table,x); @@ -1432,7 +1465,7 @@ ddGroupSiftingDown( ddGroupSiftingDownOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } @@ -1461,12 +1494,12 @@ ddGroupMove( Move *move; int size; int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx=-1,swapy=-1; // Suppress "might be used uninitialized" + int swapx,swapy; #if defined(DD_DEBUG) && defined(DD_VERBOSE) int initialSize,bestSize; #endif -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1489,8 +1522,8 @@ ddGroupMove( size = cuddSwapInPlace(table,x,y); if (size == 0) goto ddGroupMoveOutOfMem; #if defined(DD_DEBUG) && defined(DD_VERBOSE) - if (size < bestSize) - bestSize = size; + if (size < bestSize) + bestSize = size; #endif swapx = x; swapy = y; y = x; @@ -1501,7 +1534,7 @@ ddGroupMove( } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if ((bestSize < initialSize) && (bestSize < size)) - (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); #endif /* fix groups */ @@ -1539,7 +1572,7 @@ ddGroupMove( ddGroupMoveOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1567,7 +1600,7 @@ ddGroupMoveBackward( int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1636,73 +1669,75 @@ ddGroupSiftingBackward( DdManager * table, Move * moves, int size, - int upFlag, + int upFlag, int lazyFlag) { Move *move; int res; - Move *end_move = NULL; + Move *end_move; int diff, tmp_diff; - int index, pairlev; + int index; + unsigned int pairlev; if (lazyFlag) { - end_move = NULL; + end_move = NULL; - /* Find the minimum size, and the earliest position at which it + /* Find the minimum size, and the earliest position at which it ** was achieved. */ - for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - end_move = move; - } else if (move->size == size) { - if (end_move == NULL) end_move = move; - } - } - - /* Find among the moves that give minimum size the one that - ** minimizes the distance from the corresponding variable. */ - if (moves != NULL) { - diff = Cudd_ReadSize(table) + 1; - index = (upFlag == 1) ? - table->invperm[moves->x] : table->invperm[moves->y]; - pairlev = table->perm[Cudd_bddReadPairIndex(table, index)]; - for (move = moves; move != NULL; move = move->next) { - if (move->size == size) { - if (upFlag == 1) { - tmp_diff = (move->x > pairlev) ? - move->x - pairlev : pairlev - move->x; - } else { - tmp_diff = (move->y > pairlev) ? - move->y - pairlev : pairlev - move->y; + if (move->size < size) { + size = move->size; + end_move = move; + } else if (move->size == size) { + if (end_move == NULL) end_move = move; } - if (tmp_diff < diff) { - diff = tmp_diff; - end_move = move; - } } + + /* Find among the moves that give minimum size the one that + ** minimizes the distance from the corresponding variable. */ + if (moves != NULL) { + diff = Cudd_ReadSize(table) + 1; + index = (upFlag == 1) ? + table->invperm[moves->x] : table->invperm[moves->y]; + pairlev = + (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)]; + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) { + if (upFlag == 1) { + tmp_diff = (move->x > pairlev) ? + move->x - pairlev : pairlev - move->x; + } else { + tmp_diff = (move->y > pairlev) ? + move->y - pairlev : pairlev - move->y; + } + if (tmp_diff < diff) { + diff = tmp_diff; + end_move = move; + } + } + } } - } } else { - /* Find the minimum size. */ - for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } - } + /* Find the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } } /* In case of lazy sifting, end_move identifies the position at ** which we want to stop. Otherwise, we stop as soon as we meet ** the minimum size. */ for (move = moves; move != NULL; move = move->next) { - if (lazyFlag) { - if (move == end_move) return(1); - } else { - if (move->size == size) return(1); - } + if (lazyFlag) { + if (move == end_move) return(1); + } else { + if (move->size == size) return(1); + } if ((table->subtables[move->x].next == move->x) && - (table->subtables[move->y].next == move->y)) { + (table->subtables[move->y].next == move->y)) { res = cuddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); #ifdef DD_DEBUG @@ -1711,12 +1746,12 @@ ddGroupSiftingBackward( assert(table->subtables[move->y].next == move->y); #endif } else { /* Group move necessary */ - if (move->flags == MTR_NEWNODE) { - ddDissolveGroup(table,(int)move->x,(int)move->y); - } else { - res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); - if (!res) return(0); - } + if (move->flags == MTR_NEWNODE) { + ddDissolveGroup(table,(int)move->x,(int)move->y); + } else { + res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } } @@ -1752,9 +1787,9 @@ ddMergeGroups( ** this is the topmost group. In such a case we do not merge lest ** we lose the symmetry information. */ if (treenode != table->tree) { - for (i = low; i < high; i++) - table->subtables[i].next = i+1; - table->subtables[high].next = low; + for (i = low; i < high; i++) + table->subtables[i].next = i+1; + table->subtables[high].next = low; } /* Adjust the index fields of the tree nodes. If a node is the @@ -1763,11 +1798,11 @@ ddMergeGroups( newindex = table->invperm[low]; auxnode = treenode; do { - auxnode->index = newindex; - if (auxnode->parent == NULL || - (int) auxnode->parent->index != saveindex) - break; - auxnode = auxnode->parent; + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; } while (1); return; @@ -1796,8 +1831,8 @@ ddDissolveGroup( /* find top and bottom of the two groups */ boty = y; while ((unsigned) boty < table->subtables[boty].next) - boty = table->subtables[boty].next; - + boty = table->subtables[boty].next; + topx = table->subtables[boty].next; table->subtables[boty].next = y; @@ -1864,24 +1899,24 @@ ddSecDiffCheck( threshold = table->recomb / 100.0; if (Sx < threshold) { - xindex = table->invperm[x]; - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { + xindex = table->invperm[x]; + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { #if defined(DD_DEBUG) && defined(DD_VERBOSE) - (void) fprintf(table->out, - "Second difference for %d = %g Pos(%d)\n", - table->invperm[x],Sx,x); + (void) fprintf(table->out, + "Second difference for %d = %g Pos(%d)\n", + table->invperm[x],Sx,x); #endif #ifdef DD_STATS - secdiff++; + secdiff++; #endif - return(1); - } else { + return(1); + } else { #ifdef DD_STATS - secdiffmisfire++; + secdiffmisfire++; #endif - return(0); - } + return(0); + } } return(0); @@ -1907,14 +1942,14 @@ ddExtSymmCheck( { DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; DdNode *one; - int comple; /* f0 is complemented */ - int notproj; /* f is not a projection function */ - int arccount; /* number of arcs from layer x to layer y */ - int TotalRefCount; /* total reference count of layer y minus 1 */ - int counter; /* number of nodes of layer x that are allowed */ - /* to violate extended symmetry conditions */ - int arccounter; /* number of arcs into layer y that are allowed */ - /* to come from layers other than x */ + unsigned comple; /* f0 is complemented */ + int notproj; /* f is not a projection function */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int counter; /* number of nodes of layer x that are allowed */ + /* to violate extended symmetry conditions */ + int arccounter; /* number of arcs into layer y that are allowed */ + /* to come from layers other than x */ int i; int xindex; int yindex; @@ -1928,7 +1963,7 @@ ddExtSymmCheck( /* If the two variables do not interact, we do not want to merge them. */ if (!cuddTestInteract(table,xindex,yindex)) - return(0); + return(0); #ifdef DD_DEBUG /* Checks that x and y do not contain just the projection functions. @@ -1937,10 +1972,10 @@ ddExtSymmCheck( ** any other variable. */ if (table->subtables[x].keys == 1) { - assert(table->vars[xindex]->ref != 1); + assert(table->vars[xindex]->ref != 1); } if (table->subtables[y].keys == 1) { - assert(table->vars[yindex]->ref != 1); + assert(table->vars[yindex]->ref != 1); } #endif @@ -1950,89 +1985,89 @@ ddExtSymmCheck( arccount = 0; counter = (int) (table->subtables[x].keys * - (table->symmviolation/100.0) + 0.5); + (table->symmviolation/100.0) + 0.5); one = DD_ONE(table); slots = table->subtables[x].slots; list = table->subtables[x].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - f0 = Cudd_Regular(cuddE(f)); - comple = Cudd_IsComplement(cuddE(f)); - notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; - if (f1->index == yindex) { - arccount++; - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - if ((int) f0->index != yindex) { - /* If f is an isolated projection function it is - ** allowed to bypass layer y. + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; + if (f1->index == (unsigned) yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (notproj) { + if (counter == 0) + return(0); + counter--; /* f bypasses layer y */ + } + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + /* Unless we are looking at a projection function + ** without external references except the one from the + ** table, we insist that f01 == f10 or f11 == f00 */ if (notproj) { - if (counter == 0) - return(0); - counter--; /* f bypasses layer y */ + if (f01 != f10 && f11 != f00) { + if (counter == 0) + return(0); + counter--; + } } - } - f11 = f10 = f1; - } - if ((int) f0->index == yindex) { - arccount++; - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - - /* Unless we are looking at a projection function - ** without external references except the one from the - ** table, we insist that f01 == f10 or f11 == f00 - */ - if (notproj) { - if (f01 != f10 && f11 != f00) { - if (counter == 0) - return(0); - counter--; - } - } - f = f->next; - } /* while */ + f = f->next; + } /* while */ } /* for */ /* Calculate the total reference counts of y */ - TotalRefCount = -1; /* -1 for projection function */ + TotalRefCount = -1; /* -1 for projection function */ slots = table->subtables[y].slots; list = table->subtables[y].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - TotalRefCount += f->ref; - f = f->next; - } + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } } arccounter = (int) (table->subtables[y].keys * - (table->arcviolation/100.0) + 0.5); + (table->arcviolation/100.0) + 0.5); res = arccount >= TotalRefCount - arccounter; #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (res) { - (void) fprintf(table->out, - "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + (void) fprintf(table->out, + "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif #ifdef DD_STATS if (res) - extsymm++; + extsymm++; #endif return(res); @@ -2061,16 +2096,16 @@ ddVarGroupCheck( if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0); if (Cudd_bddReadPairIndex(table, xindex) == yindex) { - if (ddIsVarHandled(table, xindex) || - ddIsVarHandled(table, yindex)) { - if (Cudd_bddIsVarToBeGrouped(table, xindex) || - Cudd_bddIsVarToBeGrouped(table, yindex) ) { - if (table->keys - table->isolated <= (unsigned)originalSize) { - return(1); - } + if (ddIsVarHandled(table, xindex) || + ddIsVarHandled(table, yindex)) { + if (Cudd_bddIsVarToBeGrouped(table, xindex) || + Cudd_bddIsVarToBeGrouped(table, yindex) ) { + if (table->keys - table->isolated <= originalSize) { + return(1); + } + } } } - } return(0); @@ -2146,5 +2181,7 @@ ddIsVarHandled( return dd->subtables[dd->perm[index]].varHandled; } /* end of ddIsVarHandled */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddHarwell.c b/src/bdd/cudd/cuddHarwell.c index af552148..75e328ea 100644 --- a/src/bdd/cudd/cuddHarwell.c +++ b/src/bdd/cudd/cuddHarwell.c @@ -7,17 +7,44 @@ Synopsis [Function to read a matrix in Harwell format.] Description [External procedures included in this module: - <ul> - <li> Cudd_addHarwell() - </ul> - ] + <ul> + <li> Cudd_addHarwell() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -27,6 +54,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -47,7 +75,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.9 2004/08/13 18:04:49 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -116,16 +144,16 @@ Cudd_addHarwell( DdNode *cubex, *cubey, *minterm1; int u, v, err, i, j, nv; double val; - DdNode **lx = NULL, **ly = NULL, **lxn = NULL, **lyn = NULL; /* local copies of x, y, xn, yn_ */ /* Suppress "might be used uninitialized */ - int lnx, lny; /* local copies of nx and ny */ + DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ + int lnx, lny; /* local copies of nx and ny */ char title[73], key[9], mxtype[4], rhstyp[4]; int totcrd, ptrcrd, indcrd, valcrd, rhscrd, nrow, ncol, nnzero, neltvl, - nrhs, nrhsix; + nrhs, nrhsix; int *colptr, *rowind; #if 0 int nguess, nexact; - int *rhsptr, *rhsind; + int *rhsptr, *rhsind; #endif if (*nx < 0 || *ny < 0) return(0); @@ -136,7 +164,7 @@ Cudd_addHarwell( /* Read the header */ err = fscanf(fp, "%72c %8c", title, key); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { return(0); } @@ -146,7 +174,7 @@ Cudd_addHarwell( err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, &valcrd, &rhscrd); if (err == EOF) { - return(0); + return(0); } else if (err != 5) { return(0); } @@ -154,55 +182,55 @@ Cudd_addHarwell( err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, &nnzero, &neltvl); if (err == EOF) { - return(0); + return(0); } else if (err != 5) { return(0); } /* Skip FORTRAN formats */ if (rhscrd == 0) { - err = fscanf(fp, "%*s %*s %*s \n"); + err = fscanf(fp, "%*s %*s %*s \n"); } else { - err = fscanf(fp, "%*s %*s %*s %*s \n"); + err = fscanf(fp, "%*s %*s %*s %*s \n"); } if (err == EOF) { - return(0); + return(0); } else if (err != 0) { return(0); } /* Print out some stuff if requested to be verbose */ if (pr>0) { - (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, - mxtype, nrow, ncol, nnzero); - if (pr>1) (void) fprintf(dd->out,"%s\n", title); + (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, + mxtype, nrow, ncol, nnzero); + if (pr>1) (void) fprintf(dd->out,"%s\n", title); } /* Check matrix type */ if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { - (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", - key, mxtype); - return(0); + (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", + key, mxtype); + return(0); } if (neltvl != 0) return(0); /* Read optional 5-th line */ if (rhscrd != 0) { - err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); - if (err == EOF) { - return(0); - } else if (err != 3) { - return(0); - } - rhstyp[3] = (char) 0; - if (rhstyp[0] != 'F') { - (void) fprintf(dd->err, - "%s: Sparse right-hand side not yet supported\n", key); - return(0); - } - if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); + err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); + if (err == EOF) { + return(0); + } else if (err != 3) { + return(0); + } + rhstyp[3] = (char) 0; + if (rhstyp[0] != 'F') { + (void) fprintf(dd->err, + "%s: Sparse right-hand side not yet supported\n", key); + return(0); + } + if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); } else { - nrhs = 0; + nrhs = 0; } /* Compute the number of variables */ @@ -210,109 +238,109 @@ Cudd_addHarwell( /* row and column numbers start from 0 */ u = nrow - 1; for (i=0; u > 0; i++) { - u >>= 1; + u >>= 1; } lnx = i; if (nrhs == 0) { - v = ncol - 1; + v = ncol - 1; } else { - v = 2* (ddMax(ncol, nrhs) - 1); + v = 2* (ddMax(ncol, nrhs) - 1); } for (i=0; v > 0; i++) { - v >>= 1; + v >>= 1; } lny = i; /* Allocate or reallocate arrays for variables as needed */ if (*nx == 0) { - if (lnx > 0) { - *x = lx = ABC_ALLOC(DdNode *,lnx); + if (lnx > 0) { + *x = lx = ABC_ALLOC(DdNode *,lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ABC_ALLOC(DdNode *,lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *x = *xn = NULL; + } + } else if (lnx > *nx) { + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - *xn = lxn = ABC_ALLOC(DdNode *,lnx); + *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } } else { - *x = *xn = NULL; - } - } else if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); - if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - } else { - lx = *x; - lxn = *xn; + lx = *x; + lxn = *xn; } if (*ny == 0) { - if (lny >0) { - *y = ly = ABC_ALLOC(DdNode *,lny); + if (lny >0) { + *y = ly = ABC_ALLOC(DdNode *,lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ABC_ALLOC(DdNode *,lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *y = *yn_ = NULL; + } + } else if (lny > *ny) { + *y = ly = ABC_REALLOC(DdNode *, *y, lny); if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - *yn_ = lyn = ABC_ALLOC(DdNode *,lny); + *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } } else { - *y = *yn_ = NULL; - } - } else if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); - if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - } else { - ly = *y; - lyn = *yn_; + ly = *y; + lyn = *yn_; } /* Create new variables as needed */ for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); - do { - dd->reordered = 0; - lxn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lxn[i] == NULL) return(0); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); cuddRef(lxn[i]); } for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); - do { - dd->reordered = 0; - lyn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lyn[i] == NULL) return(0); - cuddRef(lyn[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); } /* Update matrix parameters */ @@ -320,213 +348,213 @@ Cudd_addHarwell( *ny = lny; *m = nrow; if (nrhs == 0) { - *n = ncol; + *n = ncol; } else { - *n = (1 << (lny - 1)) + nrhs; + *n = (1 << (lny - 1)) + nrhs; } /* Read structure data */ colptr = ABC_ALLOC(int, ncol+1); if (colptr == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } rowind = ABC_ALLOC(int, nnzero); if (rowind == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i=0; i<ncol+1; i++) { - err = fscanf(fp, " %d ", &u); - if (err == EOF){ - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } else if (err != 1) { - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - colptr[i] = u - 1; + err = fscanf(fp, " %d ", &u); + if (err == EOF){ + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } else if (err != 1) { + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + colptr[i] = u - 1; } if (colptr[0] != 0) { - (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n", - key,colptr[0]); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - for (i=0; i<nnzero; i++) { - err = fscanf(fp, " %d ", &u); - if (err == EOF){ - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } else if (err != 1) { + (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n", + key,colptr[0]); ABC_FREE(colptr); ABC_FREE(rowind); return(0); } - rowind[i] = u - 1; + for (i=0; i<nnzero; i++) { + err = fscanf(fp, " %d ", &u); + if (err == EOF){ + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } else if (err != 1) { + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + rowind[i] = u - 1; } *E = zero; cuddRef(*E); for (j=0; j<ncol; j++) { - v = j; - cubey = one; cuddRef(cubey); - for (nv = lny - 1; nv>=0; nv--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); - } - if (w == NULL) { - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubey); - cubey = w; - v >>= 1; - } - for (i=colptr[j]; i<colptr[j+1]; i++) { - u = rowind[i]; - err = fscanf(fp, " %lf ", &val); - if (err == EOF || err != 1){ - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - /* Create new Constant node if necessary */ - cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); - if (cubex == NULL) { - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(cubex); - - for (nv = lnx - 1; nv>=0; nv--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); - } - if (w == NULL) { + v = j; + cubey = one; cuddRef(cubey); + for (nv = lny - 1; nv>=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); + cubey = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubex); - cubex = w; - u >>= 1; - } - minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); - if (minterm1 == NULL) { - Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); + for (i=colptr[j]; i<colptr[j+1]; i++) { + u = rowind[i]; + err = fscanf(fp, " %lf ", &val); + if (err == EOF || err != 1){ + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + /* Create new Constant node if necessary */ + cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); + if (cubex == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(cubex); + + for (nv = lnx - 1; nv>=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; } - cuddRef(minterm1); - Cudd_RecursiveDeref(dd, cubex); - w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); - if (w == NULL) { Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; - } - Cudd_RecursiveDeref(dd, cubey); } ABC_FREE(colptr); ABC_FREE(rowind); /* Read right-hand sides */ for (j=0; j<nrhs; j++) { - v = j + (1<< (lny-1)); - cubey = one; cuddRef(cubey); - for (nv = lny - 1; nv>=0; nv--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); - } - if (w == NULL) { - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubey); - cubey = w; - v >>= 1; - } - for (i=0; i<nrow; i++) { - u = i; - err = fscanf(fp, " %lf ", &val); - if (err == EOF || err != 1){ - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - /* Create new Constant node if necessary */ - if (val == (double) 0.0) continue; - cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); - if (cubex == NULL) { - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(cubex); - - for (nv = lnx - 1; nv>=0; nv--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); - } - if (w == NULL) { + v = j + (1<< (lny-1)); + cubey = one; cuddRef(cubey); + for (nv = lny - 1; nv>=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - return(0); + cubey = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubex); - cubex = w; - u >>= 1; - } - minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); - if (minterm1 == NULL) { - Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - return(0); + for (i=0; i<nrow; i++) { + u = i; + err = fscanf(fp, " %lf ", &val); + if (err == EOF || err != 1){ + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + /* Create new Constant node if necessary */ + if (val == (double) 0.0) continue; + cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); + if (cubex == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(cubex); + + for (nv = lnx - 1; nv>=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; } - cuddRef(minterm1); - Cudd_RecursiveDeref(dd, cubex); - w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); - if (w == NULL) { Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; - } - Cudd_RecursiveDeref(dd, cubey); } return(1); @@ -542,5 +570,7 @@ Cudd_addHarwell( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddInit.c b/src/bdd/cudd/cuddInit.c index a970dd5b..857e638c 100644 --- a/src/bdd/cudd/cuddInit.c +++ b/src/bdd/cudd/cuddInit.c @@ -7,35 +7,61 @@ Synopsis [Functions to initialize and shut down the DD manager.] Description [External procedures included in this module: - <ul> - <li> Cudd_Init() - <li> Cudd_Quit() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddInitUniv() - <li> cuddZddFreeUniv() - </ul> - ] + <ul> + <li> Cudd_Init() + <li> Cudd_Quit() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddInitUniv() + <li> cuddZddFreeUniv() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#define CUDD_MAIN -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START -#undef CUDD_MAIN + /*---------------------------------------------------------------------------*/ /* Constant declarations */ @@ -57,7 +83,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.33 2007/07/01 05:10:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -108,19 +134,19 @@ Cudd_Init( DdNode *one, *zero; unsigned int maxCacheSize; unsigned int looseUpTo; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (maxMemory == 0) { - maxMemory = getSoftDataLimit(); + maxMemory = getSoftDataLimit(); } looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / - DD_MAX_LOOSE_FRACTION); + DD_MAX_LOOSE_FRACTION); unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); - unique->maxmem = (unsigned) maxMemory / 10 * 9; if (unique == NULL) return(NULL); + unique->maxmem = (unsigned long) maxMemory / 10 * 9; maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / - DD_MAX_CACHE_FRACTION); + DD_MAX_CACHE_FRACTION); result = cuddInitCache(unique,cacheSize,maxCacheSize); if (result == 0) return(NULL); @@ -129,7 +155,7 @@ Cudd_Init( unique->stash = ABC_ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); MMoutOfMemory = saveHandler; if (unique->stash == NULL) { - (void) fprintf(unique->err,"Unable to set aside memory\n"); + (void) fprintf(unique->err,"Unable to set aside memory\n"); } /* Initialize constants. */ @@ -141,9 +167,9 @@ Cudd_Init( cuddRef(unique->zero); #ifdef HAVE_IEEE_754 if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || - DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { - (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); - (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); + DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { + (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); + (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); } #endif unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); @@ -160,17 +186,17 @@ Cudd_Init( /* Create the projection functions. */ unique->vars = ABC_ALLOC(DdNodePtr,unique->maxSize); if (unique->vars == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); + unique->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < unique->size; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) return(0); - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) return(0); + cuddRef(unique->vars[i]); } if (unique->sizeZ) - cuddZddInitUniv(unique); + cuddZddInitUniv(unique); unique->memused += sizeof(DdNode *) * unique->maxSize; @@ -226,29 +252,29 @@ int cuddZddInitUniv( DdManager * zdd) { - DdNode *p, *res; - int i; + DdNode *p, *res; + int i; zdd->univ = ABC_ALLOC(DdNodePtr, zdd->sizeZ); if (zdd->univ == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } res = DD_ONE(zdd); cuddRef(res); for (i = zdd->sizeZ - 1; i >= 0; i--) { - unsigned int index = zdd->invpermZ[i]; - p = res; - res = cuddUniqueInterZdd(zdd, index, p, p); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd,p); - ABC_FREE(zdd->univ); - return(0); - } - cuddRef(res); - cuddDeref(p); - zdd->univ[i] = res; + unsigned int index = zdd->invpermZ[i]; + p = res; + res = cuddUniqueInterZdd(zdd, index, p, p); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd,p); + ABC_FREE(zdd->univ); + return(0); + } + cuddRef(res); + cuddDeref(p); + zdd->univ[i] = res; } #ifdef DD_VERBOSE @@ -276,8 +302,8 @@ cuddZddFreeUniv( DdManager * zdd) { if (zdd->univ) { - Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); - ABC_FREE(zdd->univ); + Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); + ABC_FREE(zdd->univ); } } /* end of cuddZddFreeUniv */ @@ -287,5 +313,7 @@ cuddZddFreeUniv( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddInt.h b/src/bdd/cudd/cuddInt.h index ca24a8aa..09892ba5 100644 --- a/src/bdd/cudd/cuddInt.h +++ b/src/bdd/cudd/cuddInt.h @@ -12,12 +12,39 @@ Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: cuddInt.h,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddInt.h,v 1.139 2009/03/08 02:49:02 fabio Exp $] ******************************************************************************/ @@ -25,7 +52,6 @@ #define _CUDDINT - /*---------------------------------------------------------------------------*/ /* Nested includes */ /*---------------------------------------------------------------------------*/ @@ -71,65 +97,65 @@ ABC_NAMESPACE_HEADER_START /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_MAXREF ((DdHalfWord) ~0) +#define DD_MAXREF ((DdHalfWord) ~0) -#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ - /* should be added when resizing */ -#define DD_MEM_CHUNK 1022 +#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ + /* should be added when resizing */ +#define DD_MEM_CHUNK 1022 /* These definitions work for CUDD_VALUE_TYPE == double */ -#define DD_ONE_VAL (1.0) -#define DD_ZERO_VAL (0.0) -#define DD_EPSILON (1.0e-12) +#define DD_ONE_VAL (1.0) +#define DD_ZERO_VAL (0.0) +#define DD_EPSILON (1.0e-12) /* The definitions of +/- infinity in terms of HUGE_VAL work on ** the DECstations and on many other combinations of OS/compiler. */ #ifdef HAVE_IEEE_754 -# define DD_PLUS_INF_VAL (HUGE_VAL) +# define DD_PLUS_INF_VAL (HUGE_VAL) #else -# define DD_PLUS_INF_VAL (10e301) -# define DD_CRI_HI_MARK (10e150) -# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) +# define DD_PLUS_INF_VAL (10e301) +# define DD_CRI_HI_MARK (10e150) +# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) #endif -#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) +#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) -#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ +#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ /* Unique table and cache management constants. */ -#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ +#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ /* gc when this percent are dead (measured w.r.t. slots, not keys) ** The first limit (LO) applies normally. The second limit applies when ** the package believes more space for the unique table (i.e., more dead ** nodes) would improve performance, and the unique table is not already ** too large. The third limit applies when memory is low. */ -#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 -#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 -#define DD_GC_FRAC_MIN 0.2 -#define DD_MIN_HIT 30 /* resize cache when hit ratio - above this percentage (default) */ -#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for - unique table in fast growth mode) */ -#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for - computed table if resizing enabled) */ -#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set - aside for emergencies) */ +#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 +#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 +#define DD_GC_FRAC_MIN 0.2 +#define DD_MIN_HIT 30 /* resize cache when hit ratio + above this percentage (default) */ +#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for + unique table in fast growth mode) */ +#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for + computed table if resizing enabled) */ +#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set + aside for emergencies) */ #define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */ /* Variable ordering default parameter values. */ -#define DD_SIFT_MAX_VAR 1000 -#define DD_SIFT_MAX_SWAPS 2000000 -#define DD_DEFAULT_RECOMB 0 -#define DD_MAX_REORDER_GROWTH 1.2 -#define DD_FIRST_REORDER 4004 /* 4 for the constants */ -#define DD_DYN_RATIO 2 /* when to dynamically reorder */ +#define DD_SIFT_MAX_VAR 1000 +#define DD_SIFT_MAX_SWAPS 2000000 +#define DD_DEFAULT_RECOMB 0 +#define DD_MAX_REORDER_GROWTH 1.2 +#define DD_FIRST_REORDER 4004 /* 4 for the constants */ +#define DD_DYN_RATIO 2 /* when to dynamically reorder */ /* Primes for cache hash functions. */ -#define DD_P1 12582917 -#define DD_P2 4256249 -#define DD_P3 741457 -#define DD_P4 1618033999 +#define DD_P1 12582917 +#define DD_P2 4256249 +#define DD_P3 741457 +#define DD_P4 1618033999 /* Cache tags for 3-operand operators. These tags are stored in the ** least significant bits of the cache operand pointers according to @@ -143,29 +169,30 @@ ABC_NAMESPACE_HEADER_START ** entry. It can by any even digit between 0 and e. This gives a total ** of 5 bits for the tag proper, which means a maximum of 32 three-operand ** operations. */ -#define DD_ADD_ITE_TAG 0x02 -#define DD_BDD_AND_ABSTRACT_TAG 0x06 -#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a -#define DD_BDD_ITE_TAG 0x0e -#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 -#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 -#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a -#define DD_BDD_COMPOSE_RECUR_TAG 0x2e -#define DD_ADD_COMPOSE_RECUR_TAG 0x42 -#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 -#define DD_EQUIV_DC_TAG 0x4a -#define DD_ZDD_ITE_TAG 0x4e -#define DD_ADD_ITE_CONSTANT_TAG 0x62 -#define DD_ADD_EVAL_CONST_TAG 0x66 -#define DD_BDD_ITE_CONSTANT_TAG 0x6a -#define DD_ADD_OUT_SUM_TAG 0x6e -#define DD_BDD_LEQ_UNLESS_TAG 0x82 -#define DD_ADD_TRIANGLE_TAG 0x86 +#define DD_ADD_ITE_TAG 0x02 +#define DD_BDD_AND_ABSTRACT_TAG 0x06 +#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a +#define DD_BDD_ITE_TAG 0x0e +#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 +#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 +#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a +#define DD_BDD_COMPOSE_RECUR_TAG 0x2e +#define DD_ADD_COMPOSE_RECUR_TAG 0x42 +#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 +#define DD_EQUIV_DC_TAG 0x4a +#define DD_ZDD_ITE_TAG 0x4e +#define DD_ADD_ITE_CONSTANT_TAG 0x62 +#define DD_ADD_EVAL_CONST_TAG 0x66 +#define DD_BDD_ITE_CONSTANT_TAG 0x6a +#define DD_ADD_OUT_SUM_TAG 0x6e +#define DD_BDD_LEQ_UNLESS_TAG 0x82 +#define DD_ADD_TRIANGLE_TAG 0x86 /* Generator constants. */ #define CUDD_GEN_CUBES 0 -#define CUDD_GEN_NODES 1 -#define CUDD_GEN_ZDD_PATHS 2 +#define CUDD_GEN_PRIMES 1 +#define CUDD_GEN_NODES 2 +#define CUDD_GEN_ZDD_PATHS 3 #define CUDD_GEN_EMPTY 0 #define CUDD_GEN_NONEMPTY 1 @@ -175,26 +202,37 @@ ABC_NAMESPACE_HEADER_START /*---------------------------------------------------------------------------*/ struct DdGen { - DdManager *manager; - int type; - int status; + DdManager *manager; + int type; + int status; union { - struct { - int *cube; - CUDD_VALUE_TYPE value; - } cubes; - struct { - st_table *visited; - st_generator *stGen; - } nodes; + struct { + int *cube; + CUDD_VALUE_TYPE value; + } cubes; + struct { + int *cube; + DdNode *ub; + } primes; + struct { + int size; + } nodes; } gen; struct { - int sp; - DdNode **stack; + int sp; +#ifdef __osf__ +#pragma pointer_size save +#pragma pointer_size short +#endif + DdNode **stack; +#ifdef __osf__ +#pragma pointer_size restore +#endif } stack; - DdNode *node; + DdNode *node; }; + /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ @@ -204,9 +242,9 @@ struct DdGen { ** are passed the manager as argument; they should return 1 if ** successful and 0 otherwise. */ -typedef struct DdHook { /* hook list element */ - int (*f) ARGS((DdManager *, char *, void *)); /* function to be called */ - struct DdHook *next; /* next element in the list */ +typedef struct DdHook { /* hook list element */ + DD_HFP f; /* function to be called */ + struct DdHook *next; /* next element in the list */ } DdHook; #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 @@ -271,173 +309,173 @@ typedef struct DdHashTable { } DdHashTable; typedef struct DdCache { - DdNode *f,*g; /* DDs */ - ptruint h; /* either operator or DD */ - DdNode *data; /* already constructed DD */ + DdNode *f,*g; /* DDs */ + ptruint h; /* either operator or DD */ + DdNode *data; /* already constructed DD */ #ifdef DD_CACHE_PROFILE ptrint count; #endif } DdCache; -typedef struct DdSubtable { /* subtable for one index */ - DdNode **nodelist; /* hash table */ - int shift; /* shift for hash function */ - unsigned int slots; /* size of the hash table */ - unsigned int keys; /* number of nodes stored in this table */ - unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ - unsigned int dead; /* number of dead nodes in this table */ - unsigned int next; /* index of next variable in group */ - int bindVar; /* flag to bind this variable to its level */ +typedef struct DdSubtable { /* subtable for one index */ + DdNode **nodelist; /* hash table */ + int shift; /* shift for hash function */ + unsigned int slots; /* size of the hash table */ + unsigned int keys; /* number of nodes stored in this table */ + unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ + unsigned int dead; /* number of dead nodes in this table */ + unsigned int next; /* index of next variable in group */ + int bindVar; /* flag to bind this variable to its level */ /* Fields for lazy sifting. */ Cudd_VariableType varType; /* variable type (ps, ns, pi) */ int pairIndex; /* corresponding variable index (ps <-> ns) */ - int varHandled; /* flag: 1 means variable is already handled */ + int varHandled; /* flag: 1 means variable is already handled */ Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */ } DdSubtable; -struct DdManager { /* specialized DD symbol table */ +struct DdManager { /* specialized DD symbol table */ /* Constants */ - DdNode sentinel; /* for collision lists */ - DdNode *one; /* constant 1 */ - DdNode *zero; /* constant 0 */ - DdNode *plusinfinity; /* plus infinity */ - DdNode *minusinfinity; /* minus infinity */ - DdNode *background; /* background value */ + DdNode sentinel; /* for collision lists */ + DdNode *one; /* constant 1 */ + DdNode *zero; /* constant 0 */ + DdNode *plusinfinity; /* plus infinity */ + DdNode *minusinfinity; /* minus infinity */ + DdNode *background; /* background value */ /* Computed Table */ - DdCache *acache; /* address of allocated memory for cache */ - DdCache *cache; /* the cache-based computed table */ + DdCache *acache; /* address of allocated memory for cache */ + DdCache *cache; /* the cache-based computed table */ unsigned int cacheSlots; /* total number of cache entries */ - int cacheShift; /* shift value for cache hash function */ - double cacheMisses; /* number of cache misses (since resizing) */ - double cacheHits; /* number of cache hits (since resizing) */ - double minHit; /* hit percentage above which to resize */ - int cacheSlack; /* slots still available for resizing */ - unsigned int maxCacheHard; /* hard limit for cache size */ + int cacheShift; /* shift value for cache hash function */ + double cacheMisses; /* number of cache misses (since resizing) */ + double cacheHits; /* number of cache hits (since resizing) */ + double minHit; /* hit percentage above which to resize */ + int cacheSlack; /* slots still available for resizing */ + unsigned int maxCacheHard; /* hard limit for cache size */ /* Unique Table */ - int size; /* number of unique subtables */ - int sizeZ; /* for ZDD */ - int maxSize; /* max number of subtables before resizing */ - int maxSizeZ; /* for ZDD */ - DdSubtable *subtables; /* array of unique subtables */ - DdSubtable *subtableZ; /* for ZDD */ - DdSubtable constants; /* unique subtable for the constants */ - unsigned int slots; /* total number of hash buckets */ - unsigned int keys; /* total number of BDD and ADD nodes */ - unsigned int keysZ; /* total number of ZDD nodes */ - unsigned int dead; /* total number of dead BDD and ADD nodes */ - unsigned int deadZ; /* total number of dead ZDD nodes */ - unsigned int maxLive; /* maximum number of live nodes */ - unsigned int minDead; /* do not GC if fewer than these dead */ - double gcFrac; /* gc when this fraction is dead */ - int gcEnabled; /* gc is enabled */ - unsigned int looseUpTo; /* slow growth beyond this limit */ - /* (measured w.r.t. slots, not keys) */ - unsigned int initSlots; /* initial size of a subtable */ - DdNode **stack; /* stack for iterative procedures */ - double allocated; /* number of nodes allocated */ - /* (not during reordering) */ - double reclaimed; /* number of nodes brought back from the dead */ - int isolated; /* isolated projection functions */ - int *perm; /* current variable perm. (index to level) */ - int *permZ; /* for ZDD */ - int *invperm; /* current inv. var. perm. (level to index) */ - int *invpermZ; /* for ZDD */ - DdNode **vars; /* projection functions */ - int *map; /* variable map for fast swap */ - DdNode **univ; /* ZDD 1 for each variable */ - int linearSize; /* number of rows and columns of linear */ - long *interact; /* interacting variable matrix */ - long *linear; /* linear transform matrix */ + int size; /* number of unique subtables */ + int sizeZ; /* for ZDD */ + int maxSize; /* max number of subtables before resizing */ + int maxSizeZ; /* for ZDD */ + DdSubtable *subtables; /* array of unique subtables */ + DdSubtable *subtableZ; /* for ZDD */ + DdSubtable constants; /* unique subtable for the constants */ + unsigned int slots; /* total number of hash buckets */ + unsigned int keys; /* total number of BDD and ADD nodes */ + unsigned int keysZ; /* total number of ZDD nodes */ + unsigned int dead; /* total number of dead BDD and ADD nodes */ + unsigned int deadZ; /* total number of dead ZDD nodes */ + unsigned int maxLive; /* maximum number of live nodes */ + unsigned int minDead; /* do not GC if fewer than these dead */ + double gcFrac; /* gc when this fraction is dead */ + int gcEnabled; /* gc is enabled */ + unsigned int looseUpTo; /* slow growth beyond this limit */ + /* (measured w.r.t. slots, not keys) */ + unsigned int initSlots; /* initial size of a subtable */ + DdNode **stack; /* stack for iterative procedures */ + double allocated; /* number of nodes allocated */ + /* (not during reordering) */ + double reclaimed; /* number of nodes brought back from the dead */ + int isolated; /* isolated projection functions */ + int *perm; /* current variable perm. (index to level) */ + int *permZ; /* for ZDD */ + int *invperm; /* current inv. var. perm. (level to index) */ + int *invpermZ; /* for ZDD */ + DdNode **vars; /* projection functions */ + int *map; /* variable map for fast swap */ + DdNode **univ; /* ZDD 1 for each variable */ + int linearSize; /* number of rows and columns of linear */ + long *interact; /* interacting variable matrix */ + long *linear; /* linear transform matrix */ /* Memory Management */ - DdNode **memoryList; /* memory manager for symbol table */ - DdNode *nextFree; /* list of free nodes */ - char *stash; /* memory reserve */ + DdNode **memoryList; /* memory manager for symbol table */ + DdNode *nextFree; /* list of free nodes */ + char *stash; /* memory reserve */ #ifndef DD_NO_DEATH_ROW - DdNode **deathRow; /* queue for dereferencing */ - int deathRowDepth; /* number of slots in the queue */ - int nextDead; /* index in the queue */ - unsigned deadMask; /* mask for circular index update */ + DdNode **deathRow; /* queue for dereferencing */ + int deathRowDepth; /* number of slots in the queue */ + int nextDead; /* index in the queue */ + unsigned deadMask; /* mask for circular index update */ #endif /* General Parameters */ CUDD_VALUE_TYPE epsilon; /* tolerance on comparisons */ /* Dynamic Reordering Parameters */ - int reordered; /* flag set at the end of reordering */ - int reorderings; /* number of calls to Cudd_ReduceHeap */ - int siftMaxVar; /* maximum number of vars sifted */ - int siftMaxSwap; /* maximum number of swaps per sifting */ - double maxGrowth; /* maximum growth during reordering */ - double maxGrowthAlt; /* alternate maximum growth for reordering */ - int reordCycle; /* how often to apply alternate threshold */ - int autoDyn; /* automatic dynamic reordering flag (BDD) */ - int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ + int reordered; /* flag set at the end of reordering */ + int reorderings; /* number of calls to Cudd_ReduceHeap */ + int siftMaxVar; /* maximum number of vars sifted */ + int siftMaxSwap; /* maximum number of swaps per sifting */ + double maxGrowth; /* maximum growth during reordering */ + double maxGrowthAlt; /* alternate maximum growth for reordering */ + int reordCycle; /* how often to apply alternate threshold */ + int autoDyn; /* automatic dynamic reordering flag (BDD) */ + int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ Cudd_ReorderingType autoMethod; /* default reordering method */ Cudd_ReorderingType autoMethodZ; /* default reordering method (ZDD) */ - int realign; /* realign ZDD order after BDD reordering */ - int realignZ; /* realign BDD order after ZDD reordering */ - unsigned int nextDyn; /* reorder if this size is reached */ - unsigned int countDead; /* if 0, count deads to trigger reordering */ - MtrNode *tree; /* Variable group tree (BDD) */ - MtrNode *treeZ; /* Variable group tree (ZDD) */ + int realign; /* realign ZDD order after BDD reordering */ + int realignZ; /* realign BDD order after ZDD reordering */ + unsigned int nextDyn; /* reorder if this size is reached */ + unsigned int countDead; /* if 0, count deads to trigger reordering */ + MtrNode *tree; /* Variable group tree (BDD) */ + MtrNode *treeZ; /* Variable group tree (ZDD) */ Cudd_AggregationType groupcheck; /* Used during group sifting */ - int recomb; /* Used during group sifting */ - int symmviolation; /* Used during group sifting */ - int arcviolation; /* Used during group sifting */ - int populationSize; /* population size for GA */ - int numberXovers; /* number of crossovers for GA */ - DdLocalCache *localCaches; /* local caches currently in existence */ + int recomb; /* Used during group sifting */ + int symmviolation; /* Used during group sifting */ + int arcviolation; /* Used during group sifting */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + DdLocalCache *localCaches; /* local caches currently in existence */ #ifdef __osf__ #pragma pointer_size restore #endif - char *hooks; /* application-specific field (used by vis) */ - DdHook *preGCHook; /* hooks to be called before GC */ - DdHook *postGCHook; /* hooks to be called after GC */ - DdHook *preReorderingHook; /* hooks to be called before reordering */ - DdHook *postReorderingHook; /* hooks to be called after reordering */ - FILE *out; /* stdout for this manager */ - FILE *err; /* stderr for this manager */ + char *hooks; /* application-specific field (used by vis) */ + DdHook *preGCHook; /* hooks to be called before GC */ + DdHook *postGCHook; /* hooks to be called after GC */ + DdHook *preReorderingHook; /* hooks to be called before reordering */ + DdHook *postReorderingHook; /* hooks to be called after reordering */ + FILE *out; /* stdout for this manager */ + FILE *err; /* stderr for this manager */ #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - Cudd_ErrorType errorCode; /* info on last error */ + Cudd_ErrorType errorCode; /* info on last error */ /* Statistical counters. */ - long memused; /* total memory allocated for the manager */ - long maxmem; /* target maximum memory */ - long maxmemhard; /* hard limit for maximum memory */ - int garbageCollections; /* number of garbage collections */ - long GCTime; /* total time spent in garbage collection */ - long reordTime; /* total time spent in reordering */ - double totCachehits; /* total number of cache hits */ - double totCacheMisses; /* total number of cache misses */ - double cachecollisions; /* number of cache collisions */ - double cacheinserts; /* number of cache insertions */ + unsigned long memused; /* total memory allocated for the manager */ + unsigned long maxmem; /* target maximum memory */ + unsigned long maxmemhard; /* hard limit for maximum memory */ + int garbageCollections; /* number of garbage collections */ + long GCTime; /* total time spent in garbage collection */ + long reordTime; /* total time spent in reordering */ + double totCachehits; /* total number of cache hits */ + double totCacheMisses; /* total number of cache misses */ + double cachecollisions; /* number of cache collisions */ + double cacheinserts; /* number of cache insertions */ double cacheLastInserts; /* insertions at the last cache resizing */ - double cachedeletions; /* number of deletions during garbage coll. */ + double cachedeletions; /* number of deletions during garbage coll. */ #ifdef DD_STATS - double nodesFreed; /* number of nodes returned to the free list */ - double nodesDropped; /* number of nodes killed by dereferencing */ + double nodesFreed; /* number of nodes returned to the free list */ + double nodesDropped; /* number of nodes killed by dereferencing */ #endif - unsigned int peakLiveNodes; /* maximum number of live nodes */ + unsigned int peakLiveNodes; /* maximum number of live nodes */ #ifdef DD_UNIQUE_PROFILE - double uniqueLookUps; /* number of unique table lookups */ - double uniqueLinks; /* total distance traveled in coll. chains */ + double uniqueLookUps; /* number of unique table lookups */ + double uniqueLinks; /* total distance traveled in coll. chains */ #endif #ifdef DD_COUNT - double recursiveCalls; /* number of recursive calls */ + double recursiveCalls; /* number of recursive calls */ #ifdef DD_STATS - double nextSample; /* when to write next line of stats */ + double nextSample; /* when to write next line of stats */ #endif - double swapSteps; /* number of elementary reordering steps */ + double swapSteps; /* number of elementary reordering steps */ #endif #ifdef DD_MIS /* mis/verif compatibility fields */ - array_t *iton; /* maps ids in ddNode to node_t */ + array_t *iton; /* maps ids in ddNode to node_t */ array_t *order; /* copy of order_list */ - lsHandle handle; /* where it is in network BDD list */ + lsHandle handle; /* where it is in network BDD list */ network_t *network; - st_table *local_order; /* for local BDDs */ - int nvars; /* variables used so far */ - int threshold; /* for pseudo var threshold value*/ + st_table *local_order; /* for local BDDs */ + int nvars; /* variables used so far */ + int threshold; /* for pseudo var threshold value*/ #endif DdNode * bFunc; DdNode * bFunc2; @@ -496,13 +534,31 @@ typedef struct DdLevelQueue { SideEffects [None] - SeeAlso [cuddAllocNode cuddDynamicAllocNode] + SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove] ******************************************************************************/ #define cuddDeallocNode(unique,node) \ (node)->next = (unique)->nextFree; \ (unique)->nextFree = node; +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddDeallocNode cuddDynamicAllocNode] + +******************************************************************************/ +#define cuddDeallocMove(unique,node) \ + ((DdNode *)(node))->ref = 0; \ + ((DdNode *)(node))->next = (unique)->nextFree; \ + (unique)->nextFree = (DdNode *)(node); + /**Macro*********************************************************************** @@ -620,7 +676,7 @@ typedef struct DdLevelQueue { SeeAlso [Cudd_ReadPerm] ******************************************************************************/ -#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) +#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) /**Macro*********************************************************************** @@ -638,7 +694,7 @@ typedef struct DdLevelQueue { SeeAlso [Cudd_ReadPermZdd] ******************************************************************************/ -#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) +#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) /**Macro*********************************************************************** @@ -654,8 +710,8 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddHash(f,g,s) \ -((((unsigned)(unsigned long)(f) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (s)) +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) #else #define ddHash(f,g,s) \ ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) @@ -675,9 +731,9 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddCHash(o,f,g,h,s) \ -((((((unsigned)(unsigned long)(f) + (unsigned)(unsigned long)(o)) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2 + \ - (unsigned)(unsigned long)(h)) * DD_P3) >> (s)) +((((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2 + \ + (unsigned)(ptruint)(h)) * DD_P3) >> (s)) #else #define ddCHash(o,f,g,h,s) \ ((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \ @@ -699,8 +755,8 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddCHash2(o,f,g,s) \ -(((((unsigned)(unsigned long)(f) + (unsigned)(unsigned long)(o)) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (s)) +(((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) #else #define ddCHash2(o,f,g,s) \ (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) @@ -825,7 +881,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY] ******************************************************************************/ -#define DD_ONE(dd) ((dd)->one) +#define DD_ONE(dd) ((dd)->one) /**Macro*********************************************************************** @@ -893,7 +949,7 @@ typedef struct DdLevelQueue { #ifdef HAVE_IEEE_754 #define cuddAdjust(x) #else -#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) +#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) #endif @@ -909,7 +965,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_MSDIGIT] ******************************************************************************/ -#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) +#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) /**Macro*********************************************************************** @@ -924,7 +980,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_LSDIGIT] ******************************************************************************/ -#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) +#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) /**Macro*********************************************************************** @@ -961,181 +1017,184 @@ dd->nextSample += 250000;} /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EXTERN DdNode * cuddAddExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddUnivAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddOrAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddApplyRecur ARGS((DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddAddMonadicApplyRecur ARGS((DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f)); -EXTERN DdNode * cuddAddScalarInverseRecur ARGS((DdManager *dd, DdNode *f, DdNode *epsilon)); -EXTERN DdNode * cuddAddIteRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddAddCmplRecur ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * cuddAddNegateRecur ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * cuddAddRoundOffRecur ARGS((DdManager *dd, DdNode *f, double trunc)); -EXTERN DdNode * cuddUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * cuddRemapUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * cuddBiasedUnderApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * cuddBddAndAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN int cuddAnnealing ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddBddXorExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * cuddBddBooleanDiffRecur ARGS((DdManager *manager, DdNode *f, DdNode *var)); -EXTERN DdNode * cuddBddIteRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddBddIntersectRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddAndRecur ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddXorRecur ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddTransfer ARGS((DdManager *ddS, DdManager *ddD, DdNode *f)); -EXTERN DdNode * cuddAddBddDoPattern ARGS((DdManager *dd, DdNode *f)); -EXTERN int cuddInitCache ARGS((DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize)); -EXTERN void cuddCacheInsert ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)); -EXTERN void cuddCacheInsert2 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)); -EXTERN void cuddCacheInsert1 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f, DdNode *data)); -EXTERN DdNode * cuddCacheLookup ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddCacheLookupZdd ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddCacheLookup2 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCacheLookup1 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f)); -EXTERN DdNode * cuddCacheLookup2Zdd ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCacheLookup1Zdd ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f)); -EXTERN DdNode * cuddConstantLookup ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN int cuddCacheProfile ARGS((DdManager *table, FILE *fp)); -EXTERN void cuddCacheResize ARGS((DdManager *table)); -EXTERN void cuddCacheFlush ARGS((DdManager *table)); -EXTERN int cuddComputeFloorLog2 ARGS((unsigned int value)); -EXTERN int cuddHeapProfile ARGS((DdManager *dd)); -EXTERN void cuddPrintNode ARGS((DdNode *f, FILE *fp)); -EXTERN void cuddPrintVarGroups ARGS((DdManager * dd, MtrNode * root, int zdd, int silent)); -EXTERN DdNode * cuddBddClippingAnd ARGS((DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)); -EXTERN DdNode * cuddBddClippingAndAbstract ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)); -EXTERN void cuddGetBranches ARGS((DdNode *g, DdNode **g1, DdNode **g0)); -EXTERN int cuddCheckCube ARGS((DdManager *dd, DdNode *g)); -EXTERN DdNode * cuddCofactorRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)); -EXTERN DdNode * cuddAddComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)); -EXTERN int cuddExact ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddConstrainRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddBddRestrictRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddAddConstrainRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddAddRestrictRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddBddLICompaction ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN int cuddGa ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddTreeSifting ARGS((DdManager *table, Cudd_ReorderingType method, int TimeStop)); -EXTERN int cuddZddInitUniv ARGS((DdManager *zdd)); -EXTERN void cuddZddFreeUniv ARGS((DdManager *zdd)); -EXTERN void cuddSetInteract ARGS((DdManager *table, int x, int y)); -EXTERN int cuddTestInteract ARGS((DdManager *table, int x, int y)); -EXTERN int cuddInitInteract ARGS((DdManager *table)); -EXTERN DdLocalCache * cuddLocalCacheInit ARGS((DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)); -EXTERN void cuddLocalCacheQuit ARGS((DdLocalCache *cache)); -EXTERN void cuddLocalCacheInsert ARGS((DdLocalCache *cache, DdNodePtr *key, DdNode *value)); -EXTERN DdNode * cuddLocalCacheLookup ARGS((DdLocalCache *cache, DdNodePtr *key)); -EXTERN void cuddLocalCacheClearDead ARGS((DdManager *manager)); -EXTERN int cuddIsInDeathRow ARGS((DdManager *dd, DdNode *f)); -EXTERN int cuddTimesInDeathRow ARGS((DdManager *dd, DdNode *f)); -EXTERN void cuddLocalCacheClearAll ARGS((DdManager *manager)); +extern DdNode * cuddAddExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddUnivAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddOrAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddApplyRecur( DdManager * dd, DdNode * (*)(DdManager * , DdNode ** , DdNode **), DdNode * f, DdNode * g ); +extern DdNode * cuddAddMonadicApplyRecur( DdManager * dd, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddAddScalarInverseRecur( DdManager * dd, DdNode * f, DdNode * epsilon ); +extern DdNode * cuddAddIteRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddAddCmplRecur( DdManager * dd, DdNode * f ); +extern DdNode * cuddAddNegateRecur( DdManager * dd, DdNode * f ); +extern DdNode * cuddAddRoundOffRecur( DdManager * dd, DdNode * f, double trunc ); +extern DdNode * cuddUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * cuddRemapUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * cuddBiasedUnderApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * cuddBddAndAbstractRecur( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern int cuddAnnealing( DdManager * table, int lower, int upper ); +extern DdNode * cuddBddExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddBddXorExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * cuddBddBooleanDiffRecur( DdManager * manager, DdNode * f, DdNode * var ); +extern DdNode * cuddBddIteRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddBddIntersectRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddBddAndRecur( DdManager * manager, DdNode * f, DdNode * g ); +extern DdNode * cuddBddXorRecur( DdManager * manager, DdNode * f, DdNode * g ); +extern DdNode * cuddBddTransfer( DdManager * ddS, DdManager * ddD, DdNode * f ); +extern DdNode * cuddAddBddDoPattern( DdManager * dd, DdNode * f ); +extern int cuddInitCache( DdManager * unique, unsigned int cacheSize, unsigned int maxCacheSize ); +extern void cuddCacheInsert( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h, DdNode * data ); +extern void cuddCacheInsert2( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g, DdNode * data ); +extern void cuddCacheInsert1( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f, DdNode * data ); +extern DdNode * cuddCacheLookup( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddCacheLookupZdd( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddCacheLookup2( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g ); +extern DdNode * cuddCacheLookup1( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddCacheLookup2Zdd( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g ); +extern DdNode * cuddCacheLookup1Zdd( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddConstantLookup( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern int cuddCacheProfile( DdManager * table, FILE * fp ); +extern void cuddCacheResize( DdManager * table ); +extern void cuddCacheFlush( DdManager * table ); +extern int cuddComputeFloorLog2( unsigned int value ); +extern int cuddHeapProfile( DdManager * dd ); +extern void cuddPrintNode( DdNode * f, FILE * fp ); +extern void cuddPrintVarGroups( DdManager * dd, MtrNode * root, int zdd, int silent ); +extern DdNode * cuddBddClippingAnd( DdManager * dd, DdNode * f, DdNode * g, int maxDepth, int direction ); +extern DdNode * cuddBddClippingAndAbstract( DdManager * dd, DdNode * f, DdNode * g, DdNode * cube, int maxDepth, int direction ); +extern void cuddGetBranches( DdNode * g, DdNode ** g1, DdNode ** g0 ); +extern int cuddCheckCube( DdManager * dd, DdNode * g ); +extern DdNode * cuddCofactorRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddBddComposeRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * proj ); +extern DdNode * cuddAddComposeRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * proj ); +extern int cuddExact( DdManager * table, int lower, int upper ); +extern DdNode * cuddBddConstrainRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddRestrictRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddNPAndRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddAddConstrainRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddAddRestrictRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddLICompaction( DdManager * dd, DdNode * f, DdNode * c ); +extern int cuddGa( DdManager * table, int lower, int upper ); +extern int cuddTreeSifting( DdManager * table, Cudd_ReorderingType method ); +extern int cuddZddInitUniv( DdManager * zdd ); +extern void cuddZddFreeUniv( DdManager * zdd ); +extern void cuddSetInteract( DdManager * table, int x, int y ); +extern int cuddTestInteract( DdManager * table, int x, int y ); +extern int cuddInitInteract( DdManager * table ); +extern DdLocalCache * cuddLocalCacheInit( DdManager * manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize ); +extern void cuddLocalCacheQuit( DdLocalCache * cache ); +extern void cuddLocalCacheInsert( DdLocalCache * cache, DdNodePtr * key, DdNode * value ); +extern DdNode * cuddLocalCacheLookup( DdLocalCache * cache, DdNodePtr * key ); +extern void cuddLocalCacheClearDead( DdManager * manager ); +extern int cuddIsInDeathRow( DdManager * dd, DdNode * f ); +extern int cuddTimesInDeathRow( DdManager * dd, DdNode * f ); +extern void cuddLocalCacheClearAll( DdManager * manager ); #ifdef DD_CACHE_PROFILE -EXTERN int cuddLocalCacheProfile ARGS((DdLocalCache *cache)); +extern int cuddLocalCacheProfile( DdLocalCache * cache ); #endif -EXTERN DdHashTable * cuddHashTableInit ARGS((DdManager *manager, unsigned int keySize, unsigned int initSize)); -EXTERN void cuddHashTableQuit ARGS((DdHashTable *hash)); -EXTERN int cuddHashTableInsert ARGS((DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup ARGS((DdHashTable *hash, DdNodePtr *key)); -EXTERN int cuddHashTableInsert1 ARGS((DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup1 ARGS((DdHashTable *hash, DdNode *f)); -EXTERN int cuddHashTableInsert2 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup2 ARGS((DdHashTable *hash, DdNode *f, DdNode *g)); -EXTERN int cuddHashTableInsert3 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup3 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdLevelQueue * cuddLevelQueueInit ARGS((int levels, int itemSize, int numBuckets)); -EXTERN void cuddLevelQueueQuit ARGS((DdLevelQueue *queue)); -EXTERN void * cuddLevelQueueEnqueue ARGS((DdLevelQueue *queue, void *key, int level)); -EXTERN void cuddLevelQueueDequeue ARGS((DdLevelQueue *queue, int level)); -EXTERN int cuddLinearAndSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddLiteralSetIntersectionRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCProjectionRecur ARGS((DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp)); -EXTERN DdNode * cuddBddClosestCube ARGS((DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound)); -EXTERN void cuddReclaim ARGS((DdManager *table, DdNode *n)); -EXTERN void cuddReclaimZdd ARGS((DdManager *table, DdNode *n)); -EXTERN void cuddClearDeathRow ARGS((DdManager *table)); -EXTERN void cuddShrinkDeathRow ARGS((DdManager *table)); -EXTERN DdNode * cuddDynamicAllocNode ARGS((DdManager *table)); -EXTERN int cuddSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddSwapping ARGS((DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)); -EXTERN int cuddNextHigh ARGS((DdManager *table, int x)); -EXTERN int cuddNextLow ARGS((DdManager *table, int x)); -EXTERN int cuddSwapInPlace ARGS((DdManager *table, int x, int y)); -EXTERN int cuddBddAlignToZdd ARGS((DdManager *table)); -EXTERN DdNode * cuddBddMakePrime ARGS((DdManager *dd, DdNode *cube, DdNode *f)); -EXTERN DdNode * cuddSolveEqnRecur ARGS((DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i)); -EXTERN DdNode * cuddVerifySol ARGS((DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n)); +extern DdHashTable * cuddHashTableInit( DdManager * manager, unsigned int keySize, unsigned int initSize ); +extern void cuddHashTableQuit( DdHashTable * hash ); +extern int cuddHashTableInsert( DdHashTable * hash, DdNodePtr * key, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup( DdHashTable * hash, DdNodePtr * key ); +extern int cuddHashTableInsert1( DdHashTable * hash, DdNode * f, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup1( DdHashTable * hash, DdNode * f ); +extern int cuddHashTableInsert2( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup2( DdHashTable * hash, DdNode * f, DdNode * g ); +extern int cuddHashTableInsert3( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * h, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup3( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * h ); +extern DdLevelQueue * cuddLevelQueueInit( int levels, int itemSize, int numBuckets ); +extern void cuddLevelQueueQuit( DdLevelQueue * queue ); +extern void * cuddLevelQueueEnqueue( DdLevelQueue * queue, void * key, int level ); +extern void cuddLevelQueueDequeue( DdLevelQueue * queue, int level ); +extern int cuddLinearAndSifting( DdManager * table, int lower, int upper ); +extern int cuddLinearInPlace( DdManager * table, int x, int y ); +extern void cuddUpdateInteractionMatrix( DdManager * table, int xindex, int yindex ); +extern int cuddInitLinear( DdManager * table ); +extern int cuddResizeLinear( DdManager * table ); +extern DdNode * cuddBddLiteralSetIntersectionRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddCProjectionRecur( DdManager * dd, DdNode * R, DdNode * Y, DdNode * Ysupp ); +extern DdNode * cuddBddClosestCube( DdManager * dd, DdNode * f, DdNode * g, CUDD_VALUE_TYPE bound ); +extern void cuddReclaim( DdManager * table, DdNode * n ); +extern void cuddReclaimZdd( DdManager * table, DdNode * n ); +extern void cuddClearDeathRow( DdManager * table ); +extern void cuddShrinkDeathRow( DdManager * table ); +extern DdNode * cuddDynamicAllocNode( DdManager * table ); +extern int cuddSifting( DdManager * table, int lower, int upper ); +extern int cuddSwapping( DdManager * table, int lower, int upper, Cudd_ReorderingType heuristic ); +extern int cuddNextHigh( DdManager * table, int x ); +extern int cuddNextLow( DdManager * table, int x ); +extern int cuddSwapInPlace( DdManager * table, int x, int y ); +extern int cuddBddAlignToZdd( DdManager * table ); +extern DdNode * cuddBddMakePrime( DdManager * dd, DdNode * cube, DdNode * f ); +extern DdNode * cuddSolveEqnRecur( DdManager * bdd, DdNode * F, DdNode * Y, DdNode ** G, int n, int * yIndex, int i ); +extern DdNode * cuddVerifySol( DdManager * bdd, DdNode * F, DdNode ** G, int * yIndex, int n ); #ifdef ST_INCLUDED -EXTERN DdNode* cuddSplitSetRecur ARGS((DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index)); +extern DdNode * cuddSplitSetRecur( DdManager * manager, st_table * mtable, int * varSeen, DdNode * p, double n, double max, int index ); #endif -EXTERN DdNode * cuddSubsetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * cuddSubsetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN int cuddSymmCheck ARGS((DdManager *table, int x, int y)); -EXTERN int cuddSymmSifting ARGS((DdManager *table, int lower, int upper, int TimeStop)); -EXTERN int cuddSymmSiftingConv ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddAllocNode ARGS((DdManager *unique)); -EXTERN DdManager * cuddInitTable ARGS((unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)); -EXTERN void cuddFreeTable ARGS((DdManager *unique)); -EXTERN int cuddGarbageCollect ARGS((DdManager *unique, int clearCache)); -EXTERN int cuddGarbageCollectZdd ARGS((DdManager *unique, int clearCache)); -EXTERN DdNode * cuddZddGetNode ARGS((DdManager *zdd, int id, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddZddGetNodeIVO ARGS((DdManager *dd, int index, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddUniqueInter ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueInterIVO ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueInterZdd ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueConst ARGS((DdManager *unique, CUDD_VALUE_TYPE value)); -EXTERN void cuddRehash ARGS((DdManager *unique, int i)); -EXTERN void cuddShrinkSubtable ARGS((DdManager *unique, int i)); -EXTERN int cuddInsertSubtables ARGS((DdManager *unique, int n, int level)); -EXTERN int cuddDestroySubtables ARGS((DdManager *unique, int n)); -EXTERN int cuddResizeTableZdd ARGS((DdManager *unique, int index)); -EXTERN void cuddSlowTableGrowth ARGS((DdManager *unique)); -EXTERN int cuddP ARGS((DdManager *dd, DdNode *f)); +extern DdNode * cuddSubsetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * cuddSubsetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern int cuddSymmCheck( DdManager * table, int x, int y ); +extern int cuddSymmSifting( DdManager * table, int lower, int upper ); +extern int cuddSymmSiftingConv( DdManager * table, int lower, int upper ); +extern DdNode * cuddAllocNode( DdManager * unique ); +extern DdManager * cuddInitTable( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo ); +extern void cuddFreeTable( DdManager * unique ); +extern int cuddGarbageCollect( DdManager * unique, int clearCache ); +extern DdNode * cuddZddGetNode( DdManager * zdd, int id, DdNode * T, DdNode * E ); +extern DdNode * cuddZddGetNodeIVO( DdManager * dd, int index, DdNode * g, DdNode * h ); +extern DdNode * cuddUniqueInter( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueInterIVO( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueInterZdd( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueConst( DdManager * unique, CUDD_VALUE_TYPE value ); +extern void cuddRehash( DdManager * unique, int i ); +extern void cuddShrinkSubtable( DdManager * unique, int i ); +extern int cuddInsertSubtables( DdManager * unique, int n, int level ); +extern int cuddDestroySubtables( DdManager * unique, int n ); +extern int cuddResizeTableZdd( DdManager * unique, int index ); +extern void cuddSlowTableGrowth( DdManager * unique ); +extern int cuddP( DdManager * dd, DdNode * f ); #ifdef ST_INCLUDED -EXTERN enum st_retval cuddStCountfree ARGS((char *key, char *value, char *arg)); -EXTERN int cuddCollectNodes ARGS((DdNode *f, st_table *visited)); +extern enum st_retval cuddStCountfree( char * key, char * value, char * arg ); +extern int cuddCollectNodes( DdNode * f, st_table * visited ); #endif -EXTERN int cuddWindowReorder ARGS((DdManager *table, int low, int high, Cudd_ReorderingType submethod)); -EXTERN DdNode * cuddZddProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddUnateProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddWeakDiv ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddWeakDivF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddDivide ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddDivideF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int cuddZddGetCofactors3 ARGS((DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)); -EXTERN int cuddZddGetCofactors2 ARGS((DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)); -EXTERN DdNode * cuddZddComplement ARGS((DdManager *dd, DdNode *node)); -EXTERN int cuddZddGetPosVarIndex(DdManager * dd, int index); -EXTERN int cuddZddGetNegVarIndex(DdManager * dd, int index); -EXTERN int cuddZddGetPosVarLevel(DdManager * dd, int index); -EXTERN int cuddZddGetNegVarLevel(DdManager * dd, int index); -EXTERN int cuddZddTreeSifting ARGS((DdManager *table, Cudd_ReorderingType method)); -EXTERN DdNode * cuddZddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)); -EXTERN DdNode * cuddBddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U)); -EXTERN DdNode * cuddMakeBddFromZddCover ARGS((DdManager *dd, DdNode *node)); -EXTERN int cuddZddLinearSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddAlignToBdd ARGS((DdManager *table)); -EXTERN int cuddZddNextHigh ARGS((DdManager *table, int x)); -EXTERN int cuddZddNextLow ARGS((DdManager *table, int x)); -EXTERN int cuddZddUniqueCompare ARGS((int *ptr_x, int *ptr_y)); -EXTERN int cuddZddSwapInPlace ARGS((DdManager *table, int x, int y)); -EXTERN int cuddZddSwapping ARGS((DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)); -EXTERN int cuddZddSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddZddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddZddUnion ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddIntersect ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddDiff ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddChangeAux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -EXTERN DdNode * cuddZddSubset1 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * cuddZddSubset0 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * cuddZddChange ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN int cuddZddSymmCheck ARGS((DdManager *table, int x, int y)); -EXTERN int cuddZddSymmSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddSymmSiftingConv ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddP ARGS((DdManager *zdd, DdNode *f)); - -EXTERN void (*MMoutOfMemory)(long); +extern DdNodePtr * cuddNodeArray( DdNode * f, int * n ); +extern int cuddWindowReorder( DdManager * table, int low, int high, Cudd_ReorderingType submethod ); +extern DdNode * cuddZddProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddUnateProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddWeakDiv( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddWeakDivF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddDivide( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddDivideF( DdManager * dd, DdNode * f, DdNode * g ); +extern int cuddZddGetCofactors3( DdManager * dd, DdNode * f, int v, DdNode ** f1, DdNode ** f0, DdNode ** fd ); +extern int cuddZddGetCofactors2( DdManager * dd, DdNode * f, int v, DdNode ** f1, DdNode ** f0 ); +extern DdNode * cuddZddComplement( DdManager * dd, DdNode * node ); +extern int cuddZddGetPosVarIndex(DdManager * dd, int index ); +extern int cuddZddGetNegVarIndex(DdManager * dd, int index ); +extern int cuddZddGetPosVarLevel(DdManager * dd, int index ); +extern int cuddZddGetNegVarLevel(DdManager * dd, int index ); +extern int cuddZddTreeSifting( DdManager * table, Cudd_ReorderingType method ); +extern DdNode * cuddZddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I ); +extern DdNode * cuddBddIsop( DdManager * dd, DdNode * L, DdNode * U ); +extern DdNode * cuddMakeBddFromZddCover( DdManager * dd, DdNode * node ); +extern int cuddZddLinearSifting( DdManager * table, int lower, int upper ); +extern int cuddZddAlignToBdd( DdManager * table ); +extern int cuddZddNextHigh( DdManager * table, int x ); +extern int cuddZddNextLow( DdManager * table, int x ); +extern int cuddZddUniqueCompare( int * ptr_x, int * ptr_y ); +extern int cuddZddSwapInPlace( DdManager * table, int x, int y ); +extern int cuddZddSwapping( DdManager * table, int lower, int upper, Cudd_ReorderingType heuristic ); +extern int cuddZddSifting( DdManager * table, int lower, int upper ); +extern DdNode * cuddZddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddZddUnion( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddIntersect( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddDiff( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddChangeAux( DdManager * zdd, DdNode * P, DdNode * zvar ); +extern DdNode * cuddZddSubset1( DdManager * dd, DdNode * P, int var ); +extern DdNode * cuddZddSubset0( DdManager * dd, DdNode * P, int var ); +extern DdNode * cuddZddChange( DdManager * dd, DdNode * P, int var ); +extern int cuddZddSymmCheck( DdManager * table, int x, int y ); +extern int cuddZddSymmSifting( DdManager * table, int lower, int upper ); +extern int cuddZddSymmSiftingConv( DdManager * table, int lower, int upper ); +extern int cuddZddP( DdManager * zdd, DdNode * f ); /**AutomaticEnd***************************************************************/ diff --git a/src/bdd/cudd/cuddInteract.c b/src/bdd/cudd/cuddInteract.c index 3891e9d0..1d335c2a 100644 --- a/src/bdd/cudd/cuddInteract.c +++ b/src/bdd/cudd/cuddInteract.c @@ -7,18 +7,18 @@ Synopsis [Functions to manipulate the variable interaction matrix.] Description [Internal procedures included in this file: - <ul> - <li> cuddSetInteract() - <li> cuddTestInteract() - <li> cuddInitInteract() - </ul> + <ul> + <li> cuddSetInteract() + <li> cuddTestInteract() + <li> cuddInitInteract() + </ul> Static procedures included in this file: - <ul> - <li> ddSuppInteract() - <li> ddClearLocal() - <li> ddUpdateInteract() - <li> ddClearGlobal() - </ul> + <ul> + <li> ddSuppInteract() + <li> ddClearLocal() + <li> ddUpdateInteract() + <li> ddClearGlobal() + </ul> The interaction matrix tells whether two variables are both in the support of some function of the DD. The main use of the interaction matrix is in the in-place swapping. Indeed, if two @@ -40,10 +40,37 @@ Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -53,6 +80,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -80,7 +108,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.12 2004/08/13 18:04:49 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -94,10 +122,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ddSuppInteract ARGS((DdNode *f, int *support)); -static void ddClearLocal ARGS((DdNode *f)); -static void ddUpdateInteract ARGS((DdManager *table, int *support)); -static void ddClearGlobal ARGS((DdManager *table)); +static void ddSuppInteract (DdNode *f, int *support); +static void ddClearLocal (DdNode *f); +static void ddUpdateInteract (DdManager *table, int *support); +static void ddClearGlobal (DdManager *table); /**AutomaticEnd***************************************************************/ @@ -168,9 +196,9 @@ cuddTestInteract( int posn, word, bit, result; if (x > y) { - int tmp = x; - x = y; - y = tmp; + int tmp = x; + x = y; + y = tmp; } #ifdef DD_DEBUG assert(x < y); @@ -222,43 +250,43 @@ cuddInitInteract( words = ((n * (n-1)) >> (1 + LOGBPL)) + 1; table->interact = interact = ABC_ALLOC(long,words); if (interact == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < words; i++) { - interact[i] = 0; + interact[i] = 0; } support = ABC_ALLOC(int,n); if (support == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(interact); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(interact); + return(0); } for (i = 0; i < n; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - /* A node is a root of the DAG if it cannot be - ** reached by nodes above it. If a node was never - ** reached during the previous depth-first searches, - ** then it is a root, and we start a new depth-first - ** search from it. - */ - if (!Cudd_IsComplement(f->next)) { - for (k = 0; k < n; k++) { - support[k] = 0; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + for (k = 0; k < n; k++) { + support[k] = 0; + } + ddSuppInteract(f,support); + ddClearLocal(f); + ddUpdateInteract(table,support); + } + f = Cudd_Regular(f->next); } - ddSuppInteract(f,support); - ddClearLocal(f); - ddUpdateInteract(table,support); } - f = Cudd_Regular(f->next); - } - } } ddClearGlobal(table); @@ -291,7 +319,7 @@ ddSuppInteract( int * support) { if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) { - return; + return; } support[f->index] = 1; @@ -321,7 +349,7 @@ ddClearLocal( DdNode * f) { if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) { - return; + return; } /* clear visited flag */ cuddT(f) = Cudd_Regular(cuddT(f)); @@ -354,14 +382,14 @@ ddUpdateInteract( int n = table->size; for (i = 0; i < n-1; i++) { - if (support[i] == 1) { - for (j = i+1; j < n; j++) { - if (support[j] == 1) { - cuddSetInteract(table,i,j); - } + if (support[i] == 1) { + for (j = i+1; j < n; j++) { + if (support[j] == 1) { + cuddSetInteract(table,i,j); + } + } } } - } } /* end of ddUpdateInteract */ @@ -390,18 +418,20 @@ ddClearGlobal( int slots; for (i = 0; i < table->size; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - f->next = Cudd_Regular(f->next); - f = f->next; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } } } - } } /* end of ddClearGlobal */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddLCache.c b/src/bdd/cudd/cuddLCache.c index bf6af8bd..45d71a8d 100644 --- a/src/bdd/cudd/cuddLCache.c +++ b/src/bdd/cudd/cuddLCache.c @@ -7,55 +7,83 @@ Synopsis [Functions for local caches.] Description [Internal procedures included in this module: - <ul> - <li> cuddLocalCacheInit() - <li> cuddLocalCacheQuit() - <li> cuddLocalCacheInsert() - <li> cuddLocalCacheLookup() - <li> cuddLocalCacheClearDead() - <li> cuddLocalCacheClearAll() - <li> cuddLocalCacheProfile() - <li> cuddHashTableInit() - <li> cuddHashTableQuit() - <li> cuddHashTableInsert() - <li> cuddHashTableLookup() - <li> cuddHashTableInsert2() - <li> cuddHashTableLookup2() - <li> cuddHashTableInsert3() - <li> cuddHashTableLookup3() - </ul> - Static procedures included in this module: - <ul> - <li> cuddLocalCacheResize() - <li> ddLCHash() - <li> cuddLocalCacheAddToList() - <li> cuddLocalCacheRemoveFromList() - <li> cuddHashTableResize() - <li> cuddHashTableAlloc() - </ul> ] + <ul> + <li> cuddLocalCacheInit() + <li> cuddLocalCacheQuit() + <li> cuddLocalCacheInsert() + <li> cuddLocalCacheLookup() + <li> cuddLocalCacheClearDead() + <li> cuddLocalCacheClearAll() + <li> cuddLocalCacheProfile() + <li> cuddHashTableInit() + <li> cuddHashTableQuit() + <li> cuddHashTableInsert() + <li> cuddHashTableLookup() + <li> cuddHashTableInsert2() + <li> cuddHashTableLookup2() + <li> cuddHashTableInsert3() + <li> cuddHashTableLookup3() + </ul> + Static procedures included in this module: + <ul> + <li> cuddLocalCacheResize() + <li> ddLCHash() + <li> cuddLocalCacheAddToList() + <li> cuddLocalCacheRemoveFromList() + <li> cuddHashTableResize() + <li> cuddHashTableAlloc() + </ul> ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ +#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -72,7 +100,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -92,8 +120,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddLCHash2(f,g,shift) \ -((((unsigned)(unsigned long)(f) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (shift)) +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) #else #define ddLCHash2(f,g,shift) \ ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) @@ -120,12 +148,12 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void cuddLocalCacheResize ARGS((DdLocalCache *cache)); -DD_INLINE static unsigned int ddLCHash ARGS((DdNodePtr *key, unsigned int keysize, int shift)); -static void cuddLocalCacheAddToList ARGS((DdLocalCache *cache)); -static void cuddLocalCacheRemoveFromList ARGS((DdLocalCache *cache)); -static int cuddHashTableResize ARGS((DdHashTable *hash)); -DD_INLINE static DdHashItem * cuddHashTableAlloc ARGS((DdHashTable *hash)); +static void cuddLocalCacheResize (DdLocalCache *cache); +DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift); +static void cuddLocalCacheAddToList (DdLocalCache *cache); +static void cuddLocalCacheRemoveFromList (DdLocalCache *cache); +static int cuddHashTableResize (DdHashTable *hash); +DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash); /**AutomaticEnd***************************************************************/ @@ -163,8 +191,8 @@ cuddLocalCacheInit( cache = ABC_ALLOC(DdLocalCache,1); if (cache == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cache->manager = manager; cache->keysize = keySize; @@ -175,11 +203,11 @@ cuddLocalCacheInit( logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2)); cacheSize = 1 << logSize; cache->item = (DdLocalCacheItem *) - ABC_ALLOC(char, cacheSize * cache->itemsize); + ABC_ALLOC(char, cacheSize * cache->itemsize); if (cache->item == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(cache); - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(cache); + return(NULL); } cache->slots = cacheSize; cache->shift = sizeof(int) * 8 - logSize; @@ -219,7 +247,7 @@ cuddLocalCacheQuit( DdLocalCache * cache /* cache to be shut down */) { cache->manager->memused -= - cache->slots * cache->itemsize + sizeof(DdLocalCache); + cache->slots * cache->itemsize + sizeof(DdLocalCache); cuddLocalCacheRemoveFromList(cache); ABC_FREE(cache->item); ABC_FREE(cache); @@ -251,7 +279,7 @@ cuddLocalCacheInsert( posn = ddLCHash(key,cache->keysize,cache->shift); entry = (DdLocalCacheItem *) ((char *) cache->item + - posn * cache->itemsize); + posn * cache->itemsize); memcpy(entry->key,key,cache->keysize * sizeof(DdNode *)); entry->value = value; #ifdef DD_CACHE_PROFILE @@ -285,22 +313,22 @@ cuddLocalCacheLookup( cache->lookUps++; posn = ddLCHash(key,cache->keysize,cache->shift); entry = (DdLocalCacheItem *) ((char *) cache->item + - posn * cache->itemsize); + posn * cache->itemsize); if (entry->value != NULL && - memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { - cache->hits++; - value = Cudd_Regular(entry->value); - if (value->ref == 0) { - cuddReclaim(cache->manager,value); - } - return(entry->value); + memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { + cache->hits++; + value = Cudd_Regular(entry->value); + if (value->ref == 0) { + cuddReclaim(cache->manager,value); + } + return(entry->value); } /* Cache miss: decide whether to resize */ if (cache->slots < cache->maxslots && - cache->hits > cache->lookUps * cache->minHit) { - cuddLocalCacheResize(cache); + cache->hits > cache->lookUps * cache->minHit) { + cuddLocalCacheResize(cache); } return(NULL); @@ -333,25 +361,27 @@ cuddLocalCacheClearDead( unsigned int i, j; while (cache != NULL) { - keysize = cache->keysize; - itemsize = cache->itemsize; - slots = cache->slots; - item = cache->item; - for (i = 0; i < slots; i++) { - if (item->value != NULL && Cudd_Regular(item->value)->ref == 0) { - item->value = NULL; - } else { - key = item->key; - for (j = 0; j < keysize; j++) { - if (Cudd_Regular(key[j])->ref == 0) { - item->value = NULL; - break; + keysize = cache->keysize; + itemsize = cache->itemsize; + slots = cache->slots; + item = cache->item; + for (i = 0; i < slots; i++) { + if (item->value != NULL) { + if (Cudd_Regular(item->value)->ref == 0) { + item->value = NULL; + } else { + key = item->key; + for (j = 0; j < keysize; j++) { + if (Cudd_Regular(key[j])->ref == 0) { + item->value = NULL; + break; + } + } + } } + item = (DdLocalCacheItem *) ((char *) item + itemsize); } - } - item = (DdLocalCacheItem *) ((char *) item + itemsize); - } - cache = cache->next; + cache = cache->next; } return; @@ -377,8 +407,8 @@ cuddLocalCacheClearAll( DdLocalCache *cache = manager->localCaches; while (cache != NULL) { - memset(cache->item, 0, cache->slots * cache->itemsize); - cache = cache->next; + memset(cache->item, 0, cache->slots * cache->itemsize); + cache = cache->next; } return; @@ -427,34 +457,34 @@ cuddLocalCacheProfile( hystogram = ABC_ALLOC(long, nbins); if (hystogram == NULL) { - return(0); + return(0); } for (i = 0; i < nbins; i++) { - hystogram[i] = 0; + hystogram[i] = 0; } for (i = 0; i < slots; i++) { - entry = (DdLocalCacheItem *) ((char *) cache->item + - i * cache->itemsize); - thiscount = (long) entry->count; - if (thiscount > max) { - max = thiscount; - imax = i; - } - if (thiscount < min) { - min = thiscount; - imin = i; - } - if (thiscount == 0) { - nzeroes++; - } - count = (double) thiscount; - mean += count; - meansq += count * count; - totalcount += count; - expected += count * (double) i; - bin = (i * nbins) / slots; - hystogram[bin] += thiscount; + entry = (DdLocalCacheItem *) ((char *) cache->item + + i * cache->itemsize); + thiscount = (long) entry->count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogram[bin] += thiscount; } mean /= (double) slots; meansq /= (double) slots; @@ -472,17 +502,17 @@ cuddLocalCacheProfile( if (retval == EOF) return(0); if (totalcount) { - expected /= totalcount; - retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); - if (retval == EOF) return(0); - retval = fprintf(fp," (expected bin value = %g)\n# ", expected); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp,"%ld ", hystogram[i]); + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\n# ", expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp,"%ld ", hystogram[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\n"); - if (retval == EOF) return(0); } ABC_FREE(hystogram); @@ -519,15 +549,15 @@ cuddHashTableInit( #endif hash = ABC_ALLOC(DdHashTable, 1); if (hash == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } hash->keysize = keySize; hash->manager = manager; hash->memoryList = NULL; hash->nextFree = NULL; hash->itemsize = (keySize + 1) * sizeof(DdNode *) + - sizeof(ptrint) + sizeof(DdHashItem *); + sizeof(ptrint) + sizeof(DdHashItem *); /* We have to guarantee that the shift be < 32. */ if (initSize < 2) initSize = 2; logSize = cuddComputeFloorLog2(initSize); @@ -535,9 +565,9 @@ cuddHashTableInit( hash->shift = sizeof(int) * 8 - logSize; hash->bucket = ABC_ALLOC(DdHashItem *, hash->numBuckets); if (hash->bucket == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(hash); - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(hash); + return(NULL); } memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *)); hash->size = 0; @@ -576,18 +606,18 @@ cuddHashTableQuit( unsigned int numBuckets = hash->numBuckets; for (i = 0; i < numBuckets; i++) { - bucket = hash->bucket[i]; - while (bucket != NULL) { - Cudd_RecursiveDeref(dd, bucket->value); - bucket = bucket->next; - } + bucket = hash->bucket[i]; + while (bucket != NULL) { + Cudd_RecursiveDeref(dd, bucket->value); + bucket = bucket->next; + } } memlist = hash->memoryList; while (memlist != NULL) { - nextmem = (DdHashItem **) memlist[0]; - ABC_FREE(memlist); - memlist = nextmem; + nextmem = (DdHashItem **) memlist[0]; + ABC_FREE(memlist); + memlist = nextmem; } ABC_FREE(hash->bucket); @@ -631,8 +661,8 @@ cuddHashTableInsert( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -641,7 +671,7 @@ cuddHashTableInsert( cuddRef(value); item->count = count; for (i = 0; i < hash->keysize; i++) { - item->key[i] = key[i]; + item->key[i] = key[i]; } posn = ddLCHash(key,hash->keysize,hash->shift); item->next = hash->bucket[posn]; @@ -688,32 +718,32 @@ cuddHashTableLookup( keysize = hash->keysize; while (item != NULL) { - DdNodePtr *key2 = item->key; - int equal = 1; - for (i = 0; i < keysize; i++) { - if (key[i] != key2[i]) { - equal = 0; - break; - } - } - if (equal) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; + DdNodePtr *key2 = item->key; + int equal = 1; + for (i = 0; i < keysize; i++) { + if (key[i] != key2[i]) { + equal = 0; + break; + } } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + if (equal) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -749,8 +779,8 @@ cuddHashTableInsert1( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -776,7 +806,7 @@ cuddHashTableInsert1( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -802,25 +832,25 @@ cuddHashTableLookup1( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if (f == key[0]) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if (f == key[0]) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -857,8 +887,8 @@ cuddHashTableInsert2( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -885,7 +915,7 @@ cuddHashTableInsert2( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -912,25 +942,25 @@ cuddHashTableLookup2( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if ((f == key[0]) && (g == key[1])) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -968,8 +998,8 @@ cuddHashTableInsert3( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -997,7 +1027,7 @@ cuddHashTableInsert3( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -1025,25 +1055,25 @@ cuddHashTableLookup3( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if ((f == key[0]) && (g == key[1]) && (h == key[2])) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1]) && (h == key[2])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -1074,8 +1104,8 @@ cuddLocalCacheResize( int i, shift; unsigned int posn; unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; olditem = cache->item; oldslots = cache->slots; @@ -1083,28 +1113,28 @@ cuddLocalCacheResize( #ifdef DD_VERBOSE (void) fprintf(cache->manager->err, - "Resizing local cache from %d to %d entries\n", - oldslots, slots); + "Resizing local cache from %d to %d entries\n", + oldslots, slots); (void) fprintf(cache->manager->err, - "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", - cache->hits, cache->lookUps, cache->hits / cache->lookUps); + "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", + cache->hits, cache->lookUps, cache->hits / cache->lookUps); #endif saveHandler = MMoutOfMemory; MMoutOfMemory = Cudd_OutOfMem; cache->item = item = - (DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize); + (DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize); MMoutOfMemory = saveHandler; /* If we fail to allocate the new table we just give up. */ if (item == NULL) { #ifdef DD_VERBOSE - (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); + (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); #endif - cache->slots = oldslots; - cache->item = olditem; - /* Do not try to resize again. */ - cache->maxslots = oldslots - 1; - return; + cache->slots = oldslots; + cache->item = olditem; + /* Do not try to resize again. */ + cache->maxslots = oldslots - 1; + return; } shift = --(cache->shift); cache->manager->memused += (slots - oldslots) * cache->itemsize; @@ -1114,14 +1144,14 @@ cuddLocalCacheResize( /* Copy from old cache to new one. */ for (i = 0; (unsigned) i < oldslots; i++) { - old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); - if (old->value != NULL) { - posn = ddLCHash(old->key,cache->keysize,slots); - entry = (DdLocalCacheItem *) ((char *) item + - posn * cache->itemsize); - memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); - entry->value = old->value; - } + old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); + if (old->value != NULL) { + posn = ddLCHash(old->key,cache->keysize,shift); + entry = (DdLocalCacheItem *) ((char *) item + + posn * cache->itemsize); + memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); + entry->value = old->value; + } } ABC_FREE(olditem); @@ -1154,11 +1184,11 @@ ddLCHash( unsigned int keysize, int shift) { - unsigned int val = (unsigned int) (ptrint) key[0]; + unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2; unsigned int i; for (i = 1; i < keysize; i++) { - val = val * DD_P1 + (int) (ptrint) key[i]; + val = val * DD_P1 + (int) (ptrint) key[i]; } return(val >> shift); @@ -1219,14 +1249,14 @@ cuddLocalCacheRemoveFromList( nextCache = manager->localCaches; while (nextCache != NULL) { - if (nextCache == cache) { - *prevCache = nextCache->next; - return; - } - prevCache = &(nextCache->next); - nextCache = nextCache->next; + if (nextCache == cache) { + *prevCache = nextCache->next; + return; + } + prevCache = &(nextCache->next); + nextCache = nextCache->next; } - return; /* should never get here */ + return; /* should never get here */ } /* end of cuddLocalCacheRemoveFromList */ @@ -1264,8 +1294,8 @@ cuddHashTableResize( #endif int shift; int oldNumBuckets = hash->numBuckets; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; /* Compute the new size of the table. */ numBuckets = oldNumBuckets << 1; @@ -1278,8 +1308,8 @@ cuddHashTableResize( buckets = ABC_ALLOC(DdHashItem *, numBuckets); MMoutOfMemory = saveHandler; if (buckets == NULL) { - hash->maxsize <<= 1; - return(1); + hash->maxsize <<= 1; + return(1); } hash->bucket = buckets; @@ -1291,53 +1321,53 @@ cuddHashTableResize( #pragma pointer_size restore #endif if (hash->keysize == 1) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash2(key[0], key[0], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[0], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else if (hash->keysize == 2) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash2(key[0], key[1], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[1], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else if (hash->keysize == 3) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash3(key[0], key[1], key[2], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash3(key[0], key[1], key[2], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - posn = ddLCHash(item->key, hash->keysize, shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + posn = ddLCHash(item->key, hash->keysize, shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } } - } ABC_FREE(oldBuckets); return(1); @@ -1365,8 +1395,8 @@ cuddHashTableAlloc( { int i; unsigned int itemsize = hash->itemsize; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short @@ -1374,54 +1404,54 @@ cuddHashTableAlloc( DdHashItem **mem, *thisOne, *next, *item; if (hash->nextFree == NULL) { - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); - MMoutOfMemory = saveHandler; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + MMoutOfMemory = saveHandler; #ifdef __osf__ #pragma pointer_size restore #endif - if (mem == NULL) { - if (hash->manager->stash != NULL) { - ABC_FREE(hash->manager->stash); - hash->manager->stash = NULL; - /* Inhibit resizing of tables. */ - hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; - hash->manager->cacheSlack = -(int)(hash->manager->cacheSlots + 1); - for (i = 0; i < hash->manager->size; i++) { - hash->manager->subtables[i].maxKeys <<= 2; - } - hash->manager->gcFrac = 0.2; - hash->manager->minDead = - (unsigned) (0.2 * (double) hash->manager->slots); + if (mem == NULL) { + if (hash->manager->stash != NULL) { + ABC_FREE(hash->manager->stash); + hash->manager->stash = NULL; + /* Inhibit resizing of tables. */ + hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; + hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1); + for (i = 0; i < hash->manager->size; i++) { + hash->manager->subtables[i].maxKeys <<= 2; + } + hash->manager->gcFrac = 0.2; + hash->manager->minDead = + (unsigned) (0.2 * (double) hash->manager->slots); #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); #ifdef __osf__ #pragma pointer_size restore #endif + } + if (mem == NULL) { + (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize)); + hash->manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } } - if (mem == NULL) { - (*MMoutOfMemory)((DD_MEM_CHUNK + 1) * itemsize); - hash->manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - } - mem[0] = (DdHashItem *) hash->memoryList; - hash->memoryList = mem; + mem[0] = (DdHashItem *) hash->memoryList; + hash->memoryList = mem; - thisOne = (DdHashItem *) ((char *) mem + itemsize); - hash->nextFree = thisOne; - for (i = 1; i < DD_MEM_CHUNK; i++) { - next = (DdHashItem *) ((char *) thisOne + itemsize); - thisOne->next = next; - thisOne = next; - } + thisOne = (DdHashItem *) ((char *) mem + itemsize); + hash->nextFree = thisOne; + for (i = 1; i < DD_MEM_CHUNK; i++) { + next = (DdHashItem *) ((char *) thisOne + itemsize); + thisOne->next = next; + thisOne = next; + } - thisOne->next = NULL; + thisOne->next = NULL; } item = hash->nextFree; @@ -1429,5 +1459,7 @@ cuddHashTableAlloc( return(item); } /* end of cuddHashTableAlloc */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLevelQ.c b/src/bdd/cudd/cuddLevelQ.c index 1a09820a..43e730d6 100644 --- a/src/bdd/cudd/cuddLevelQ.c +++ b/src/bdd/cudd/cuddLevelQ.c @@ -25,28 +25,55 @@ Internal procedures provided by this module: <ul> - <li> cuddLevelQueueInit() - <li> cuddLevelQueueQuit() - <li> cuddLevelQueueEnqueue() - <li> cuddLevelQueueDequeue() - </ul> + <li> cuddLevelQueueInit() + <li> cuddLevelQueueQuit() + <li> cuddLevelQueueEnqueue() + <li> cuddLevelQueueDequeue() + </ul> Static procedures included in this module: - <ul> - <li> hashLookup() - <li> hashInsert() - <li> hashDelete() - <li> hashResize() - </ul> - ] + <ul> + <li> hashLookup() + <li> hashInsert() + <li> hashDelete() + <li> hashResize() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -56,6 +83,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.13 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -95,7 +123,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define lqHash(key,shift) \ -(((unsigned)(unsigned long)(key) * DD_P1) >> (shift)) +(((unsigned)(ptruint)(key) * DD_P1) >> (shift)) #else #define lqHash(key,shift) \ (((unsigned)(key) * DD_P1) >> (shift)) @@ -108,10 +136,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdQueueItem * hashLookup ARGS((DdLevelQueue *queue, void *key)); -static int hashInsert ARGS((DdLevelQueue *queue, DdQueueItem *item)); -static void hashDelete ARGS((DdLevelQueue *queue, DdQueueItem *item)); -static int hashResize ARGS((DdLevelQueue *queue)); +static DdQueueItem * hashLookup (DdLevelQueue *queue, void *key); +static int hashInsert (DdLevelQueue *queue, DdQueueItem *item); +static void hashDelete (DdLevelQueue *queue, DdQueueItem *item); +static int hashResize (DdLevelQueue *queue); /**AutomaticEnd***************************************************************/ @@ -148,7 +176,7 @@ cuddLevelQueueInit( queue = ABC_ALLOC(DdLevelQueue,1); if (queue == NULL) - return(NULL); + return(NULL); #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short @@ -159,8 +187,8 @@ cuddLevelQueueInit( #pragma pointer_size restore #endif if (queue->last == NULL) { - ABC_FREE(queue); - return(NULL); + ABC_FREE(queue); + return(NULL); } /* Use a hash table to test for uniqueness. */ if (numBuckets < 2) numBuckets = 2; @@ -176,9 +204,9 @@ cuddLevelQueueInit( #pragma pointer_size restore #endif if (queue->buckets == NULL) { - ABC_FREE(queue->last); - ABC_FREE(queue); - return(NULL); + ABC_FREE(queue->last); + ABC_FREE(queue); + return(NULL); } #ifdef __osf__ #pragma pointer_size save @@ -219,14 +247,14 @@ cuddLevelQueueQuit( DdQueueItem *item; while (queue->freelist != NULL) { - item = queue->freelist; - queue->freelist = item->next; - ABC_FREE(item); + item = queue->freelist; + queue->freelist = item->next; + ABC_FREE(item); } while (queue->first != NULL) { - item = (DdQueueItem *) queue->first; - queue->first = item->next; - ABC_FREE(item); + item = (DdQueueItem *) queue->first; + queue->first = item->next; + ABC_FREE(item); } ABC_FREE(queue->buckets); ABC_FREE(queue->last); @@ -268,12 +296,12 @@ cuddLevelQueueEnqueue( /* Get a free item from either the free list or the memory manager. */ if (queue->freelist == NULL) { - item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize); - if (item == NULL) - return(NULL); + item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); } else { - item = queue->freelist; - queue->freelist = item->next; + item = queue->freelist; + queue->freelist = item->next; } /* Initialize. */ memset(item, 0, queue->itemsize); @@ -282,29 +310,29 @@ cuddLevelQueueEnqueue( queue->size++; if (queue->last[level]) { - /* There are already items for this level in the queue. */ - item->next = queue->last[level]->next; - queue->last[level]->next = item; - } else { - /* There are no items at the current level. Look for the first - ** non-empty level preceeding this one. */ - plevel = level; - while (plevel != 0 && queue->last[plevel] == NULL) - plevel--; - if (queue->last[plevel] == NULL) { - /* No element precedes this one in the queue. */ - item->next = (DdQueueItem *) queue->first; - queue->first = item; + /* There are already items for this level in the queue. */ + item->next = queue->last[level]->next; + queue->last[level]->next = item; } else { - item->next = queue->last[plevel]->next; - queue->last[plevel]->next = item; - } + /* There are no items at the current level. Look for the first + ** non-empty level preceeding this one. */ + plevel = level; + while (plevel != 0 && queue->last[plevel] == NULL) + plevel--; + if (queue->last[plevel] == NULL) { + /* No element precedes this one in the queue. */ + item->next = (DdQueueItem *) queue->first; + queue->first = item; + } else { + item->next = queue->last[plevel]->next; + queue->last[plevel]->next = item; + } } queue->last[level] = item; /* Insert entry for the key in the hash table. */ if (hashInsert(queue,item) == 0) { - return(NULL); + return(NULL); } return(item); @@ -335,7 +363,7 @@ cuddLevelQueueDequeue( /* Since we delete from the front, if this is the last item for ** its level, there are no other items for the same level. */ if (queue->last[level] == item) - queue->last[level] = NULL; + queue->last[level] = NULL; queue->first = item->next; /* Put item on the free list. */ @@ -378,10 +406,10 @@ hashLookup( item = queue->buckets[posn]; while (item != NULL) { - if (item->key == key) { - return(item); - } - item = item->cnext; + if (item->key == key) { + return(item); + } + item = item->cnext; } return(NULL); @@ -410,8 +438,8 @@ hashInsert( int posn; if (queue->size > queue->maxsize) { - result = hashResize(queue); - if (result == 0) return(0); + result = hashResize(queue); + if (result == 0) return(0); } posn = lqHash(item->key,queue->shift); @@ -448,16 +476,16 @@ hashDelete( if (prevItem == NULL) return; if (prevItem == item) { - queue->buckets[posn] = prevItem->cnext; - return; + queue->buckets[posn] = prevItem->cnext; + return; } while (prevItem->cnext != NULL) { - if (prevItem->cnext == item) { - prevItem->cnext = item->cnext; - return; - } - prevItem = prevItem->cnext; + if (prevItem->cnext == item) { + prevItem->cnext = item->cnext; + return; + } + prevItem = prevItem->cnext; } return; @@ -496,8 +524,8 @@ hashResize( #endif int shift; int oldNumBuckets = queue->numBuckets; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; /* Compute the new size of the subtable. */ numBuckets = oldNumBuckets << 1; @@ -508,9 +536,10 @@ hashResize( #pragma pointer_size short #endif buckets = queue->buckets = ABC_ALLOC(DdQueueItem *, numBuckets); + MMoutOfMemory = saveHandler; if (buckets == NULL) { - queue->maxsize <<= 1; - return(1); + queue->maxsize <<= 1; + return(1); } queue->numBuckets = numBuckets; @@ -521,18 +550,20 @@ hashResize( #pragma pointer_size restore #endif for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->cnext; - posn = lqHash(item->key, shift); - item->cnext = buckets[posn]; - buckets[posn] = item; - item = next; - } + item = oldBuckets[j]; + while (item != NULL) { + next = item->cnext; + posn = lqHash(item->key, shift); + item->cnext = buckets[posn]; + buckets[posn] = item; + item = next; + } } ABC_FREE(oldBuckets); return(1); } /* end of hashResize */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLinear.c b/src/bdd/cudd/cuddLinear.c index 9cb19e95..19de9820 100644 --- a/src/bdd/cudd/cuddLinear.c +++ b/src/bdd/cudd/cuddLinear.c @@ -7,30 +7,57 @@ Synopsis [Functions for DD reduction by linear transformations.] Description [ Internal procedures included in this module: - <ul> - <li> cuddLinearAndSifting() - </ul> - Static procedures included in this module: - <ul> - <li> ddLinearUniqueCompare() - <li> ddLinearAndSiftingAux() - <li> ddLinearAndSiftingUp() - <li> ddLinearAndSiftingDown() - <li> ddLinearAndSiftingBackward() - <li> ddUndoMoves() - <li> ddUpdateInteractionMatrix() - <li> cuddLinearInPlace() - <li> cuddInitLinear() - <li> cuddResizeLinear() - <li> cuddXorLinear() - </ul>] + <ul> + <li> cuddLinearAndSifting() + <li> cuddLinearInPlace() + <li> cuddUpdateInteractionMatrix() + <li> cuddInitLinear() + <li> cuddResizeLinear() + </ul> + Static procedures included in this module: + <ul> + <li> ddLinearUniqueCompare() + <li> ddLinearAndSiftingAux() + <li> ddLinearAndSiftingUp() + <li> ddLinearAndSiftingDown() + <li> ddLinearAndSiftingBackward() + <li> ddUndoMoves() + <li> cuddXorLinear() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,19 +96,19 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $"; #endif -static int *entry; +static int *entry; #ifdef DD_STATS -extern int ddTotalNumberSwapping; -extern int ddTotalNISwaps; -static int ddTotalNumberLinearTr; +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int ddTotalNumberLinearTr; #endif #ifdef DD_DEBUG -static int zero = 0; +static int zero = 0; #endif /*---------------------------------------------------------------------------*/ @@ -93,17 +121,13 @@ static int zero = 0; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddLinearUniqueCompare ARGS((int *ptrX, int *ptrY)); -static int ddLinearAndSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddLinearAndSiftingUp ARGS((DdManager *table, int y, int xLow, Move *prevMoves)); -static Move * ddLinearAndSiftingDown ARGS((DdManager *table, int x, int xHigh, Move *prevMoves)); -static int ddLinearAndSiftingBackward ARGS((DdManager *table, int size, Move *moves)); -static Move* ddUndoMoves ARGS((DdManager *table, Move *moves)); -static int cuddLinearInPlace ARGS((DdManager *table, int x, int y)); -static void ddUpdateInteractionMatrix ARGS((DdManager *table, int xindex, int yindex)); -static int cuddInitLinear ARGS((DdManager *table)); -static int cuddResizeLinear ARGS((DdManager *table)); -static void cuddXorLinear ARGS((DdManager *table, int x, int y)); +static int ddLinearUniqueCompare (int *ptrX, int *ptrY); +static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves); +static Move* ddUndoMoves (DdManager *table, Move *moves); +static void cuddXorLinear (DdManager *table, int x, int y); /**AutomaticEnd***************************************************************/ @@ -114,7 +138,7 @@ static void cuddXorLinear ARGS((DdManager *table, int x, int y)); /**Function******************************************************************** - + Synopsis [Prints the linear transform matrix.] Description [Prints the linear transform matrix. Returns 1 in case of @@ -136,16 +160,16 @@ Cudd_PrintLinear( long word; for (i = 0; i < nvars; i++) { - for (j = 0; j < wordsPerRow; j++) { - word = table->linear[i*wordsPerRow + j]; - for (k = 0; k < BPL; k++) { - retval = fprintf(table->out,"%ld",word & 1); - if (retval == 0) return(0); - word >>= 1; + for (j = 0; j < wordsPerRow; j++) { + word = table->linear[i*wordsPerRow + j]; + for (k = 0; k < BPL; k++) { + retval = fprintf(table->out,"%ld",word & 1); + if (retval == 0) return(0); + word >>= 1; + } } - } - retval = fprintf(table->out,"\n"); - if (retval == 0) return(0); + retval = fprintf(table->out,"\n"); + if (retval == 0) return(0); } return(1); @@ -153,7 +177,7 @@ Cudd_PrintLinear( /**Function******************************************************************** - + Synopsis [Reads an entry of the linear transform matrix.] Description [Reads an entry of the linear transform matrix.] @@ -218,13 +242,13 @@ cuddLinearAndSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif #ifdef DD_STATS @@ -236,65 +260,65 @@ cuddLinearAndSifting( var = NULL; entry = NULL; if (table->linear == NULL) { - result = cuddInitLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + result = cuddInitLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #if 0 - (void) fprintf(table->out,"\n"); - result = Cudd_PrintLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #endif } else if (table->size != table->linearSize) { - result = cuddResizeLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + result = cuddResizeLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #if 0 - (void) fprintf(table->out,"\n"); - result = Cudd_PrintLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #endif } /* Find order in which to sift variables. */ entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddLinearAndSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddLinearAndSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddLinearUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - x = table->perm[var[i]]; - if (x < lower || x > upper) continue; + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddLinearAndSiftingAux(table,x,lower,upper); - if (!result) goto cuddLinearAndSiftingOutOfMem; + result = ddLinearAndSiftingAux(table,x,lower,upper); + if (!result) goto cuddLinearAndSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif #ifdef DD_DEBUG - (void) Cudd_DebugCheck(table); + (void) Cudd_DebugCheck(table); #endif } @@ -303,7 +327,7 @@ cuddLinearAndSifting( #ifdef DD_STATS (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.", - ddTotalNumberLinearTr); + ddTotalNumberLinearTr); #endif return(1); @@ -313,11 +337,520 @@ cuddLinearAndSiftingOutOfMem: if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - return(0); + return(0); } /* end of cuddLinearAndSifting */ +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise.] + + SideEffects [The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected.] + + SeeAlso [cuddSwapInPlace] + +******************************************************************************/ +int +cuddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next,*last; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int count, idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + if (cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNumberLinearTr++; +#endif + /* Get parameters of x subtable. */ + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + g = NULL; +#ifdef DD_DEBUG + last = NULL; +#endif + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == sentinel) continue; + xlist[i] = sentinel; + if (g == NULL) { + g = f; + } else { + last->next = f; + } + while ((next = f->next) != sentinel) { + f = next; + } /* while there are elements in the collision chain */ + last = f; + } /* for each slot of the x subtable */ +#ifdef DD_DEBUG + /* last is always assigned in the for loop because there is at + ** least one key */ + assert(last != NULL); +#endif + last->next = NULL; + +#ifdef DD_COUNT + table->swapSteps += oldxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f00) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex,f11,f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddLinearOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f00; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* decrease ref count of f0 */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* create the new E child */ + if (f01 == f10) { + newf0 = f01; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f01 is regular */ + newcomplement = Cudd_IsComplement(f01); + if (newcomplement) { + f01 = Cudd_Not(f01); + f10 = Cudd_Not(f10); + } + /* Check ylist for triple (yindex,f01,f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf0 = *previousP; + while (f01 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddLinearOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f01; + cuddE(newf0) = f10; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f01 and f10. + */ + newykeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f01->ref); + tmp = Cudd_Regular(f10); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + previousP = &(xlist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for every collision list */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys || newxkeys != oldxkeys) { + fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + + /* Set the appropriate fields in table. */ + table->subtables[y].keys = newykeys; + + /* Here we should update the linear combination table + ** to record that x <- x EXNOR y. This is done by complementing + ** the (x,y) entry of the table. + */ + + table->keys += newykeys - oldykeys; + + cuddXorLinear(table,xindex,yindex); + } + +#ifdef DD_DEBUG + if (zero) { + (void) Cudd_DebugCheck(table); + } +#endif + + return(table->keys - table->isolated); + +cuddLinearOutOfMem: + (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); + + return (0); + +} /* end of cuddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Updates the interaction matrix.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +void +cuddUpdateInteractionMatrix( + DdManager * table, + int xindex, + int yindex) +{ + int i; + for (i = 0; i < yindex; i++) { + if (i != xindex && cuddTestInteract(table,i,yindex)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + for (i = yindex+1; i < table->size; i++) { + if (i != xindex && cuddTestInteract(table,yindex,i)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + +} /* end of cuddUpdateInteractionMatrix */ + + +/**Function******************************************************************** + + Synopsis [Initializes the linear transform matrix.] + + Description [Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitLinear( + DdManager * table) +{ + int words; + int wordsPerRow; + int nvars; + int word; + int bit; + int i; + long *linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ABC_ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += words * sizeof(long); + table->linearSize = nvars; + for (i = 0; i < words; i++) linear[i] = 0; + for (i = 0; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + return(1); + +} /* end of cuddInitLinear */ + + +/**Function******************************************************************** + + Synopsis [Resizes the linear transform matrix.] + + Description [Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddResizeLinear( + DdManager * table) +{ + int words,oldWords; + int wordsPerRow,oldWordsPerRow; + int nvars,oldNvars; + int word,oldWord; + int bit; + int i,j; + long *linear,*oldLinear; + + oldNvars = table->linearSize; + oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; + oldWords = oldWordsPerRow * oldNvars; + oldLinear = table->linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ABC_ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += (words - oldWords) * sizeof(long); + for (i = 0; i < words; i++) linear[i] = 0; + + /* Copy old matrix. */ + for (i = 0; i < oldNvars; i++) { + for (j = 0; j < oldWordsPerRow; j++) { + oldWord = oldWordsPerRow * i + j; + word = wordsPerRow * i + j; + linear[word] = oldLinear[oldWord]; + } + } + ABC_FREE(oldLinear); + + /* Add elements to the diagonal. */ + for (i = oldNvars; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + table->linearSize = nvars; + + return(1); + +} /* end of cuddResizeLinear */ + + /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ @@ -342,7 +875,7 @@ ddLinearUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -371,11 +904,11 @@ ddLinearAndSiftingAux( int xHigh) { - Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; initialSize = table->keys - table->isolated; @@ -383,73 +916,73 @@ ddLinearAndSiftingAux( moveUp = NULL; if (x == xLow) { - moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else if (x == xHigh) { - moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - moveUp = ddUndoMoves(table,moveDown); + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddUndoMoves(table,moveDown); #ifdef DD_DEBUG - assert(moveUp == NULL || moveUp->x == x); + assert(moveUp == NULL || moveUp->x == x); #endif - moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else { /* must go up first: shorter */ - moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - moveDown = ddUndoMoves(table,moveUp); + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddUndoMoves(table,moveUp); #ifdef DD_DEBUG - assert(moveDown == NULL || moveDown->y == x); + assert(moveDown == NULL || moveDown->y == x); #endif - moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddLinearAndSiftingAuxOutOfMem: while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(0); @@ -476,14 +1009,14 @@ ddLinearAndSiftingUp( int xLow, Move * prevMoves) { - Move *moves; - Move *move; - int x; - int size, newsize; - int limitSize; - int xindex, yindex; - int isolated; - int L; /* lower bound on DD size */ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; int z; @@ -501,84 +1034,84 @@ ddLinearAndSiftingUp( */ limitSize = L = table->keys - table->isolated; for (x = xLow + 1; x < y; x++) { - xindex = table->invperm[x]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L -= table->subtables[x].keys - isolated; - } + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } } isolated = table->vars[yindex]->ref == 1; L -= table->subtables[y].keys - isolated; x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { - xindex = table->invperm[x]; + xindex = table->invperm[x]; #ifdef DD_DEBUG - checkL = table->keys - table->isolated; - for (z = xLow + 1; z < y; z++) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + if (L != checkL) { + (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); } - } - isolated = table->vars[yindex]->ref == 1; - checkL -= table->subtables[y].keys - isolated; - if (L != checkL) { - (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); - } #endif - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddLinearAndSiftingUpOutOfMem; - newsize = cuddLinearInPlace(table,x,y); - if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize >= size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingUpOutOfMem; newsize = cuddLinearInPlace(table,x,y); if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; #ifdef DD_DEBUG - if (newsize != size) { - (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); - } + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } #endif - } else if (cuddTestInteract(table,xindex,yindex)) { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - ddUpdateInteractionMatrix(table,xindex,yindex); - } - move->size = size; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - y = x; - x = cuddNextLow(table,y); + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); } return(moves); ddLinearAndSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of ddLinearAndSiftingUp */ - + /**Function******************************************************************** @@ -599,18 +1132,18 @@ ddLinearAndSiftingDown( int xHigh, Move * prevMoves) { - Move *moves; - Move *move; - int y; - int size, newsize; - int R; /* upper bound on node decrease */ - int limitSize; - int xindex, yindex; - int isolated; + Move *moves; + Move *move; + int y; + int size, newsize; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; #ifdef DD_DEBUG - int checkR; - int z; - int zindex; + int checkR; + int z; + int zindex; #endif moves = prevMoves; @@ -619,73 +1152,73 @@ ddLinearAndSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (y = xHigh; y > x; y--) { - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R += table->subtables[y].keys - isolated; - } + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - checkR = 0; - for (z = xHigh; z > x; z--) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + if (R != checkR) { + (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); } - } - if (R != checkR) { - (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); - } #endif - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddLinearAndSiftingDownOutOfMem; - newsize = cuddLinearInPlace(table,x,y); - if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize >= size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingDownOutOfMem; newsize = cuddLinearInPlace(table,x,y); if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; - if (newsize != size) { - (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); } - } else if (cuddTestInteract(table,xindex,yindex)) { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - ddUpdateInteractionMatrix(table,xindex,yindex); - } - move->size = size; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - x = y; - y = cuddNextHigh(table,x); + move->size = size; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); } return(moves); ddLinearAndSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -712,26 +1245,26 @@ ddLinearAndSiftingBackward( Move * moves) { Move *move; - int res; + int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - res = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { - res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); - } + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } return(1); @@ -759,45 +1292,45 @@ ddUndoMoves( Move *invmoves = NULL; Move *move; Move *invmove; - int size; + int size; for (move = moves; move != NULL; move = move->next) { - invmove = (Move *) cuddDynamicAllocNode(table); - if (invmove == NULL) goto ddUndoMovesOutOfMem; - invmove->x = move->x; - invmove->y = move->y; - invmove->next = invmoves; - invmoves = invmove; - if (move->flags == CUDD_SWAP_MOVE) { - invmove->flags = CUDD_SWAP_MOVE; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; - size = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto ddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ #ifdef DD_DEBUG - (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); #endif - invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - size = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } - invmove->size = size; + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } + invmove->size = size; } return(invmoves); ddUndoMovesOutOfMem: while (invmoves != NULL) { - move = invmoves->next; - cuddDeallocNode(table, (DdNode *) invmoves); - invmoves = move; + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -805,506 +1338,7 @@ ddUndoMovesOutOfMem: /**Function******************************************************************** - - Synopsis [Linearly combines two adjacent variables.] - - Description [Linearly combines two adjacent variables. Specifically, - replaces the top variable with the exclusive nor of the two variables. - It assumes that no dead nodes are present on entry to this - procedure. The procedure then guarantees that no dead nodes will be - present when it terminates. cuddLinearInPlace assumes that x < - y. Returns the number of keys in the table if successful; 0 - otherwise.] - - SideEffects [The two subtables corrresponding to variables x and y are - modified. The global counters of the unique table are also affected.] - - SeeAlso [cuddSwapInPlace] - -******************************************************************************/ -static int -cuddLinearInPlace( - DdManager * table, - int x, - int y) -{ - DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; - int oldxkeys, oldykeys; - int newxkeys, newykeys; - int comple, newcomplement; - int i; - int posn; - int isolated; - DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; - DdNode *g,*next,*last = NULL; // Suppress "might be used uninitialized" - DdNodePtr *previousP; - DdNode *tmp; - DdNode *sentinel = &(table->sentinel); -#if DD_DEBUG - int count, idcheck; -#endif - -#ifdef DD_DEBUG - assert(x < y); - assert(cuddNextHigh(table,x) == y); - assert(table->subtables[x].keys != 0); - assert(table->subtables[y].keys != 0); - assert(table->subtables[x].dead == 0); - assert(table->subtables[y].dead == 0); -#endif - - xindex = table->invperm[x]; - yindex = table->invperm[y]; - - if (cuddTestInteract(table,xindex,yindex)) { -#ifdef DD_STATS - ddTotalNumberLinearTr++; -#endif - /* Get parameters of x subtable. */ - xlist = table->subtables[x].nodelist; - oldxkeys = table->subtables[x].keys; - xslots = table->subtables[x].slots; - xshift = table->subtables[x].shift; - - /* Get parameters of y subtable. */ - ylist = table->subtables[y].nodelist; - oldykeys = table->subtables[y].keys; - yslots = table->subtables[y].slots; - yshift = table->subtables[y].shift; - - newxkeys = 0; - newykeys = oldykeys; - - /* Check whether the two projection functions involved in this - ** swap are isolated. At the end, we'll be able to tell how many - ** isolated projection functions are there by checking only these - ** two functions again. This is done to eliminate the isolated - ** projection functions from the node count. - */ - isolated = - ((table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1)); - - /* The nodes in the x layer are put in a chain. - ** The chain is handled as a FIFO; g points to the beginning and - ** last points to the end. - */ - g = NULL; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - if (f == sentinel) continue; - xlist[i] = sentinel; - if (g == NULL) { - g = f; - } else { - last->next = f; - } - while ((next = f->next) != sentinel) { - f = next; - } /* while there are elements in the collision chain */ - last = f; - } /* for each slot of the x subtable */ - last->next = NULL; - -#ifdef DD_COUNT - table->swapSteps += oldxkeys; -#endif - /* Take care of the x nodes that must be re-expressed. - ** They form a linked list pointed by g. - */ - f = g; - while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f1))); -#endif - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = f10 = f1; - } -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f11))); -#endif - f0 = cuddE(f); - comple = Cudd_IsComplement(f0); - f0 = Cudd_Regular(f0); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == f00) { - newf1 = f11; - cuddSatInc(newf1->ref); - } else { - /* Check ylist for triple (yindex,f11,f00). */ - posn = ddHash(f11, f00, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - previousP = &(ylist[posn]); - newf1 = *previousP; - while (f11 < cuddT(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { - cuddSatInc(newf1->ref); - } else { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto cuddLinearOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f00; - /* Insert newf1 in the collision list ylist[posn]; - ** increase the ref counts of f11 and f00. - */ - newykeys++; - newf1->next = *previousP; - *previousP = newf1; - cuddSatInc(f11->ref); - tmp = Cudd_Regular(f00); - cuddSatInc(tmp->ref); - } - } - cuddT(f) = newf1; -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(newf1))); -#endif - - /* Do the same for f0, keeping complement dots into account. */ - /* decrease ref count of f0 */ - tmp = Cudd_Regular(f0); - cuddSatDec(tmp->ref); - /* create the new E child */ - if (f01 == f10) { - newf0 = f01; - tmp = Cudd_Regular(newf0); - cuddSatInc(tmp->ref); - } else { - /* make sure f01 is regular */ - newcomplement = Cudd_IsComplement(f01); - if (newcomplement) { - f01 = Cudd_Not(f01); - f10 = Cudd_Not(f10); - } - /* Check ylist for triple (yindex,f01,f10). */ - posn = ddHash(f01, f10, yshift); - /* For each element newf0 in collision list ylist[posn]. */ - previousP = &(ylist[posn]); - newf0 = *previousP; - while (f01 < cuddT(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { - cuddSatInc(newf0->ref); - } else { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto cuddLinearOutOfMem; - newf0->index = yindex; newf0->ref = 1; - cuddT(newf0) = f01; - cuddE(newf0) = f10; - /* Insert newf0 in the collision list ylist[posn]; - ** increase the ref counts of f01 and f10. - */ - newykeys++; - newf0->next = *previousP; - *previousP = newf0; - cuddSatInc(f01->ref); - tmp = Cudd_Regular(f10); - cuddSatInc(tmp->ref); - } - if (newcomplement) { - newf0 = Cudd_Not(newf0); - } - } - cuddE(f) = newf0; - - /* Re-insert the modified f in xlist. - ** The modified f does not already exists in xlist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, xshift); - newxkeys++; - previousP = &(xlist[posn]); - tmp = *previousP; - while (newf1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; - } /* while f != NULL */ - - /* GC the y layer. */ - - /* For each node f in ylist. */ - for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - if (f->ref == 0) { - tmp = cuddT(f); - cuddSatDec(tmp->ref); - tmp = Cudd_Regular(cuddE(f)); - cuddSatDec(tmp->ref); - cuddDeallocNode(table,f); - newykeys--; - } else { - *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = sentinel; - } /* for every collision list */ - -#if DD_DEBUG -#if 0 - (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); -#endif - count = 0; - idcheck = 0; - for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) yindex) - idcheck++; - f = f->next; - } - } - if (count != newykeys) { - fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); - } - if (idcheck != 0) - fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); - count = 0; - idcheck = 0; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) xindex) - idcheck++; - f = f->next; - } - } - if (count != newxkeys || newxkeys != oldxkeys) { - fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); - } - if (idcheck != 0) - fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); -#endif - - isolated += (table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1); - table->isolated += isolated; - - /* Set the appropriate fields in table. */ - table->subtables[y].keys = newykeys; - - /* Here we should update the linear combination table - ** to record that x <- x EXNOR y. This is done by complementing - ** the (x,y) entry of the table. - */ - - table->keys += newykeys - oldykeys; - - cuddXorLinear(table,xindex,yindex); - } - -#ifdef DD_DEBUG - if (zero) { - (void) Cudd_DebugCheck(table); - } -#endif - - return(table->keys - table->isolated); - -cuddLinearOutOfMem: - (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); - - return (0); - -} /* end of cuddLinearInPlace */ - - -/**Function******************************************************************** - - Synopsis [Updates the interaction matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static void -ddUpdateInteractionMatrix( - DdManager * table, - int xindex, - int yindex) -{ - int i; - for (i = 0; i < yindex; i++) { - if (i != xindex && cuddTestInteract(table,i,yindex)) { - if (i < xindex) { - cuddSetInteract(table,i,xindex); - } else { - cuddSetInteract(table,xindex,i); - } - } - } - for (i = yindex+1; i < table->size; i++) { - if (i != xindex && cuddTestInteract(table,yindex,i)) { - if (i < xindex) { - cuddSetInteract(table,i,xindex); - } else { - cuddSetInteract(table,xindex,i); - } - } - } - -} /* end of ddUpdateInteractionMatrix */ - - -/**Function******************************************************************** - - Synopsis [Initializes the linear transform matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static int -cuddInitLinear( - DdManager * table) -{ - int words; - int wordsPerRow; - int nvars; - int word; - int bit; - int i; - long *linear; - nvars = table->size; - wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; - words = wordsPerRow * nvars; - table->linear = linear = ABC_ALLOC(long,words); - if (linear == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); - } - table->memused += words * sizeof(long); - table->linearSize = nvars; - for (i = 0; i < words; i++) linear[i] = 0; - for (i = 0; i < nvars; i++) { - word = wordsPerRow * i + (i >> LOGBPL); - bit = i & (BPL-1); - linear[word] = 1 << bit; - } - return(1); - -} /* end of cuddInitLinear */ - - -/**Function******************************************************************** - - Synopsis [Resizes the linear transform matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static int -cuddResizeLinear( - DdManager * table) -{ - int words,oldWords; - int wordsPerRow,oldWordsPerRow; - int nvars,oldNvars; - int word,oldWord; - int bit; - int i,j; - long *linear,*oldLinear; - - oldNvars = table->linearSize; - oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; - oldWords = oldWordsPerRow * oldNvars; - oldLinear = table->linear; - - nvars = table->size; - wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; - words = wordsPerRow * nvars; - table->linear = linear = ABC_ALLOC(long,words); - if (linear == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); - } - table->memused += (words - oldWords) * sizeof(long); - for (i = 0; i < words; i++) linear[i] = 0; - - /* Copy old matrix. */ - for (i = 0; i < oldNvars; i++) { - for (j = 0; j < oldWordsPerRow; j++) { - oldWord = oldWordsPerRow * i + j; - word = wordsPerRow * i + j; - linear[word] = oldLinear[oldWord]; - } - } - ABC_FREE(oldLinear); - - /* Add elements to the diagonal. */ - for (i = oldNvars; i < nvars; i++) { - word = wordsPerRow * i + (i >> LOGBPL); - bit = i & (BPL-1); - linear[word] = 1 << bit; - } - table->linearSize = nvars; - - return(1); - -} /* end of cuddResizeLinear */ - - -/**Function******************************************************************** - Synopsis [XORs two rows of the linear transform matrix.] Description [XORs two rows of the linear transform matrix and replaces @@ -1329,10 +1363,11 @@ cuddXorLinear( long *linear = table->linear; for (i = 0; i < wordsPerRow; i++) { - linear[xstart+i] ^= linear[ystart+i]; + linear[xstart+i] ^= linear[ystart+i]; } } /* end of cuddXorLinear */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLiteral.c b/src/bdd/cudd/cuddLiteral.c index c5684e9b..b5895fcf 100644 --- a/src/bdd/cudd/cuddLiteral.c +++ b/src/bdd/cudd/cuddLiteral.c @@ -8,20 +8,47 @@ BDDs.] Description [External procedures included in this file: - <ul> - <li> Cudd_bddLiteralSetIntersection() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddBddLiteralSetIntersectionRecur() - </ul>] + <ul> + <li> Cudd_bddLiteralSetIntersection() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddBddLiteralSetIntersectionRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -49,7 +77,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.8 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -95,8 +123,8 @@ Cudd_bddLiteralSetIntersection( DdNode *res; do { - dd->reordered = 0; - res = cuddBddLiteralSetIntersectionRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddLiteralSetIntersectionRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -155,27 +183,27 @@ cuddBddLiteralSetIntersectionRecur( ** loop will stop when the constant node is reached in both cubes. */ while (topf != topg) { - if (topf < topg) { /* move down on f */ - comple = f != F; - f = cuddT(F); - if (comple) f = Cudd_Not(f); - if (f == zero) { - f = cuddE(F); - if (comple) f = Cudd_Not(f); - } - F = Cudd_Regular(f); - topf = cuddI(dd,F->index); - } else if (topg < topf) { - comple = g != G; - g = cuddT(G); - if (comple) g = Cudd_Not(g); - if (g == zero) { - g = cuddE(G); - if (comple) g = Cudd_Not(g); + if (topf < topg) { /* move down on f */ + comple = f != F; + f = cuddT(F); + if (comple) f = Cudd_Not(f); + if (f == zero) { + f = cuddE(F); + if (comple) f = Cudd_Not(f); + } + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + } else if (topg < topf) { + comple = g != G; + g = cuddT(G); + if (comple) g = Cudd_Not(g); + if (g == zero) { + g = cuddE(G); + if (comple) g = Cudd_Not(g); + } + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); } - G = Cudd_Regular(g); - topg = cuddI(dd,G->index); - } } /* At this point, f == one <=> g == 1. It suffices to test one of them. */ @@ -183,7 +211,7 @@ cuddBddLiteralSetIntersectionRecur( res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g); if (res != NULL) { - return(res); + return(res); } /* Here f and g are both non constant and have the same top variable. */ @@ -192,39 +220,39 @@ cuddBddLiteralSetIntersectionRecur( phasef = 1; if (comple) fc = Cudd_Not(fc); if (fc == zero) { - fc = cuddE(F); - phasef = 0; - if (comple) fc = Cudd_Not(fc); + fc = cuddE(F); + phasef = 0; + if (comple) fc = Cudd_Not(fc); } comple = g != G; gc = cuddT(G); phaseg = 1; if (comple) gc = Cudd_Not(gc); if (gc == zero) { - gc = cuddE(G); - phaseg = 0; - if (comple) gc = Cudd_Not(gc); + gc = cuddE(G); + phaseg = 0; + if (comple) gc = Cudd_Not(gc); } tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc); if (tmp == NULL) { - return(NULL); + return(NULL); } if (phasef != phaseg) { - res = tmp; - } else { - cuddRef(tmp); - if (phasef == 0) { - res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + res = tmp; } else { - res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); - } - if (res == NULL) { - Cudd_RecursiveDeref(dd,tmp); - return(NULL); - } - cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ + cuddRef(tmp); + if (phasef == 0) { + res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + } else { + res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ } cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res); @@ -238,5 +266,7 @@ cuddBddLiteralSetIntersectionRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddMatMult.c b/src/bdd/cudd/cuddMatMult.c index b4ec5c6a..f78d037d 100644 --- a/src/bdd/cudd/cuddMatMult.c +++ b/src/bdd/cudd/cuddMatMult.c @@ -7,25 +7,52 @@ Synopsis [Matrix multiplication functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_addMatrixMultiply() - <li> Cudd_addTimesPlus() - <li> Cudd_addTriangle() - <li> Cudd_addOuterSum() - </ul> - Static procedures included in this module: - <ul> - <li> addMMRecur() - <li> addTriangleRecur() - <li> cuddAddOuterSumRecur() - </ul>] + <ul> + <li> Cudd_addMatrixMultiply() + <li> Cudd_addTimesPlus() + <li> Cudd_addTriangle() + <li> Cudd_addOuterSum() + </ul> + Static procedures included in this module: + <ul> + <li> addMMRecur() + <li> addTriangleRecur() + <li> cuddAddOuterSumRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -36,6 +63,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -56,7 +84,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.17 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -70,9 +98,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addMMRecur ARGS((DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars)); -static DdNode * addTriangleRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube)); -static DdNode * cuddAddOuterSumRecur ARGS((DdManager *dd, DdNode *M, DdNode *r, DdNode *c)); +static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars); +static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube); +static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); /**AutomaticEnd***************************************************************/ @@ -115,8 +143,8 @@ Cudd_addMatrixMultiply( nvars = dd->size; vars = ABC_ALLOC(int,nvars); if (vars == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < nvars; i++) { vars[i] = 0; @@ -126,8 +154,8 @@ Cudd_addMatrixMultiply( } do { - dd->reordered = 0; - res = addMMRecur(dd,A,B,-1,vars); + dd->reordered = 0; + res = addMMRecur(dd,A,B,-1,vars); } while (dd->reordered == 1); ABC_FREE(vars); return(res); @@ -168,20 +196,20 @@ Cudd_addTimesPlus( Cudd_Ref(tmp); Cudd_Ref(cube = DD_ONE(dd)); for (i = nz-1; i >= 0; i--) { - w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); - if (w == NULL) { - Cudd_RecursiveDeref(dd,tmp); - return(NULL); - } - Cudd_Ref(w); - Cudd_RecursiveDeref(dd,cube); - cube = w; + w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); + if (w == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; } res = Cudd_addExistAbstract(dd,tmp,cube); if (res == NULL) { - Cudd_RecursiveDeref(dd,tmp); - Cudd_RecursiveDeref(dd,cube); - return(NULL); + Cudd_RecursiveDeref(dd,tmp); + Cudd_RecursiveDeref(dd,cube); + return(NULL); } Cudd_Ref(res); Cudd_RecursiveDeref(dd,cube); @@ -225,21 +253,21 @@ Cudd_addTriangle( nvars = dd->size; vars = ABC_ALLOC(int, nvars); if (vars == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < nvars; i++) vars[i] = -1; for (i = 0; i < nz; i++) vars[z[i]->index] = i; cube = Cudd_addComputeCube(dd, z, NULL, nz); if (cube == NULL) { - ABC_FREE(vars); - return(NULL); + ABC_FREE(vars); + return(NULL); } cuddRef(cube); do { - dd->reordered = 0; - res = addTriangleRecur(dd, f, g, vars, cube); + dd->reordered = 0; + res = addTriangleRecur(dd, f, g, vars, cube); } while (dd->reordered == 1); if (res != NULL) cuddRef(res); Cudd_RecursiveDeref(dd,cube); @@ -274,8 +302,8 @@ Cudd_addOuterSum( DdNode *res; do { - dd->reordered = 0; - res = cuddAddOuterSumRecur(dd, M, r, c); + dd->reordered = 0; + res = cuddAddOuterSumRecur(dd, M, r, c); } while (dd->reordered == 1); return(res); @@ -310,21 +338,21 @@ addMMRecur( int * vars) { DdNode *zero, - *At, /* positive cofactor of first operand */ - *Ae, /* negative cofactor of first operand */ - *Bt, /* positive cofactor of second operand */ - *Be, /* negative cofactor of second operand */ - *t, /* positive cofactor of result */ - *e, /* negative cofactor of result */ - *scaled, /* scaled result */ - *add_scale, /* ADD representing the scaling factor */ - *res; - int i; /* loop index */ - double scale; /* scaling factor */ - int index; /* index of the top variable */ + *At, /* positive cofactor of first operand */ + *Ae, /* negative cofactor of first operand */ + *Bt, /* positive cofactor of second operand */ + *Be, /* negative cofactor of second operand */ + *t, /* positive cofactor of result */ + *e, /* negative cofactor of result */ + *scaled, /* scaled result */ + *add_scale, /* ADD representing the scaling factor */ + *res; + int i; /* loop index */ + double scale; /* scaling factor */ + int index; /* index of the top variable */ CUDD_VALUE_TYPE value; unsigned int topA, topB, topV; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(dd); zero = DD_ZERO(dd); @@ -334,21 +362,21 @@ addMMRecur( } if (cuddIsConstant(A) && cuddIsConstant(B)) { - /* Compute the scaling factor. It is 2^k, where k is the - ** number of summation variables below the current variable. - ** Indeed, these constants represent blocks of 2^k identical - ** constant values in both A and B. - */ - value = cuddV(A) * cuddV(B); - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP) { - value *= (CUDD_VALUE_TYPE) 2; + /* Compute the scaling factor. It is 2^k, where k is the + ** number of summation variables below the current variable. + ** Indeed, these constants represent blocks of 2^k identical + ** constant values in both A and B. + */ + value = cuddV(A) * cuddV(B); + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP) { + value *= (CUDD_VALUE_TYPE) 2; + } + } } - } - } - res = cuddUniqueConst(dd, value); - return(res); + res = cuddUniqueConst(dd, value); + return(res); } /* Standardize to increase cache efficiency. Clearly, A*B != B*A @@ -357,67 +385,67 @@ addMMRecur( ** which one is passed as first argument. */ if (A > B) { - DdNode *tmp = A; - A = B; - B = tmp; + DdNode *tmp = A; + A = B; + B = tmp; } topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); topV = ddMin(topA,topB); - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) addMMRecur; + cacheOp = (DD_CTFP) addMMRecur; res = cuddCacheLookup2(dd,cacheOp,A,B); if (res != NULL) { - /* If the result is 0, there is no need to normalize. - ** Otherwise we count the number of z variables between - ** the current depth and the top of the ADDs. These are - ** the missing variables that determine the size of the - ** constant blocks. - */ - if (res == zero) return(res); - scale = 1.0; - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { - scale *= 2; - } - } - } - if (scale > 1.0) { - cuddRef(res); - add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); - if (add_scale == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + /* If the result is 0, there is no need to normalize. + ** Otherwise we count the number of z variables between + ** the current depth and the top of the ADDs. These are + ** the missing variables that determine the size of the + ** constant blocks. + */ + if (res == zero) return(res); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } } - cuddRef(add_scale); - scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); - if (scaled == NULL) { - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - return(NULL); + if (scale > 1.0) { + cuddRef(res); + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + cuddDeref(res); } - cuddRef(scaled); - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - res = scaled; - cuddDeref(res); - } return(res); } /* compute the cofactors */ if (topV == topA) { - At = cuddT(A); - Ae = cuddE(A); + At = cuddT(A); + Ae = cuddE(A); } else { - At = Ae = A; + At = Ae = A; } if (topV == topB) { - Bt = cuddT(B); - Be = cuddE(B); + Bt = cuddT(B); + Be = cuddE(B); } else { - Bt = Be = B; + Bt = Be = B; } t = addMMRecur(dd, At, Bt, (int)topV, vars); @@ -425,39 +453,39 @@ addMMRecur( cuddRef(t); e = addMMRecur(dd, Ae, Be, (int)topV, vars); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); index = dd->invperm[topV]; if (vars[index] == 0) { - /* We have split on either the rows of A or the columns - ** of B. We just need to connect the two subresults, - ** which correspond to two submatrices of the result. - */ - res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); - if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - cuddDeref(t); - cuddDeref(e); + /* We have split on either the rows of A or the columns + ** of B. We just need to connect the two subresults, + ** which correspond to two submatrices of the result. + */ + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + cuddDeref(t); + cuddDeref(e); } else { - /* we have simultaneously split on the columns of A and - ** the rows of B. The two subresults must be added. - */ - res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); - if (res == NULL) { + /* we have simultaneously split on the columns of A and + ** the rows of B. The two subresults must be added. + */ + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd, t); Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); } cuddCacheInsert2(dd,cacheOp,A,B,res); @@ -469,32 +497,32 @@ addMMRecur( ** scaling the result. */ if (res != zero) { - scale = 1.0; - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { - scale *= 2; - } - } - } - if (scale > 1.0) { - add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); - if (add_scale == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } } - cuddRef(add_scale); - scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); - if (scaled == NULL) { - Cudd_RecursiveDeref(dd, res); - Cudd_RecursiveDeref(dd, add_scale); - return(NULL); + if (scale > 1.0) { + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, res); + Cudd_RecursiveDeref(dd, add_scale); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; } - cuddRef(scaled); - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - res = scaled; - } } cuddDeref(res); return(res); @@ -526,25 +554,25 @@ addTriangleRecur( statLine(dd); if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) { - return(DD_PLUS_INFINITY(dd)); + return(DD_PLUS_INFINITY(dd)); } if (cuddIsConstant(f) && cuddIsConstant(g)) { - value = cuddV(f) + cuddV(g); - res = cuddUniqueConst(dd, value); - return(res); + value = cuddV(f) + cuddV(g); + res = cuddUniqueConst(dd, value); + return(res); } if (f < g) { - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } if (f->ref != 1 || g->ref != 1) { - res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); - if (res != NULL) { - return(res); - } + res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); + if (res != NULL) { + return(res); + } } topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); @@ -558,36 +586,36 @@ addTriangleRecur( cuddRef(t); e = addTriangleRecur(dd, fvn, gvn, vars, cube); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); index = dd->invperm[top]; if (vars[index] < 0) { - res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); - if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } else { - res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); - if (res == NULL) { + res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd, t); Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - cuddDeref(res); + cuddDeref(res); } if (f->ref != 1 || g->ref != 1) { - cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); + cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); } return(res); @@ -623,23 +651,23 @@ cuddAddOuterSumRecur( if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); if (cuddIsConstant(c) && cuddIsConstant(r)) { - R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); - cuddRef(R); - if (cuddIsConstant(M)) { - if (cuddV(R) <= cuddV(M)) { - cuddDeref(R); - return(R); + R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); + cuddRef(R); + if (cuddIsConstant(M)) { + if (cuddV(R) <= cuddV(M)) { + cuddDeref(R); + return(R); + } else { + Cudd_RecursiveDeref(dd,R); + return(M); + } } else { - Cudd_RecursiveDeref(dd,R); - return(M); + P = Cudd_addApply(dd,Cudd_addMinimum,R,M); + cuddRef(P); + Cudd_RecursiveDeref(dd,R); + cuddDeref(P); + return(P); } - } else { - P = Cudd_addApply(dd,Cudd_addMinimum,R,M); - cuddRef(P); - Cudd_RecursiveDeref(dd,R); - cuddDeref(P); - return(P); - } } /* Check the cache. */ @@ -661,16 +689,16 @@ cuddAddOuterSumRecur( cuddRef(Rt); Re = cuddAddOuterSumRecur(dd,Me,re,ce); if (Re == NULL) { - Cudd_RecursiveDeref(dd, Rt); - return(NULL); + Cudd_RecursiveDeref(dd, Rt); + return(NULL); } cuddRef(Re); index = dd->invperm[v]; R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re); if (R == NULL) { - Cudd_RecursiveDeref(dd, Rt); - Cudd_RecursiveDeref(dd, Re); - return(NULL); + Cudd_RecursiveDeref(dd, Rt); + Cudd_RecursiveDeref(dd, Re); + return(NULL); } cuddDeref(Rt); cuddDeref(Re); @@ -681,5 +709,7 @@ cuddAddOuterSumRecur( return(R); } /* end of cuddAddOuterSumRecur */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c index f67fb88a..188d2c9e 100644 --- a/src/bdd/cudd/cuddPriority.c +++ b/src/bdd/cudd/cuddPriority.c @@ -7,39 +7,69 @@ Synopsis [Priority functions.] Description [External procedures included in this file: - <ul> - <li> Cudd_PrioritySelect() - <li> Cudd_Xgty() - <li> Cudd_Xeqy() - <li> Cudd_addXeqy() - <li> Cudd_Dxygtdxz() - <li> Cudd_Dxygtdyz() - <li> Cudd_CProjection() - <li> Cudd_addHamming() - <li> Cudd_MinHammingDist() - <li> Cudd_bddClosestCube() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddCProjectionRecur() - <li> cuddBddClosestCube() - </ul> - Static procedures included in this module: - <ul> - <li> cuddMinHammingDistRecur() - <li> separateCube() - <li> createResult() - </ul> - ] + <ul> + <li> Cudd_PrioritySelect() + <li> Cudd_Xgty() + <li> Cudd_Xeqy() + <li> Cudd_addXeqy() + <li> Cudd_Dxygtdxz() + <li> Cudd_Dxygtdyz() + <li> Cudd_Inequality() + <li> Cudd_Disequality() + <li> Cudd_bddInterval() + <li> Cudd_CProjection() + <li> Cudd_addHamming() + <li> Cudd_MinHammingDist() + <li> Cudd_bddClosestCube() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddCProjectionRecur() + <li> cuddBddClosestCube() + </ul> + Static procedures included in this module: + <ul> + <li> cuddMinHammingDistRecur() + <li> separateCube() + <li> createResult() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -50,10 +80,12 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ +#define DD_DEBUG 1 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -70,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.33 2009/02/20 02:14:58 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -83,9 +115,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23: /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddMinHammingDistRecur ARGS((DdNode * f, int *minterm, DdHashTable * table, int upperBound)); -static DdNode * separateCube ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance)); -static DdNode * createResult ARGS((DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance)); +static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound); +static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance); +static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance); /**AutomaticEnd***************************************************************/ @@ -148,7 +180,7 @@ Cudd_PrioritySelect( DdNode ** z /* array of z variables (optional: may be NULL) */, DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, int n /* size of x, y, and z */, - DdNode * (*Pifunc)(DdManager *, int, DdNode **, DdNode **, DdNode **) /* function used to build Pi if it is NULL */) + DD_PRFP Pifunc /* function used to build Pi if it is NULL */) { DdNode *res = NULL; DdNode *zcube = NULL; @@ -159,38 +191,38 @@ Cudd_PrioritySelect( /* Create z variables if needed. */ if (z == NULL) { - if (Pi != NULL) return(NULL); - z = ABC_ALLOC(DdNode *,n); - if (z == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - createdZ = 1; - for (i = 0; i < n; i++) { - if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; - z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); - if (z[i] == NULL) goto endgame; - } + if (Pi != NULL) return(NULL); + z = ABC_ALLOC(DdNode *,n); + if (z == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + createdZ = 1; + for (i = 0; i < n; i++) { + if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; + z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + if (z[i] == NULL) goto endgame; + } } /* Create priority function BDD if needed. */ if (Pi == NULL) { - Pi = Pifunc(dd,n,x,y,z); - if (Pi == NULL) goto endgame; - createdPi = 1; - cuddRef(Pi); + Pi = Pifunc(dd,n,x,y,z); + if (Pi == NULL) goto endgame; + createdPi = 1; + cuddRef(Pi); } /* Initialize abstraction cube. */ zcube = DD_ONE(dd); cuddRef(zcube); for (i = n - 1; i >= 0; i--) { - DdNode *tmpp; - tmpp = Cudd_bddAnd(dd,z[i],zcube); - if (tmpp == NULL) goto endgame; - cuddRef(tmpp); - Cudd_RecursiveDeref(dd,zcube); - zcube = tmpp; + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,z[i],zcube); + if (tmpp == NULL) goto endgame; + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,zcube); + zcube = tmpp; } /* Compute subset of (x,y) pairs. */ @@ -199,15 +231,15 @@ Cudd_PrioritySelect( cuddRef(Rxz); Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); if (Q == NULL) { - Cudd_RecursiveDeref(dd,Rxz); - goto endgame; + Cudd_RecursiveDeref(dd,Rxz); + goto endgame; } cuddRef(Q); Cudd_RecursiveDeref(dd,Rxz); res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); if (res == NULL) { - Cudd_RecursiveDeref(dd,Q); - goto endgame; + Cudd_RecursiveDeref(dd,Q); + goto endgame; } cuddRef(res); Cudd_RecursiveDeref(dd,Q); @@ -215,10 +247,10 @@ Cudd_PrioritySelect( endgame: if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); if (createdZ) { - ABC_FREE(z); + ABC_FREE(z); } if (createdPi) { - Cudd_RecursiveDeref(dd,Pi); + Cudd_RecursiveDeref(dd,Pi); } if (res != NULL) cuddDeref(res); return(res); @@ -234,7 +266,7 @@ endgame: Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: + It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. Argument z is not used by Cudd_Xgty: it is included to make it call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] @@ -262,29 +294,29 @@ Cudd_Xgty( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { + v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); - if (u == NULL) { + u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); @@ -301,7 +333,7 @@ Cudd_Xgty( Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: + It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] SideEffects [None] @@ -326,29 +358,29 @@ Cudd_Xeqy( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], u); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { + v = Cudd_bddAnd(dd, y[i], u); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], v, w); - if (u == NULL) { + u = Cudd_bddIte(dd, x[i], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); return(u); @@ -364,7 +396,7 @@ Cudd_Xeqy( Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The ADD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: + It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] SideEffects [None] @@ -392,15 +424,15 @@ Cudd_addXeqy( cuddRef(v); w = Cudd_addIte(dd, y[N-1], zero, one); if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - return(NULL); + Cudd_RecursiveDeref(dd, v); + return(NULL); } cuddRef(w); u = Cudd_addIte(dd, x[N-1], v, w); - if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); } cuddRef(u); Cudd_RecursiveDeref(dd, v); @@ -408,29 +440,29 @@ Cudd_addXeqy( /* Loop to build the rest of the ADD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_addIte(dd, y[i], u, zero); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_addIte(dd, y[i], zero, u); - if (w == NULL) { + v = Cudd_addIte(dd, y[i], u, zero); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_addIte(dd, y[i], zero, u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_addIte(dd, x[i], v, w); - if (w == NULL) { + u = Cudd_addIte(dd, x[i], v, w); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); return(u); @@ -448,9 +480,9 @@ Cudd_addXeqy( y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], with 0 the most significant bit. The distance d(x,y) is defined as: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: + It has 7*N-3 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] SideEffects [None] @@ -479,15 +511,15 @@ Cudd_Dxygtdxz( cuddRef(y1_); y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); } cuddRef(y2); x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); } cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); @@ -495,69 +527,69 @@ Cudd_Dxygtdxz( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], x1, zero); - if (z4 == NULL) { + z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], x1, zero); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, z3); - if (y2 == NULL) { + y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, z3); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); Cudd_RecursiveDeref(dd, z1); Cudd_RecursiveDeref(dd, z2); Cudd_RecursiveDeref(dd, z3); Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, y2); - if (x1 == NULL) { + x1 = Cudd_bddIte(dd, x[i], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); } cuddDeref(x1); return(Cudd_Not(x1)); @@ -575,9 +607,9 @@ Cudd_Dxygtdxz( y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], with 0 the most significant bit. The distance d(x,y) is defined as: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: + It has 7*N-3 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] SideEffects [None] @@ -606,15 +638,15 @@ Cudd_Dxygtdyz( cuddRef(y1_); y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); } cuddRef(y2); x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); } cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); @@ -622,69 +654,69 @@ Cudd_Dxygtdyz( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], x1, zero); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z4 == NULL) { + z1 = Cudd_bddIte(dd, z[i], x1, zero); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, z1); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); - if (y2 == NULL) { + y1_ = Cudd_bddIte(dd, y[i], z2, z1); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); Cudd_RecursiveDeref(dd, z1); Cudd_RecursiveDeref(dd, z2); Cudd_RecursiveDeref(dd, z3); Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); - if (x1 == NULL) { + x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); } cuddDeref(x1); return(Cudd_Not(x1)); @@ -694,6 +726,464 @@ Cudd_Dxygtdyz( /**Function******************************************************************** + Synopsis [Generates a BDD for the function x - y ≥ c.] + + Description [This function generates a BDD for the function x -y ≥ c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Inequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrue = c; + int kFalse = c - 1; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2] = {0}; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c >= 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c) return(zero); + else if ((-(1 << N) + 1) >= c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLower, kFalseLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLower = kTrue; + kFalseLower = kFalse; + /* kTrue = ceiling((c-1)/2^i) + 1 */ + kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; + mask = (mask << 1) | 1; + /* kFalse = floor(c/2^i) - 1 */ + kFalse = (c >> i) - 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kFalse + 1; j < kTrue; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLower) { + fminus = one; + } else if (leftChild <= kFalseLower) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLower) { + fequal = one; + } else if (middleChild <= kFalseLower) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLower) { + fplus = one; + } else if (rightChild <= kFalseLower) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Inequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function x - y != c.] + + Description [This function generates a BDD for the function x -y != c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Disequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrueLb = c + 1; + int kTrueUb = c - 1; + int kFalse = c; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2] = {0}; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c != 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLbLower, kTrueUbLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLbLower = kTrueLb; + kTrueUbLower = kTrueUb; + /* kTrueLb = floor((c-1)/2^i) + 2 */ + kTrueLb = ((c-1) >> i) + 2; + /* kTrueUb = ceiling((c+1)/2^i) - 2 */ + kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; + mask = (mask << 1) | 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kTrueUb + 1; j < kTrueLb; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { + fminus = one; + } else if (i == 1 && leftChild == kFalse) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { + fequal = one; + } else if (i == 1 && middleChild == kFalse) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { + fplus = one; + } else if (i == 1 && rightChild == kFalse) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Disequality */ + + +/**Function******************************************************************** + + Synopsis [Generates a BDD for the function lowerB ≤ x ≤ upperB.] + + Description [This function generates a BDD for the function + lowerB ≤ x ≤ upperB, where x is an N-bit number, + x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). + The number of variables N should be sufficient to represent the bounds; + otherwise, the bounds are truncated to their N least significant bits. + Two BDDs are built bottom-up for lowerB ≤ x and x ≤ upperB, and they + are finally conjoined.] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_bddInterval( + DdManager * dd /* DD manager */, + int N /* number of x variables */, + DdNode ** x /* array of x variables */, + unsigned int lowerB /* lower bound */, + unsigned int upperB /* upper bound */) +{ + DdNode *one, *zero; + DdNode *r, *rl, *ru; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + rl = one; + cuddRef(rl); + ru = one; + cuddRef(ru); + + /* Loop to build the rest of the BDDs. */ + for (i = N-1; i >= 0; i--) { + DdNode *vl, *vu; + vl = Cudd_bddIte(dd, x[i], + lowerB&1 ? rl : one, + lowerB&1 ? zero : rl); + if (vl == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vl); + Cudd_IterDerefBdd(dd, rl); + rl = vl; + lowerB >>= 1; + vu = Cudd_bddIte(dd, x[i], + upperB&1 ? ru : zero, + upperB&1 ? one : ru); + if (vu == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vu); + Cudd_IterDerefBdd(dd, ru); + ru = vu; + upperB >>= 1; + } + + /* Conjoin the two bounds. */ + r = Cudd_bddAnd(dd, rl, ru); + if (r == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + cuddDeref(r); + return(r); + +} /* end of Cudd_bddInterval */ + + +/**Function******************************************************************** + Synopsis [Computes the compatible projection of R w.r.t. cube Y.] Description [Computes the compatible projection of relation R with @@ -716,10 +1206,10 @@ Cudd_CProjection( DdNode *support; if (cuddCheckCube(dd,Y) == 0) { - (void) fprintf(dd->err, - "Error: The third argument of Cudd_CProjection should be a cube\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(dd->err, + "Error: The third argument of Cudd_CProjection should be a cube\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } /* Compute the support of Y, which is used by the abstraction step @@ -730,13 +1220,13 @@ Cudd_CProjection( cuddRef(support); do { - dd->reordered = 0; - res = cuddCProjectionRecur(dd,R,Y,support); + dd->reordered = 0; + res = cuddCProjectionRecur(dd,R,Y,support); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd,support); - return(NULL); + Cudd_RecursiveDeref(dd,support); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,support); @@ -776,30 +1266,30 @@ Cudd_addHamming( cuddRef(result); for (i = 0; i < nVars; i++) { - tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); - if (tempBdd == NULL) { - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempBdd); - tempAdd = Cudd_BddToAdd(dd,tempBdd); - if (tempAdd == NULL) { + tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); + if (tempBdd == NULL) { + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempBdd); + tempAdd = Cudd_BddToAdd(dd,tempBdd); + if (tempAdd == NULL) { + Cudd_RecursiveDeref(dd,tempBdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempAdd); Cudd_RecursiveDeref(dd,tempBdd); - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempAdd); - Cudd_RecursiveDeref(dd,tempBdd); - temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); - if (temp == NULL) { + temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); + if (temp == NULL) { + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(temp); Cudd_RecursiveDeref(dd,tempAdd); Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(temp); - Cudd_RecursiveDeref(dd,tempAdd); - Cudd_RecursiveDeref(dd,result); - result = temp; + result = temp; } cuddDeref(result); @@ -837,7 +1327,7 @@ Cudd_MinHammingDist( table = cuddHashTableInit(dd,1,2); if (table == NULL) { - return(CUDD_OUT_OF_MEM); + return(CUDD_OUT_OF_MEM); } epsilon = Cudd_ReadEpsilon(dd); Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); @@ -846,7 +1336,7 @@ Cudd_MinHammingDist( Cudd_SetEpsilon(dd,epsilon); return(res); - + } /* end of Cudd_MinHammingDist */ @@ -877,32 +1367,32 @@ Cudd_bddClosestCube( /* Compute the cube and distance as a single ADD. */ do { - dd->reordered = 0; - res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); + dd->reordered = 0; + res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); } while (dd->reordered == 1); if (res == NULL) return(NULL); cuddRef(res); /* Unpack distance and cube. */ do { - dd->reordered = 0; - acube = separateCube(dd, res, &rdist); + dd->reordered = 0; + acube = separateCube(dd, res, &rdist); } while (dd->reordered == 1); if (acube == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + Cudd_RecursiveDeref(dd, res); + return(NULL); } cuddRef(acube); Cudd_RecursiveDeref(dd, res); /* Convert cube from ADD to BDD. */ do { - dd->reordered = 0; - res = cuddAddBddDoPattern(dd, acube); + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, acube); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, acube); - return(NULL); + Cudd_RecursiveDeref(dd, acube); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, acube); @@ -940,8 +1430,7 @@ cuddCProjectionRecur( { DdNode *res, *res1, *res2, *resA; DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; - unsigned int topR, topY, top; - unsigned int index = 0; // Suppress "might be used uninitialized" + unsigned int topR, topY, top, index; DdNode *one = DD_ONE(dd); statLine(dd); @@ -965,114 +1454,114 @@ cuddCProjectionRecur( /* Compute the cofactors of R */ if (topR == top) { - index = r->index; - RT = cuddT(r); - RE = cuddE(r); - if (r != R) { - RT = Cudd_Not(RT); RE = Cudd_Not(RE); - } + index = r->index; + RT = cuddT(r); + RE = cuddE(r); + if (r != R) { + RT = Cudd_Not(RT); RE = Cudd_Not(RE); + } } else { - RT = RE = R; + RT = RE = R; } if (topY > top) { - /* Y does not depend on the current top variable. - ** We just need to compute the results on the two cofactors of R - ** and make them the children of a node labeled r->index. - */ - res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); - } - cuddRef(res2); - res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); - } - /* If we have reached this point, res1 and res2 are now - ** incorporated in res. cuddDeref is therefore sufficient. - */ - cuddDeref(res1); - cuddDeref(res2); - } else { - /* Compute the cofactors of Y */ - index = y->index; - YT = cuddT(y); - YE = cuddE(y); - if (y != Y) { - YT = Cudd_Not(YT); YE = Cudd_Not(YE); - } - if (YT == Cudd_Not(one)) { - Alpha = Cudd_Not(dd->vars[index]); - Yrest = YE; - Ra = RE; - Ran = RT; - } else { - Alpha = dd->vars[index]; - Yrest = YT; - Ra = RT; - Ran = RE; - } - Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); - if (Gamma == NULL) return(NULL); - if (Gamma == one) { - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + /* Y does not depend on the current top variable. + ** We just need to compute the results on the two cofactors of R + ** and make them the children of a node labeled r->index. + */ + res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); if (res1 == NULL) return(NULL); cuddRef(res1); - res = cuddBddAndRecur(dd, Alpha, res1); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); + res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); } - cuddDeref(res1); - } else if (Gamma == Cudd_Not(one)) { - res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + cuddRef(res2); + res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); } + /* If we have reached this point, res1 and res2 are now + ** incorporated in res. cuddDeref is therefore sufficient. + */ cuddDeref(res1); + cuddDeref(res2); } else { - cuddRef(Gamma); - resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (resA == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - return(NULL); - } - cuddRef(resA); - res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - return(NULL); + /* Compute the cofactors of Y */ + index = y->index; + YT = cuddT(y); + YE = cuddE(y); + if (y != Y) { + YT = Cudd_Not(YT); YE = Cudd_Not(YE); } - cuddRef(res2); - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); - if (res1 == NULL) { - Cudd_RecursiveDeref(dd,res2); - return(NULL); + if (YT == Cudd_Not(one)) { + Alpha = Cudd_Not(dd->vars[index]); + Yrest = YE; + Ra = RE; + Ran = RT; + } else { + Alpha = dd->vars[index]; + Yrest = YT; + Ra = RT; + Ran = RE; } - cuddRef(res1); - res = cuddBddIteRecur(dd, Alpha, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); + Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); + if (Gamma == NULL) return(NULL); + if (Gamma == one) { + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Alpha, res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else if (Gamma == Cudd_Not(one)) { + res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else { + cuddRef(Gamma); + resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (resA == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + return(NULL); + } + cuddRef(resA); + res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + return(NULL); + } + cuddRef(res2); + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddRef(res1); + res = cuddBddIteRecur(dd, Alpha, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); } - cuddDeref(res1); - cuddDeref(res2); - } } cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); @@ -1089,14 +1578,64 @@ cuddCProjectionRecur( Description [Performs the recursive step of Cudd_bddClosestCube. Returns the cube if succesful; NULL otherwise. The procedure uses a four-way recursion to examine all four combinations of cofactors of - f and g. The most interesting feature of this function is the - scheme used for caching the results in the global computed table. - Since we have a cube and a distance, we combine them to form an ADD. - The combination replaces the zero child of the top node of the cube - with the negative of the distance. (The use of the negative is to - avoid ambiguity with 1.) The degenerate cases (zero and one) are - treated specially because the distance is known (0 for one, and - infinity for zero).] + <code>f</code> and <code>g</code> according to the following formula. + <pre> + H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1) + </pre> + Bounding is based on the following observations. + <ul> + <li> If we already found two points at distance 0, there is no point in + continuing. Furthermore, + <li> If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) + </ul> + The variable <code>bound</code> is set at the largest value of the distance + that we are still interested in. Therefore, we desist when + <pre> + (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)). + </pre> + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant + <pre> + bound < minD, + </pre> + except at the very beginning, when we have no value for + <code>minD</code>.<p> + + However, we do not use <code>bound < minD</code> when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.<p> + + When we compute <code>H(ft,ge)</code> and <code>H(fe,gt)</code> we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.<p> + + Another important observation concerns the need of examining all + four pairs of cofators only when both <code>f</code> and + <code>g</code> depend on the top variable.<p> + + Suppose <code>gt == ge == g</code>. (That is, <code>g</code> does + not depend on the top variable.) Then + <pre> + H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1) + = min(H(ft,g), H(fe,g)) . + </pre> + Therefore, under these circumstances, we skip the two "cross" cases.<p> + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero).] SideEffects [None] @@ -1119,7 +1658,7 @@ cuddBddClosestCube( unsigned int topf, topg, index; statLine(dd); - if (bound < (f == Cudd_Not(g))) return(azero); + if (bound < (int)(f == Cudd_Not(g))) return(azero); /* Terminal cases. */ if (g == lzero || f == lzero) return(azero); if (f == one && g == one) return(one); @@ -1128,9 +1667,8 @@ cuddBddClosestCube( F = Cudd_Regular(f); G = Cudd_Regular(g); if (F->ref != 1 || G->ref != 1) { - res = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g); - if (res != NULL) return(res); + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); + if (res != NULL) return(res); } topf = cuddI(dd,F->index); @@ -1138,27 +1676,27 @@ cuddBddClosestCube( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg <= topf) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } tt = cuddBddClosestCube(dd,ft,gt,bound); @@ -1166,8 +1704,8 @@ cuddBddClosestCube( cuddRef(tt); ctt = separateCube(dd,tt,&dtt); if (ctt == NULL) { - Cudd_RecursiveDeref(dd, tt); - return(NULL); + Cudd_RecursiveDeref(dd, tt); + return(NULL); } cuddRef(ctt); Cudd_RecursiveDeref(dd, tt); @@ -1176,86 +1714,99 @@ cuddBddClosestCube( ee = cuddBddClosestCube(dd,fe,ge,bound); if (ee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - return(NULL); + Cudd_RecursiveDeref(dd, ctt); + return(NULL); } cuddRef(ee); cee = separateCube(dd,ee,&dee); if (cee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, ee); - return(NULL); + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, ee); + return(NULL); } cuddRef(cee); Cudd_RecursiveDeref(dd, ee); minD = ddMin(dtt, dee); - bound = ddMin(bound,minD-1); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); if (minD > 0 && topf == topg) { - DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); - if (te == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - return(NULL); - } - cuddRef(te); - cte = separateCube(dd,te,&dte); - if (cte == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); + DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); + if (te == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + return(NULL); + } + cuddRef(te); + cte = separateCube(dd,te,&dte); + if (cte == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, te); + return(NULL); + } + cuddRef(cte); Cudd_RecursiveDeref(dd, te); - return(NULL); - } - cuddRef(cte); - Cudd_RecursiveDeref(dd, te); - dte += 1.0; - minD = ddMin(minD, dte); + dte += 1.0; + minD = ddMin(minD, dte); } else { - cte = azero; - cuddRef(cte); - dte = CUDD_CONST_INDEX + 1.0; + cte = azero; + cuddRef(cte); + dte = CUDD_CONST_INDEX + 1.0; } - bound = ddMin(bound,minD-1); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); if (minD > 0 && topf == topg) { - DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); - if (et == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); - return(NULL); - } - cuddRef(et); - cet = separateCube(dd,et,&det); - if (cet == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); + DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); + if (et == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + return(NULL); + } + cuddRef(et); + cet = separateCube(dd,et,&det); + if (cet == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, et); + return(NULL); + } + cuddRef(cet); Cudd_RecursiveDeref(dd, et); - return(NULL); - } - cuddRef(cet); - Cudd_RecursiveDeref(dd, et); - det += 1.0; - minD = ddMin(minD, det); + det += 1.0; + minD = ddMin(minD, det); } else { - cet = azero; - cuddRef(cet); - det = CUDD_CONST_INDEX + 1.0; + cet = azero; + cuddRef(cet); + det = CUDD_CONST_INDEX + 1.0; } if (minD == dtt) { - if (dtt == dee && ctt == cee) { - res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); - } else { - res = createResult(dd,index,1,ctt,dtt); - } + if (dtt == dee && ctt == cee) { + res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); + } else { + res = createResult(dd,index,1,ctt,dtt); + } } else if (minD == dee) { - res = createResult(dd,index,0,cee,dee); + res = createResult(dd,index,0,cee,dee); } else if (minD == dte) { - res = createResult(dd,index,(topf <= topg),cte,dte); +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,1,cte,dte); } else { - res = createResult(dd,index,(topf > topg),cet,det); +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,0,cet,det); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, ctt); @@ -1263,9 +1814,10 @@ cuddBddClosestCube( Cudd_RecursiveDeref(dd, cte); Cudd_RecursiveDeref(dd, cet); - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g, res); + /* Only cache results that are different from azero to avoid + ** storing results that depend on the value of the bound. */ + if ((F->ref != 1 || G->ref != 1) && res != azero) + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); cuddDeref(res); return(res); @@ -1309,10 +1861,10 @@ cuddMinHammingDistRecur( DdHashTable * table, int upperBound) { - DdNode *F, *Ft, *Fe; - double h, hT, hE; - DdNode *zero, *res; - DdManager *dd = table->manager; + DdNode *F, *Ft, *Fe; + double h, hT, hE; + DdNode *zero, *res; + DdManager *dd = table->manager; statLine(dd); if (upperBound == 0) return(0); @@ -1320,49 +1872,49 @@ cuddMinHammingDistRecur( F = Cudd_Regular(f); if (cuddIsConstant(F)) { - zero = Cudd_Not(DD_ONE(dd)); - if (f == dd->background || f == zero) { - return(upperBound); - } else { - return(0); - } + zero = Cudd_Not(DD_ONE(dd)); + if (f == dd->background || f == zero) { + return(upperBound); + } else { + return(0); + } } if ((res = cuddHashTableLookup1(table,f)) != NULL) { - h = cuddV(res); - if (res->ref == 0) { - dd->dead++; - dd->constants.dead++; - } - return((int) h); + h = cuddV(res); + if (res->ref == 0) { + dd->dead++; + dd->constants.dead++; + } + return((int) h); } Ft = cuddT(F); Fe = cuddE(F); if (Cudd_IsComplement(f)) { - Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); + Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); } if (minterm[F->index] == 0) { - DdNode *temp = Ft; - Ft = Fe; Fe = temp; + DdNode *temp = Ft; + Ft = Fe; Fe = temp; } hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); if (hT == 0) { - hE = upperBound; + hE = upperBound; } else { - hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); - if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); + if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); } h = ddMin(hT, hE + 1); if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - cuddRef(res); Cudd_RecursiveDeref(dd, res); - return(CUDD_OUT_OF_MEM); - } + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(dd, res); + return(CUDD_OUT_OF_MEM); + } } return((int) h); @@ -1392,9 +1944,9 @@ separateCube( /* One and zero are special cases because the distance is implied. */ if (Cudd_IsConstant(f)) { - *distance = (f == DD_ONE(dd)) ? 0.0 : - (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); - return(f); + *distance = (f == DD_ONE(dd)) ? 0.0 : + (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); + return(f); } /* Find out which branch points to the distance and replace the top @@ -1402,16 +1954,16 @@ separateCube( t = cuddT(f); if (Cudd_IsConstant(t) && cuddV(t) <= 0) { #ifdef DD_DEBUG - assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); + assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); #endif - *distance = -cuddV(t); - cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); + *distance = -cuddV(t); + cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); } else { #ifdef DD_DEBUG - assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); + assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); #endif - *distance = -cuddV(cuddE(f)); - cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); + *distance = -cuddV(cuddE(f)); + cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); } return(cube); @@ -1443,7 +1995,7 @@ createResult( /* Special case. The cube is either one or zero, and we do not ** add any variables. Hence, the result is also one or zero, - ** and the distance remains implied by teh value of the constant. */ + ** and the distance remains implied by the value of the constant. */ if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); constant = cuddUniqueConst(dd,-distance); @@ -1451,31 +2003,33 @@ createResult( cuddRef(constant); if (index == CUDD_CONST_INDEX) { - /* Replace the top node. */ - if (cuddT(cube) == DD_ZERO(dd)) { - res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); - } else { - res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); - } + /* Replace the top node. */ + if (cuddT(cube) == DD_ZERO(dd)) { + res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); + } else { + res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); + } } else { - /* Add a new top node. */ + /* Add a new top node. */ #ifdef DD_DEBUG - assert(cuddI(dd,index) < cuddI(dd,cube->index)); + assert(cuddI(dd,index) < cuddI(dd,cube->index)); #endif - if (phase) { - res = cuddUniqueInter(dd,index,cube,constant); - } else { - res = cuddUniqueInter(dd,index,constant,cube); - } + if (phase) { + res = cuddUniqueInter(dd,index,cube,constant); + } else { + res = cuddUniqueInter(dd,index,constant,cube); + } } if (res == NULL) { - Cudd_RecursiveDeref(dd, constant); - return(NULL); + Cudd_RecursiveDeref(dd, constant); + return(NULL); } cuddDeref(constant); /* safe because constant is part of res */ return(res); } /* end of createResult */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddRead.c b/src/bdd/cudd/cuddRead.c index 52670a6c..06789589 100644 --- a/src/bdd/cudd/cuddRead.c +++ b/src/bdd/cudd/cuddRead.c @@ -7,19 +7,46 @@ Synopsis [Functions to read in a matrix] Description [External procedures included in this module: - <ul> - <li> Cudd_addRead() - <li> Cudd_bddRead() - </ul>] + <ul> + <li> Cudd_addRead() + <li> Cudd_bddRead() + </ul>] SeeAlso [cudd_addHarwell.c] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -30,6 +57,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -50,7 +78,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.6 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -145,85 +173,85 @@ Cudd_addRead( err = fscanf(fp, "%d %d", &u, &v); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { - return(0); + return(0); } *m = u; /* Compute the number of x variables. */ lx = *x; lxn = *xn; - u--; /* row and column numbers start from 0 */ + u--; /* row and column numbers start from 0 */ for (lnx=0; u > 0; lnx++) { - u >>= 1; + u >>= 1; } - /* Here we rely on the fact that ABC_REALLOC of a null pointer is - ** translates to an ABC_ALLOC. + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. */ if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); - if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } *n = v; /* Compute the number of y variables. */ ly = *y; lyn = *yn_; - v--; /* row and column numbers start from 0 */ + v--; /* row and column numbers start from 0 */ for (lny=0; v > 0; lny++) { - v >>= 1; + v >>= 1; } - /* Here we rely on the fact that ABC_REALLOC of a null pointer is - ** translates to an ABC_ALLOC. + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. */ if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); - if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *y = ly = ABC_REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } /* Create all new variables. */ for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); - do { - dd->reordered = 0; - lxn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lxn[i] == NULL) return(0); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); cuddRef(lxn[i]); } for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); - do { - dd->reordered = 0; - lyn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lyn[i] == NULL) return(0); - cuddRef(lyn[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); } *nx = lnx; *ny = lny; @@ -232,69 +260,69 @@ Cudd_addRead( cuddRef(*E); while (! feof(fp)) { - err = fscanf(fp, "%d %d %lf", &u, &v, &val); - if (err == EOF) { - break; - } else if (err != 3) { - return(0); - } else if (u >= *m || v >= *n || u < 0 || v < 0) { - return(0); - } + err = fscanf(fp, "%d %d %lf", &u, &v, &val); + if (err == EOF) { + break; + } else if (err != 3) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } - minterm1 = one; cuddRef(minterm1); - - /* Build minterm1 corresponding to this arc */ - for (i = lnx - 1; i>=0; i--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + u >>= 1; } - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - u >>= 1; - } - for (i = lny - 1; i>=0; i--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + /* Create new constant node if necessary. + ** This call will never cause reordering. + */ + neW = cuddUniqueConst(dd, val); + if (neW == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); } + cuddRef(neW); + + w = Cudd_addIte(dd, minterm1, neW, *E); if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + return(0); } cuddRef(w); Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - v >>= 1; - } - /* Create new constant node if necessary. - ** This call will never cause reordering. - */ - neW = cuddUniqueConst(dd, val); - if (neW == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); - } - cuddRef(neW); - - w = Cudd_addIte(dd, minterm1, neW, *E); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); Cudd_RecursiveDeref(dd, neW); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, neW); - Cudd_RecursiveDeref(dd, *E); - *E = w; + Cudd_RecursiveDeref(dd, *E); + *E = w; } return(1); @@ -365,57 +393,57 @@ Cudd_bddRead( err = fscanf(fp, "%d %d", &u, &v); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { - return(0); + return(0); } *m = u; /* Compute the number of x variables. */ lx = *x; - u--; /* row and column numbers start from 0 */ + u--; /* row and column numbers start from 0 */ for (lnx=0; u > 0; lnx++) { - u >>= 1; + u >>= 1; } if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } *n = v; /* Compute the number of y variables. */ ly = *y; - v--; /* row and column numbers start from 0 */ + v--; /* row and column numbers start from 0 */ for (lny=0; v > 0; lny++) { - v >>= 1; + v >>= 1; } if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *y = ly = ABC_REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } /* Create all new variables. */ for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); } for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); } *nx = lnx; *ny = lny; @@ -424,59 +452,59 @@ Cudd_bddRead( cuddRef(*E); while (! feof(fp)) { - err = fscanf(fp, "%d %d", &u, &v); - if (err == EOF) { - break; - } else if (err != 2) { - return(0); - } else if (u >= *m || v >= *n || u < 0 || v < 0) { - return(0); - } - - minterm1 = one; cuddRef(minterm1); - - /* Build minterm1 corresponding to this arc. */ - for (i = lnx - 1; i>=0; i--) { - if (u & 1) { - w = Cudd_bddAnd(dd, minterm1, lx[i]); - } else { - w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + break; + } else if (err != 2) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); } - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc. */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_bddAnd(dd, minterm1, lx[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd,minterm1); + minterm1 = w; + u >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd,minterm1); - minterm1 = w; - u >>= 1; - } - for (i = lny - 1; i>=0; i--) { - if (v & 1) { - w = Cudd_bddAnd(dd, minterm1, ly[i]); - } else { - w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_bddAnd(dd, minterm1, ly[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; } + + w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + Cudd_RecursiveDeref(dd, minterm1); + return(0); } + w = Cudd_Not(w); cuddRef(w); Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - v >>= 1; - } - - w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); - } - w = Cudd_Not(w); - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; + Cudd_RecursiveDeref(dd, *E); + *E = w; } return(1); @@ -491,5 +519,7 @@ Cudd_bddRead( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddRef.c b/src/bdd/cudd/cuddRef.c index a8f654af..183d30ca 100644 --- a/src/bdd/cudd/cuddRef.c +++ b/src/bdd/cudd/cuddRef.c @@ -7,43 +7,71 @@ Synopsis [Functions that manipulate the reference counts.] Description [External procedures included in this module: - <ul> - <li> Cudd_Ref() - <li> Cudd_RecursiveDeref() - <li> Cudd_IterDerefBdd() - <li> Cudd_DelayedDerefBdd() - <li> Cudd_RecursiveDerefZdd() - <li> Cudd_Deref() - <li> Cudd_CheckZeroRef() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddReclaim() - <li> cuddReclaimZdd() - <li> cuddClearDeathRow() - <li> cuddShrinkDeathRow() - <li> cuddIsInDeathRow() - <li> cuddTimesInDeathRow() - </ul> - ] + <ul> + <li> Cudd_Ref() + <li> Cudd_RecursiveDeref() + <li> Cudd_IterDerefBdd() + <li> Cudd_DelayedDerefBdd() + <li> Cudd_RecursiveDerefZdd() + <li> Cudd_Deref() + <li> Cudd_CheckZeroRef() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddReclaim() + <li> cuddReclaimZdd() + <li> cuddClearDeathRow() + <li> cuddShrinkDeathRow() + <li> cuddIsInDeathRow() + <li> cuddTimesInDeathRow() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.28 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -134,35 +162,35 @@ Cudd_RecursiveDeref( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } N = Cudd_Regular(n); do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - if (cuddIsConstant(N)) { - table->constants.dead++; - N = stack[--SP]; + if (cuddIsConstant(N)) { + table->constants.dead++; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } } else { - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); + cuddSatDec(N->ref); + N = stack[--SP]; } - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } } while (SP != 0); } /* end of Cudd_RecursiveDeref */ @@ -197,30 +225,30 @@ Cudd_IterDerefBdd( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } N = Cudd_Regular(n); do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } } while (SP != 0); } /* end of Cudd_IterDerefBdd */ @@ -254,7 +282,7 @@ Cudd_DelayedDerefBdd( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } n = Cudd_Regular(n); @@ -267,10 +295,10 @@ Cudd_DelayedDerefBdd( #else if (cuddIsConstant(n) || n->ref > 1) { #ifdef DD_DEBUG - assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); + assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); #endif - cuddSatDec(n->ref); - return; + cuddSatDec(n->ref); + return; } N = table->deathRow[table->nextDead]; @@ -278,29 +306,29 @@ Cudd_DelayedDerefBdd( if (N != NULL) { #endif #ifdef DD_DEBUG - assert(!Cudd_IsComplement(N)); + assert(!Cudd_IsComplement(N)); #endif - stack = table->stack; - SP = 1; - do { + stack = table->stack; + SP = 1; + do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } - } while (SP != 0); + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); #ifndef DD_NO_DEATH_ROW } table->deathRow[table->nextDead] = n; @@ -310,29 +338,29 @@ Cudd_DelayedDerefBdd( table->nextDead &= table->deadMask; #if 0 if (table->nextDead == table->deathRowDepth) { - if (table->deathRowDepth < table->looseUpTo / 2) { -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long) = MMoutOfMemory; - DdNodePtr *newRow; - MMoutOfMemory = Cudd_OutOfMem; - newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); - MMoutOfMemory = saveHandler; - if (newRow == NULL) { - table->nextDead = 0; + if (table->deathRowDepth < table->looseUpTo / 2) { + extern void (*MMoutOfMemory)(long); + void (*saveHandler)(long) = MMoutOfMemory; + DdNodePtr *newRow; + MMoutOfMemory = Cudd_OutOfMem; + newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); + MMoutOfMemory = saveHandler; + if (newRow == NULL) { + table->nextDead = 0; + } else { + int i; + table->memused += table->deathRowDepth; + i = table->deathRowDepth; + table->deathRowDepth <<= 1; + for (; i < table->deathRowDepth; i++) { + newRow[i] = NULL; + } + table->deadMask = table->deathRowDepth - 1; + table->deathRow = newRow; + } } else { - int i; - table->memused += table->deathRowDepth; - i = table->deathRowDepth; - table->deathRowDepth <<= 1; - for (; i < table->deathRowDepth; i++) { - newRow[i] = NULL; + table->nextDead = 0; } - table->deadMask = table->deathRowDepth - 1; - table->deathRow = newRow; - } - } else { - table->nextDead = 0; - } } #endif #endif @@ -367,26 +395,26 @@ Cudd_RecursiveDerefZdd( do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - cuddSatDec(N->ref); + cuddSatDec(N->ref); - if (N->ref == 0) { - table->deadZ++; + if (N->ref == 0) { + table->deadZ++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif #ifdef DD_DEBUG - assert(!cuddIsConstant(N)); + assert(!cuddIsConstant(N)); #endif - ord = table->permZ[N->index]; - stack[SP++] = cuddE(N); - table->subtableZ[ord].dead++; - N = cuddT(N); - } else { - N = stack[--SP]; - } + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead++; + N = cuddT(N); + } else { + N = stack[--SP]; + } } while (SP != 0); } /* end of Cudd_RecursiveDerefZdd */ @@ -440,7 +468,7 @@ Cudd_CheckZeroRef( { int size; int i, j; - int remain; /* the expected number of remaining references to one */ + int remain; /* the expected number of remaining references to one */ DdNodePtr *nodelist; DdNode *node; DdNode *sentinel = &(manager->sentinel); @@ -455,53 +483,53 @@ Cudd_CheckZeroRef( /* First look at the BDD/ADD subtables. */ remain = 1; /* reference from the manager */ size = manager->size; - remain += 2 * size; /* reference from the BDD projection functions */ + remain += 2 * size; /* reference from the BDD projection functions */ for (i = 0; i < size; i++) { - subtable = &(manager->subtables[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - while (node != sentinel) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - index = (int) node->index; - if (node != manager->vars[index]) { - count++; - } else { - if (node->ref != 1) { - count++; - } + subtable = &(manager->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != sentinel) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node != manager->vars[index]) { + count++; + } else { + if (node->ref != 1) { + count++; + } + } + } + node = node->next; } } - node = node->next; - } - } } /* Then look at the ZDD subtables. */ size = manager->sizeZ; if (size) /* references from ZDD universe */ - remain += 2; + remain += 2; for (i = 0; i < size; i++) { - subtable = &(manager->subtableZ[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - while (node != NULL) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - index = (int) node->index; - if (node == manager->univ[manager->permZ[index]]) { - if (node->ref > 2) { - count++; - } - } else { - count++; + subtable = &(manager->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node == manager->univ[manager->permZ[index]]) { + if (node->ref > 2) { + count++; + } + } else { + count++; + } + } + node = node->next; } } - node = node->next; - } - } } /* Now examine the constant table. Plusinfinity, minusinfinity, and @@ -511,25 +539,25 @@ Cudd_CheckZeroRef( */ nodelist = manager->constants.nodelist; for (j = 0; (unsigned) j < manager->constants.slots; j++) { - node = nodelist[j]; - while (node != NULL) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - if (node == manager->one) { - if ((int) node->ref != remain) { - count++; - } - } else if (node == manager->zero || - node == manager->plusinfinity || - node == manager->minusinfinity) { - if (node->ref != 1) { - count++; + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + if (node == manager->one) { + if ((int) node->ref != remain) { + count++; + } + } else if (node == manager->zero || + node == manager->plusinfinity || + node == manager->minusinfinity) { + if (node->ref != 1) { + count++; + } + } else { + count++; + } } - } else { - count++; - } + node = node->next; } - node = node->next; - } } return(count); @@ -570,22 +598,22 @@ cuddReclaim( #endif do { - if (N->ref == 0) { - N->ref = 1; - table->dead--; - if (cuddIsConstant(N)) { - table->constants.dead--; - N = stack[--SP]; + if (N->ref == 0) { + N->ref = 1; + table->dead--; + if (cuddIsConstant(N)) { + table->constants.dead--; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead--; + N = cuddT(N); + } } else { - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead--; - N = cuddT(N); + cuddSatInc(N->ref); + N = stack[--SP]; } - } else { - cuddSatInc(N->ref); - N = stack[--SP]; - } } while (SP != 0); N = Cudd_Regular(n); @@ -623,21 +651,21 @@ cuddReclaimZdd( #endif do { - cuddSatInc(N->ref); + cuddSatInc(N->ref); - if (N->ref == 1) { - table->deadZ--; - table->reclaimed++; + if (N->ref == 1) { + table->deadZ--; + table->reclaimed++; #ifdef DD_DEBUG - assert(!cuddIsConstant(N)); + assert(!cuddIsConstant(N)); #endif - ord = table->permZ[N->index]; - stack[SP++] = cuddE(N); - table->subtableZ[ord].dead--; - N = cuddT(N); - } else { - N = stack[--SP]; - } + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead--; + N = cuddT(N); + } else { + N = stack[--SP]; + } } while (SP != 0); cuddSatDec(n->ref); @@ -664,18 +692,18 @@ cuddShrinkDeathRow( int i; if (table->deathRowDepth > 3) { - for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { - if (table->deathRow[i] == NULL) break; - Cudd_IterDerefBdd(table,table->deathRow[i]); - table->deathRow[i] = NULL; - } - table->deathRowDepth /= 4; - table->deadMask = table->deathRowDepth - 2; - if ((unsigned) table->nextDead > table->deadMask) { - table->nextDead = 0; - } - table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow, - table->deathRowDepth); + for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } + table->deathRowDepth /= 4; + table->deadMask = table->deathRowDepth - 1; + if ((unsigned) table->nextDead > table->deadMask) { + table->nextDead = 0; + } + table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow, + table->deathRowDepth); } #endif @@ -702,13 +730,13 @@ cuddClearDeathRow( int i; for (i = 0; i < table->deathRowDepth; i++) { - if (table->deathRow[i] == NULL) break; - Cudd_IterDerefBdd(table,table->deathRow[i]); - table->deathRow[i] = NULL; + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; } #ifdef DD_DEBUG for (; i < table->deathRowDepth; i++) { - assert(table->deathRow[i] == NULL); + assert(table->deathRow[i] == NULL); } #endif table->nextDead = 0; @@ -739,9 +767,9 @@ cuddIsInDeathRow( int i; for (i = 0; i < dd->deathRowDepth; i++) { - if (f == dd->deathRow[i]) { - return(i); - } + if (f == dd->deathRow[i]) { + return(i); + } } #endif @@ -771,7 +799,7 @@ cuddTimesInDeathRow( int i; for (i = 0; i < dd->deathRowDepth; i++) { - count += f == dd->deathRow[i]; + count += f == dd->deathRow[i]; } #endif @@ -782,5 +810,7 @@ cuddTimesInDeathRow( /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddReorder.c b/src/bdd/cudd/cuddReorder.c index 020a1b5e..383be18a 100644 --- a/src/bdd/cudd/cuddReorder.c +++ b/src/bdd/cudd/cuddReorder.c @@ -7,41 +7,68 @@ Synopsis [Functions for dynamic variable reordering.] Description [External procedures included in this file: - <ul> - <li> Cudd_ReduceHeap() - <li> Cudd_ShuffleHeap() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddDynamicAllocNode() - <li> cuddSifting() - <li> cuddSwapping() - <li> cuddNextHigh() - <li> cuddNextLow() - <li> cuddSwapInPlace() - <li> cuddBddAlignToZdd() - </ul> - Static procedures included in this module: - <ul> - <li> ddUniqueCompare() - <li> ddSwapAny() - <li> ddSiftingAux() - <li> ddSiftingUp() - <li> ddSiftingDown() - <li> ddSiftingBackward() - <li> ddReorderPreprocess() - <li> ddReorderPostprocess() - <li> ddShuffle() - <li> ddSiftUp() - <li> bddFixTree() - </ul>] + <ul> + <li> Cudd_ReduceHeap() + <li> Cudd_ShuffleHeap() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddDynamicAllocNode() + <li> cuddSifting() + <li> cuddSwapping() + <li> cuddNextHigh() + <li> cuddNextLow() + <li> cuddSwapInPlace() + <li> cuddBddAlignToZdd() + </ul> + Static procedures included in this module: + <ul> + <li> ddUniqueCompare() + <li> ddSwapAny() + <li> ddSiftingAux() + <li> ddSiftingUp() + <li> ddSiftingDown() + <li> ddSiftingBackward() + <li> ddReorderPreprocess() + <li> ddReorderPostprocess() + <li> ddShuffle() + <li> ddSiftUp() + <li> bddFixTree() + </ul>] Author [Shipra Panda, Bernard Plessier, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -51,6 +78,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -71,14 +99,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.69 2009/02/21 18:24:10 fabio Exp $"; #endif -static int *entry; +static int *entry; -int ddTotalNumberSwapping; +int ddTotalNumberSwapping; #ifdef DD_STATS -int ddTotalNISwaps; +int ddTotalNISwaps; #endif /*---------------------------------------------------------------------------*/ @@ -91,19 +119,19 @@ int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddUniqueCompare ARGS((int *ptrX, int *ptrY)); -static Move * ddSwapAny ARGS((DdManager *table, int x, int y)); -static int ddSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddSiftingUp ARGS((DdManager *table, int y, int xLow)); -static Move * ddSiftingDown ARGS((DdManager *table, int x, int xHigh)); -static int ddSiftingBackward ARGS((DdManager *table, int size, Move *moves)); -static int ddReorderPreprocess ARGS((DdManager *table)); -static int ddReorderPostprocess ARGS((DdManager *table)); -static int ddShuffle ARGS((DdManager *table, int *permutation)); -static int ddSiftUp ARGS((DdManager *table, int x, int xLow)); -static void bddFixTree ARGS((DdManager *table, MtrNode *treenode)); -static int ddUpdateMtrTree ARGS((DdManager *table, MtrNode *treenode, int *perm, int *invperm)); -static int ddCheckPermuation ARGS((DdManager *table, MtrNode *treenode, int *perm, int *invperm)); +static int ddUniqueCompare (int *ptrX, int *ptrY); +static Move * ddSwapAny (DdManager *table, int x, int y); +static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSiftingDown (DdManager *table, int x, int xHigh); +static int ddSiftingBackward (DdManager *table, int size, Move *moves); +static int ddReorderPreprocess (DdManager *table); +static int ddReorderPostprocess (DdManager *table); +static int ddShuffle (DdManager *table, int *permutation); +static int ddSiftUp (DdManager *table, int x, int xLow); +static void bddFixTree (DdManager *table, MtrNode *treenode); +static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm); +static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm); /**AutomaticEnd***************************************************************/ @@ -151,24 +179,23 @@ Cudd_ReduceHeap( int minsize /* bound below which no reordering occurs */) { DdHook *hook; - int result; + int result; unsigned int nextDyn; #ifdef DD_STATS unsigned int initialSize; unsigned int finalSize; #endif long localTime; - int TimeStop = table->TimeStop; /* Don't reorder if there are too many dead nodes. */ if (table->keys - table->dead < (unsigned) minsize) - return(1); + return(1); if (heuristic == CUDD_REORDER_SAME) { - heuristic = table->autoMethod; + heuristic = table->autoMethod; } if (heuristic == CUDD_REORDER_NONE) { - return(1); + return(1); } /* This call to Cudd_ReduceHeap does initiate reordering. Therefore @@ -181,16 +208,16 @@ Cudd_ReduceHeap( /* Run the hook functions. */ hook = table->preReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "BDD", (void *)heuristic); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "BDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; } if (!ddReorderPreprocess(table)) return(0); ddTotalNumberSwapping = 0; - + if (table->keys > table->peakLiveNodes) { - table->peakLiveNodes = table->keys; + table->peakLiveNodes = table->keys; } #ifdef DD_STATS initialSize = table->keys - table->isolated; @@ -199,89 +226,89 @@ Cudd_ReduceHeap( switch(heuristic) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - (void) fprintf(table->out,"#:I_RANDOM "); - break; + (void) fprintf(table->out,"#:I_RANDOM "); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: case CUDD_REORDER_GROUP_SIFT: case CUDD_REORDER_GROUP_SIFT_CONV: - (void) fprintf(table->out,"#:I_SIFTING "); - break; + (void) fprintf(table->out,"#:I_SIFTING "); + break; case CUDD_REORDER_WINDOW2: case CUDD_REORDER_WINDOW3: case CUDD_REORDER_WINDOW4: case CUDD_REORDER_WINDOW2_CONV: case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: - (void) fprintf(table->out,"#:I_WINDOW "); - break; + (void) fprintf(table->out,"#:I_WINDOW "); + break; case CUDD_REORDER_ANNEALING: - (void) fprintf(table->out,"#:I_ANNEAL "); - break; + (void) fprintf(table->out,"#:I_ANNEAL "); + break; case CUDD_REORDER_GENETIC: - (void) fprintf(table->out,"#:I_GENETIC "); - break; + (void) fprintf(table->out,"#:I_GENETIC "); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - (void) fprintf(table->out,"#:I_LINSIFT "); - break; + (void) fprintf(table->out,"#:I_LINSIFT "); + break; case CUDD_REORDER_EXACT: - (void) fprintf(table->out,"#:I_EXACT "); - break; + (void) fprintf(table->out,"#:I_EXACT "); + break; default: - return(0); + return(0); } - (void) fprintf(table->out,"%8d: initial size",initialSize); + (void) fprintf(table->out,"%8d: initial size",initialSize); #endif /* See if we should use alternate threshold for maximum growth. */ if (table->reordCycle && table->reorderings % table->reordCycle == 0) { - double saveGrowth = table->maxGrowth; - table->maxGrowth = table->maxGrowthAlt; - result = cuddTreeSifting(table,heuristic,TimeStop); - table->maxGrowth = saveGrowth; + double saveGrowth = table->maxGrowth; + table->maxGrowth = table->maxGrowthAlt; + result = cuddTreeSifting(table,heuristic); + table->maxGrowth = saveGrowth; } else { - result = cuddTreeSifting(table,heuristic,TimeStop); + result = cuddTreeSifting(table,heuristic); } #ifdef DD_STATS (void) fprintf(table->out,"\n"); finalSize = table->keys - table->isolated; - (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", - ddTotalNumberSwapping); + ddTotalNumberSwapping); (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); #endif if (result == 0) - return(0); + return(0); if (!ddReorderPostprocess(table)) - return(0); + return(0); if (table->realign) { - if (!cuddZddAlignToBdd(table)) - return(0); + if (!cuddZddAlignToBdd(table)) + return(0); } nextDyn = (table->keys - table->constants.keys + 1) * - DD_DYN_RATIO + table->constants.keys; + DD_DYN_RATIO + table->constants.keys; if (table->reorderings < 20 || nextDyn > table->nextDyn) - table->nextDyn = nextDyn; + table->nextDyn = nextDyn; else - table->nextDyn += 20; + table->nextDyn += 20; table->reordered = 1; /* Run hook functions. */ hook = table->postReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "BDD", (void *)localTime); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "BDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; } /* Update cumulative reordering time. */ table->reordTime += util_cpu_time() - localTime; @@ -313,36 +340,36 @@ Cudd_ShuffleHeap( int * permutation /* required variable permutation */) { - int result; + int result; int i; int identity = 1; int *perm; /* Don't waste time in case of identity permutation. */ for (i = 0; i < table->size; i++) { - if (permutation[i] != table->invperm[i]) { - identity = 0; - break; - } + if (permutation[i] != table->invperm[i]) { + identity = 0; + break; + } } if (identity == 1) { - return(1); + return(1); } if (!ddReorderPreprocess(table)) return(0); if (table->keys > table->peakLiveNodes) { - table->peakLiveNodes = table->keys; + table->peakLiveNodes = table->keys; } perm = ABC_ALLOC(int, table->size); for (i = 0; i < table->size; i++) - perm[permutation[i]] = i; + perm[permutation[i]] = i; if (!ddCheckPermuation(table,table->tree,perm,permutation)) { - ABC_FREE(perm); - return(0); + ABC_FREE(perm); + return(0); } if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { - ABC_FREE(perm); - return(0); + ABC_FREE(perm); + return(0); } ABC_FREE(perm); @@ -382,66 +409,68 @@ cuddDynamicAllocNode( int i; DdNodePtr *mem; DdNode *list, *node; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (table->nextFree == NULL) { /* free list is empty */ - /* Try to allocate a new block. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 1); - MMoutOfMemory = saveHandler; - if (mem == NULL && table->stash != NULL) { - ABC_FREE(table->stash); - table->stash = NULL; - /* Inhibit resizing of tables. */ - table->maxCacheHard = table->cacheSlots - 1; - table->cacheSlack = -(int)(table->cacheSlots + 1); - for (i = 0; i < table->size; i++) { - table->subtables[i].maxKeys <<= 2; + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL && table->stash != NULL) { + ABC_FREE(table->stash); + table->stash = NULL; + /* Inhibit resizing of tables. */ + table->maxCacheHard = table->cacheSlots - 1; + table->cacheSlack = - (int) (table->cacheSlots + 1); + for (i = 0; i < table->size; i++) { + table->subtables[i].maxKeys <<= 2; + } + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); } - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); - } - if (mem == NULL) { - /* Out of luck. Call the default handler to do - ** whatever it specifies for a failed malloc. If this - ** handler returns, then set error code, print - ** warning, and return. */ - (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); - table->errorCode = CUDD_MEMORY_OUT; + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. If this + ** handler returns, then set error code, print + ** warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + table->errorCode = CUDD_MEMORY_OUT; #ifdef DD_VERBOSE - (void) fprintf(table->err, - "cuddDynamicAllocNode: out of memory"); - (void) fprintf(table->err,"Memory in use = %ld\n", - table->memused); + (void) fprintf(table->err, + "cuddDynamicAllocNode: out of memory"); + (void) fprintf(table->err,"Memory in use = %lu\n", + table->memused); #endif - return(NULL); - } else { /* successful allocation; slice memory */ - unsigned long offset; - table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); - mem[0] = (DdNode *) table->memoryList; - table->memoryList = mem; - - /* Here we rely on the fact that the size of a DdNode is a - ** power of 2 and a multiple of the size of a pointer. - ** If we align one node, all the others will be aligned - ** as well. */ - offset = (unsigned long) mem & (sizeof(DdNode) - 1); - mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + return(NULL); + } else { /* successful allocation; slice memory */ + unsigned long offset; + table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNode *) table->memoryList; + table->memoryList = mem; + + /* Here we rely on the fact that the size of a DdNode is a + ** power of 2 and a multiple of the size of a pointer. + ** If we align one node, all the others will be aligned + ** as well. */ + offset = (unsigned long) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); #ifdef DD_DEBUG - assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); + assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); #endif - list = (DdNode *) mem; + list = (DdNode *) mem; - i = 1; - do { - list[i - 1].next = &list[i]; - } while (++i < DD_MEM_CHUNK); + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); - list[DD_MEM_CHUNK - 1].next = NULL; + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK - 1].next = NULL; - table->nextFree = &list[0]; - } + table->nextFree = &list[0]; + } } /* if free list empty */ node = table->nextFree; @@ -476,13 +505,13 @@ cuddSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->size; @@ -491,46 +520,46 @@ cuddSifting( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - - if (x < lower || x > upper || table->subtables[x].bindVar == 1) - continue; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftingAux(table, x, lower, upper); - if (!result) goto cuddSiftingOutOfMem; + result = ddSiftingAux(table, x, lower, upper); + if (!result) goto cuddSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -544,7 +573,7 @@ cuddSiftingOutOfMem: if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - return(0); + return(0); } /* end of cuddSifting */ @@ -574,15 +603,15 @@ cuddSwapping( int upper, Cudd_ReorderingType heuristic) { - int i, j; - int max, keys; - int nvars; - int x, y; - int iterate; + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; int previousSize; Move *moves, *move; - int pivot = 0; // Suppress "might be used uninitialized" - int modulo; + int pivot; + int modulo; int result; #ifdef DD_DEBUG @@ -594,61 +623,61 @@ cuddSwapping( iterate = nvars; for (i = 0; i < iterate; i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { - max = -1; - for (j = lower; j <= upper; j++) { - if ((keys = table->subtables[j].keys) > max) { - max = keys; - pivot = j; - } - } + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + max = -1; + for (j = lower; j <= upper; j++) { + if ((keys = table->subtables[j].keys) > max) { + max = keys; + pivot = j; + } + } - modulo = upper - pivot; - if (modulo == 0) { - y = pivot; - } else{ - y = pivot + 1 + ((int) Cudd_Random() % modulo); - } + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; + } else{ + y = pivot + 1 + ((int) Cudd_Random() % modulo); + } - modulo = pivot - lower - 1; - if (modulo < 1) { - x = lower; - } else{ - do { - x = (int) Cudd_Random() % modulo; - } while (x == y); + modulo = pivot - lower - 1; + if (modulo < 1) { + x = lower; + } else{ + do { + x = (int) Cudd_Random() % modulo; + } while (x == y); + } + } else { + x = ((int) Cudd_Random() % nvars) + lower; + do { + y = ((int) Cudd_Random() % nvars) + lower; + } while (x == y); + } + previousSize = table->keys - table->isolated; + moves = ddSwapAny(table,x,y); + if (moves == NULL) goto cuddSwappingOutOfMem; + result = ddSiftingBackward(table,previousSize,moves); + if (!result) goto cuddSwappingOutOfMem; + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } - } else { - x = ((int) Cudd_Random() % nvars) + lower; - do { - y = ((int) Cudd_Random() % nvars) + lower; - } while (x == y); - } - previousSize = table->keys - table->isolated; - moves = ddSwapAny(table,x,y); - if (moves == NULL) goto cuddSwappingOutOfMem; - result = ddSiftingBackward(table,previousSize,moves); - if (!result) goto cuddSwappingOutOfMem; - while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; - } #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif #if 0 - (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", - table->keys - table->isolated); + (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", + table->keys - table->isolated); #endif } @@ -656,9 +685,9 @@ cuddSwapping( cuddSwappingOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -686,7 +715,7 @@ cuddNextHigh( return(x+1); } /* end of cuddNextHigh */ - + /**Function******************************************************************** @@ -746,10 +775,10 @@ cuddSwapInPlace( DdNodePtr *previousP; DdNode *tmp; DdNode *sentinel = &(table->sentinel); -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; -#if DD_DEBUG +#ifdef DD_DEBUG int count,idcheck; #endif @@ -766,7 +795,7 @@ cuddSwapInPlace( /* Get parameters of x subtable. */ xindex = table->invperm[x]; - xlist = table->subtables[x].nodelist; + xlist = table->subtables[x].nodelist; oldxkeys = table->subtables[x].keys; xslots = table->subtables[x].slots; xshift = table->subtables[x].shift; @@ -780,365 +809,370 @@ cuddSwapInPlace( if (!cuddTestInteract(table,xindex,yindex)) { #ifdef DD_STATS - ddTotalNISwaps++; + ddTotalNISwaps++; #endif - newxkeys = oldxkeys; - newykeys = oldykeys; + newxkeys = oldxkeys; + newykeys = oldykeys; } else { - newxkeys = 0; - newykeys = oldykeys; - - /* Check whether the two projection functions involved in this - ** swap are isolated. At the end, we'll be able to tell how many - ** isolated projection functions are there by checking only these - ** two functions again. This is done to eliminate the isolated - ** projection functions from the node count. - */ - isolated = - ((table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1)); + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); - /* The nodes in the x layer that do not depend on - ** y will stay there; the others are put in a chain. - ** The chain is handled as a LIFO; g points to the beginning. - */ - g = NULL; - if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && - oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { - for (i = 0; i < xslots; i++) { - previousP = &(xlist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if (f1->index != (DdHalfWord) yindex && - Cudd_Regular(f0)->index != (DdHalfWord) yindex) { - /* stays */ - newxkeys++; - *previousP = f; - previousP = &(f->next); - } else { - f->index = yindex; - f->next = g; - g = f; + /* The nodes in the x layer that do not depend on + ** y will stay there; the others are put in a chain. + ** The chain is handled as a LIFO; g points to the beginning. + */ + g = NULL; + if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && + oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = sentinel; + } /* for each slot of the x subtable */ + } else { /* resize xlist */ + DdNode *h = NULL; + DdNodePtr *newxlist; + unsigned int newxslots; + int newxshift; + /* Empty current xlist. Nodes that stay go to list h; + ** nodes that move go to list g. */ + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + f->next = h; + h = f; + newxkeys++; + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + /* Decide size of new subtable. */ + newxshift = xshift; + newxslots = xslots; + while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) { + newxshift--; + newxslots <<= 1; } - f = next; - } /* while there are elements in the collision chain */ - *previousP = sentinel; - } /* for each slot of the x subtable */ - } else { /* resize xlist */ - DdNode *h = NULL; - DdNodePtr *newxlist; - unsigned int newxslots; - int newxshift; - /* Empty current xlist. Nodes that stay go to list h; - ** nodes that move go to list g. */ - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if (f1->index != (DdHalfWord) yindex && - Cudd_Regular(f0)->index != (DdHalfWord) yindex) { - /* stays */ - f->next = h; - h = f; - newxkeys++; + while ((unsigned) oldxkeys < newxslots && + newxslots > table->initSlots) { + newxshift++; + newxslots >>= 1; + } + /* Try to allocate new table. Be ready to back off. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + newxlist = ABC_ALLOC(DdNodePtr, newxslots); + MMoutOfMemory = saveHandler; + if (newxlist == NULL) { + (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); + newxlist = xlist; + newxslots = xslots; + newxshift = xshift; } else { - f->index = yindex; - f->next = g; - g = f; + table->slots += ((int) newxslots - xslots); + table->minDead = (unsigned) + (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) + ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO + * table->slots) - 2 * (int) table->cacheSlots; + table->memused += + ((int) newxslots - xslots) * sizeof(DdNodePtr); + ABC_FREE(xlist); + xslots = newxslots; + xshift = newxshift; + xlist = newxlist; + } + /* Initialize new subtable. */ + for (i = 0; i < xslots; i++) { + xlist[i] = sentinel; + } + /* Move nodes that were parked in list h to their new home. */ + f = h; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f0 = cuddE(f); + /* Check xlist for pair (f11,f01). */ + posn = ddHash(f1, f0, xshift); + /* For each element tmp in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + tmp = *previousP; + while (f1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; } - f = next; - } /* while there are elements in the collision chain */ - } /* for each slot of the x subtable */ - /* Decide size of new subtable. */ - if (oldxkeys > DD_MAX_SUBTABLE_DENSITY * xslots) { - newxshift = xshift - 1; - newxslots = xslots << 1; - } else { - newxshift = xshift + 1; - newxslots = xslots >> 1; - } - /* Try to allocate new table. Be ready to back off. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - newxlist = ABC_ALLOC(DdNodePtr, newxslots); - MMoutOfMemory = saveHandler; - if (newxlist == NULL) { - (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); - newxlist = xlist; - newxslots = xslots; - newxshift = xshift; - } else { - table->slots += (newxslots - xslots); - table->minDead = (unsigned) - (table->gcFrac * (double) table->slots); - table->cacheSlack = (int) - ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO - * table->slots) - 2 * (int) table->cacheSlots; - table->memused += (newxslots - xslots) * sizeof(DdNodePtr); - ABC_FREE(xlist); - xslots = newxslots; - xshift = newxshift; - xlist = newxlist; - } - /* Initialize new subtable. */ - for (i = 0; i < xslots; i++) { - xlist[i] = sentinel; - } - /* Move nodes that were parked in list h to their new home. */ - f = h; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); - f0 = cuddE(f); - /* Check xlist for pair (f11,f01). */ - posn = ddHash(f1, f0, xshift); - /* For each element tmp in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - tmp = *previousP; - while (f1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; } - } #ifdef DD_COUNT - table->swapSteps += oldxkeys - newxkeys; + table->swapSteps += oldxkeys - newxkeys; #endif - /* Take care of the x nodes that must be re-expressed. - ** They form a linked list pointed by g. Their index has been - ** already changed to yindex. - */ - f = g; - while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** already changed to yindex. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f1))); + assert(!(Cudd_IsComplement(f1))); #endif - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = f10 = f1; - } + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f11))); + assert(!(Cudd_IsComplement(f11))); #endif - f0 = cuddE(f); - comple = Cudd_IsComplement(f0); - f0 = Cudd_Regular(f0); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == f01) { - newf1 = f11; - cuddSatInc(newf1->ref); - } else { - /* Check xlist for triple (xindex,f11,f01). */ - posn = ddHash(f11, f01, xshift); - /* For each element newf1 in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - newf1 = *previousP; - while (f11 < cuddT(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { - cuddSatInc(newf1->ref); - } else { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto cuddSwapOutOfMem; - newf1->index = xindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f01; - /* Insert newf1 in the collision list xlist[posn]; - ** increase the ref counts of f11 and f01. - */ - newxkeys++; - newf1->next = *previousP; - *previousP = newf1; - cuddSatInc(f11->ref); - tmp = Cudd_Regular(f01); - cuddSatInc(tmp->ref); - } - } - cuddT(f) = newf1; + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f01) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check xlist for triple (xindex,f11,f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[posn]; + ** increase the ref counts of f11 and f01. + */ + newxkeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f01); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(newf1))); + assert(!(Cudd_IsComplement(newf1))); #endif - /* Do the same for f0, keeping complement dots into account. */ - /* Decrease ref count of f0. */ - tmp = Cudd_Regular(f0); - cuddSatDec(tmp->ref); - /* Create the new E child. */ - if (f10 == f00) { - newf0 = f00; - tmp = Cudd_Regular(newf0); - cuddSatInc(tmp->ref); - } else { - /* make sure f10 is regular */ - newcomplement = Cudd_IsComplement(f10); - if (newcomplement) { - f10 = Cudd_Not(f10); - f00 = Cudd_Not(f00); - } - /* Check xlist for triple (xindex,f10,f00). */ - posn = ddHash(f10, f00, xshift); - /* For each element newf0 in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - newf0 = *previousP; - while (f10 < cuddT(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { - cuddSatInc(newf0->ref); - } else { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto cuddSwapOutOfMem; - newf0->index = xindex; newf0->ref = 1; - cuddT(newf0) = f10; - cuddE(newf0) = f00; - /* Insert newf0 in the collision list xlist[posn]; - ** increase the ref counts of f10 and f00. - */ - newxkeys++; - newf0->next = *previousP; - *previousP = newf0; - cuddSatInc(f10->ref); - tmp = Cudd_Regular(f00); - cuddSatInc(tmp->ref); - } - if (newcomplement) { - newf0 = Cudd_Not(newf0); - } - } - cuddE(f) = newf0; - - /* Insert the modified f in ylist. - ** The modified f does not already exists in ylist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, yshift); - newykeys++; - previousP = &(ylist[posn]); - tmp = *previousP; - while (newf1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; - } /* while f != NULL */ - - /* GC the y layer. */ - - /* For each node f in ylist. */ - for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - if (f->ref == 0) { - tmp = cuddT(f); - cuddSatDec(tmp->ref); - tmp = Cudd_Regular(cuddE(f)); + /* Do the same for f0, keeping complement dots into account. */ + /* Decrease ref count of f0. */ + tmp = Cudd_Regular(f0); cuddSatDec(tmp->ref); - cuddDeallocNode(table,f); - newykeys--; - } else { + /* Create the new E child. */ + if (f10 == f00) { + newf0 = f00; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f10 is regular */ + newcomplement = Cudd_IsComplement(f10); + if (newcomplement) { + f10 = Cudd_Not(f10); + f00 = Cudd_Not(f00); + } + /* Check xlist for triple (xindex,f10,f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf0 = *previousP; + while (f10 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; + cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f10->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + previousP = &(ylist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = sentinel; - } /* for i */ + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for i */ -#if DD_DEBUG +#ifdef DD_DEBUG #if 0 - (void) fprintf(table->out,"Swapping %d and %d\n",x,y); + (void) fprintf(table->out,"Swapping %d and %d\n",x,y); #endif - count = 0; - idcheck = 0; - for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) yindex) - idcheck++; - f = f->next; + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } } - } - if (count != newykeys) { - (void) fprintf(table->out, - "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", - oldykeys,newykeys,count); - } - if (idcheck != 0) - (void) fprintf(table->out, - "Error in id's of ylist\twrong id's = %d\n", - idcheck); - count = 0; - idcheck = 0; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) xindex) - idcheck++; - f = f->next; + if (count != newykeys) { + (void) fprintf(table->out, + "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", + oldykeys,newykeys,count); } - } - if (count != newxkeys) { - (void) fprintf(table->out, - "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", - oldxkeys,newxkeys,count); - } - if (idcheck != 0) - (void) fprintf(table->out, - "Error in id's of xlist\twrong id's = %d\n", - idcheck); + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of ylist\twrong id's = %d\n", + idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys) { + (void) fprintf(table->out, + "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", + oldxkeys,newxkeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of xlist\twrong id's = %d\n", + idcheck); #endif - isolated += (table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1); - table->isolated += isolated; + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; } /* Set the appropriate fields in table. */ @@ -1212,31 +1246,31 @@ int cuddBddAlignToZdd( DdManager * table /* DD manager */) { - int *invperm; /* permutation array */ - int M; /* ratio of ZDD variables to BDD variables */ - int i; /* loop index */ - int result; /* return value */ + int *invperm; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i; /* loop index */ + int result; /* return value */ /* We assume that a ratio of 0 is OK. */ if (table->size == 0) - return(1); + return(1); M = table->sizeZ / table->size; /* Check whether the number of ZDD variables is a multiple of the ** number of BDD variables. */ if (M * table->size != table->sizeZ) - return(0); + return(0); /* Create and initialize the inverse permutation array. */ invperm = ABC_ALLOC(int,table->size); if (invperm == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < table->sizeZ; i += M) { - int indexZ = table->invpermZ[i]; - int index = indexZ / M; - invperm[i / M] = index; + int indexZ = table->invpermZ[i]; + int index = indexZ / M; + invperm[i / M] = index; } /* Eliminate dead nodes. Do not scan the cache again, because we ** assume that Cudd_zddReduceHeap has already cleared it. @@ -1246,7 +1280,7 @@ cuddBddAlignToZdd( /* Initialize number of isolated projection functions. */ table->isolated = 0; for (i = 0; i < table->size; i++) { - if (table->vars[i]->ref == 1) table->isolated++; + if (table->vars[i]->ref == 1) table->isolated++; } /* Initialize the interaction matrix. */ @@ -1287,7 +1321,7 @@ ddUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -1310,15 +1344,15 @@ ddSwapAny( int x, int y) { - Move *move, *moves; - int xRef,yRef; - int xNext,yNext; - int size; - int limitSize; - int tmp; + Move *move, *moves; + int xRef,yRef; + int xNext,yNext; + int size; + int limitSize; + int tmp; if (x >y) { - tmp = x; x = y; y = tmp; + tmp = x; x = y; y = tmp; } xRef = x; yRef = y; @@ -1329,64 +1363,86 @@ ddSwapAny( limitSize = table->keys - table->isolated; for (;;) { - if ( xNext == yNext) { - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; - - size = cuddSwapInPlace(table,yNext,y); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = yNext; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; + if ( xNext == yNext) { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == yNext) { + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; - tmp = x; x = y; y = tmp; - - } else if (x == yNext) { - - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; x = y; y = tmp; + } else { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = xNext; + y = yNext; + } - } else { - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + if (xNext > yRef) break; + if ((double) size > table->maxGrowth * (double) limitSize) break; + if (size < limitSize) limitSize = size; + } + if (yNext>=xRef) { size = cuddSwapInPlace(table,yNext,y); if (size == 0) goto ddSwapAnyOutOfMem; move = (Move *) cuddDynamicAllocNode(table); @@ -1396,37 +1452,15 @@ ddSwapAny( move->size = size; move->next = moves; moves = move; - - x = xNext; - y = yNext; - } - - xNext = cuddNextHigh(table,x); - yNext = cuddNextLow(table,y); - if (xNext > yRef) break; - - if ((double) size > table->maxGrowth * (double) limitSize) break; - if (size < limitSize) limitSize = size; - } - if (yNext>=xRef) { - size = cuddSwapInPlace(table,yNext,y); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = yNext; - move->y = y; - move->size = size; - move->next = moves; - moves = move; } return(moves); - + ddSwapAnyOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1453,11 +1487,11 @@ ddSiftingAux( int xHigh) { - Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; initialSize = table->keys - table->isolated; @@ -1465,75 +1499,75 @@ ddSiftingAux( moveUp = NULL; if (x == xLow) { - moveDown = ddSiftingDown(table,x,xHigh); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddSiftingAuxOutOfMem; + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; } else if (x == xHigh) { - moveUp = ddSiftingUp(table,x,xLow); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddSiftingAuxOutOfMem; + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSiftingDown(table,x,xHigh); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - if (moveDown != NULL) { - x = moveDown->y; - } - moveUp = ddSiftingUp(table,x,xLow); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position */ - result = ddSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddSiftingAuxOutOfMem; + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveDown != NULL) { + x = moveDown->y; + } + moveUp = ddSiftingUp(table,x,xLow); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; } else { /* must go up first: shorter */ - moveUp = ddSiftingUp(table,x,xLow); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - } - moveDown = ddSiftingDown(table,x,xHigh); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddSiftingAuxOutOfMem; + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveUp != NULL) { + x = moveUp->x; + } + moveDown = ddSiftingDown(table,x,xHigh); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSiftingAuxOutOfMem: if (moveDown != (Move *) CUDD_OUT_OF_MEM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != (Move *) CUDD_OUT_OF_MEM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -1558,14 +1592,14 @@ ddSiftingUp( int y, int xLow) { - Move *moves; - Move *move; - int x; - int size; - int limitSize; - int xindex, yindex; - int isolated; - int L; /* lower bound on DD size */ + Move *moves; + Move *move; + int x; + int size; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; int z; @@ -1583,62 +1617,62 @@ ddSiftingUp( */ limitSize = L = table->keys - table->isolated; for (x = xLow + 1; x < y; x++) { - xindex = table->invperm[x]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L -= table->subtables[x].keys - isolated; - } + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } } isolated = table->vars[yindex]->ref == 1; L -= table->subtables[y].keys - isolated; x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { - xindex = table->invperm[x]; + xindex = table->invperm[x]; #ifdef DD_DEBUG - checkL = table->keys - table->isolated; - for (z = xLow + 1; z < y; z++) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } } - } - isolated = table->vars[yindex]->ref == 1; - checkL -= table->subtables[y].keys - isolated; - assert(L == checkL); + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + assert(L == checkL); #endif - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - y = x; - x = cuddNextLow(table,y); + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); } return(moves); ddSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of ddSiftingUp */ - + /**Function******************************************************************** @@ -1658,18 +1692,18 @@ ddSiftingDown( int x, int xHigh) { - Move *moves; - Move *move; - int y; - int size; - int R; /* upper bound on node decrease */ - int limitSize; - int xindex, yindex; - int isolated; + Move *moves; + Move *move; + int y; + int size; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; #ifdef DD_DEBUG - int checkR; - int z; - int zindex; + int checkR; + int z; + int zindex; #endif moves = NULL; @@ -1678,53 +1712,53 @@ ddSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (y = xHigh; y > x; y--) { - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R += table->subtables[y].keys - isolated; - } + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - checkR = 0; - for (z = xHigh; z > x; z--) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - } - assert(R == checkR); + assert(R == checkR); #endif - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - x = y; - y = cuddNextHigh(table,x); + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); } return(moves); ddSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -1751,18 +1785,18 @@ ddSiftingBackward( Move * moves) { Move *move; - int res; + int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); + if (move->size == size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); } return(1); @@ -1800,7 +1834,7 @@ ddReorderPreprocess( /* Initialize number of isolated projection functions. */ table->isolated = 0; for (i = 0; i < table->size; i++) { - if (table->vars[i]->ref == 1) table->isolated++; + if (table->vars[i]->ref == 1) table->isolated++; } /* Initialize the interaction matrix. */ @@ -1859,16 +1893,16 @@ ddShuffle( DdManager * table, int * permutation) { - int index; - int level; - int position; - int numvars; - int result; + int index; + int level; + int position; + int numvars; + int result; #ifdef DD_STATS - long localTime; - int initialSize; - int finalSize; - int previousSize; + long localTime; + int initialSize; + int finalSize; + int previousSize; #endif ddTotalNumberSwapping = 0; @@ -1876,40 +1910,40 @@ ddShuffle( localTime = util_cpu_time(); initialSize = table->keys - table->isolated; (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", - initialSize); + initialSize); ddTotalNISwaps = 0; #endif numvars = table->size; for (level = 0; level < numvars; level++) { - index = permutation[level]; - position = table->perm[index]; + index = permutation[level]; + position = table->perm[index]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftUp(table,position,level); - if (!result) return(0); + result = ddSiftUp(table,position,level); + if (!result) return(0); #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } #ifdef DD_STATS (void) fprintf(table->out,"\n"); finalSize = table->keys - table->isolated; - (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", - ddTotalNumberSwapping); + ddTotalNumberSwapping); (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps); #endif @@ -1942,12 +1976,12 @@ ddSiftUp( y = cuddNextLow(table,x); while (y >= xLow) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -1974,15 +2008,15 @@ bddFixTree( { if (treenode == NULL) return; treenode->low = ((int) treenode->index < table->size) ? - table->perm[treenode->index] : treenode->index; + table->perm[treenode->index] : treenode->index; if (treenode->child != NULL) { - bddFixTree(table, treenode->child); + bddFixTree(table, treenode->child); } if (treenode->younger != NULL) - bddFixTree(table, treenode->younger); + bddFixTree(table, treenode->younger); if (treenode->parent != NULL && treenode->low < treenode->parent->low) { - treenode->parent->low = treenode->low; - treenode->parent->index = treenode->index; + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; } return; @@ -2008,36 +2042,41 @@ ddUpdateMtrTree( int * perm, int * invperm) { - int i, size, index, level; - int minLevel = table->size, maxLevel = 0, minIndex = 0; // Suppress "might be used uninitialized" + int i, size; + int index, level, minLevel, maxLevel, minIndex; if (treenode == NULL) return(1); + minLevel = CUDD_MAXINDEX; + maxLevel = 0; + minIndex = -1; /* i : level */ for (i = treenode->low; i < treenode->low + treenode->size; i++) { - index = table->invperm[i]; - level = perm[index]; - if (level < minLevel) { - minLevel = level; - minIndex = index; - } - if (level > maxLevel) - maxLevel = level; + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) { + minLevel = level; + minIndex = index; + } + if (level > maxLevel) + maxLevel = level; } size = maxLevel - minLevel + 1; + if (minIndex == -1) return(0); if (size == treenode->size) { - treenode->low = minLevel; - treenode->index = minIndex; - } else - return(0); + treenode->low = minLevel; + treenode->index = minIndex; + } else { + return(0); + } if (treenode->child != NULL) { - if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) - return(0); + if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) + return(0); } if (treenode->younger != NULL) { - if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) - return(0); + if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) + return(0); } return(1); } @@ -2062,8 +2101,8 @@ ddCheckPermuation( int * perm, int * invperm) { - int i, size, index, level; - int minLevel, maxLevel; + int i, size; + int index, level, minLevel, maxLevel; if (treenode == NULL) return(1); @@ -2071,26 +2110,28 @@ ddCheckPermuation( maxLevel = 0; /* i : level */ for (i = treenode->low; i < treenode->low + treenode->size; i++) { - index = table->invperm[i]; - level = perm[index]; - if (level < minLevel) - minLevel = level; - if (level > maxLevel) - maxLevel = level; + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) + minLevel = level; + if (level > maxLevel) + maxLevel = level; } size = maxLevel - minLevel + 1; if (size != treenode->size) - return(0); + return(0); if (treenode->child != NULL) { - if (!ddCheckPermuation(table, treenode->child, perm, invperm)) - return(0); + if (!ddCheckPermuation(table, treenode->child, perm, invperm)) + return(0); } if (treenode->younger != NULL) { - if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) - return(0); + if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) + return(0); } return(1); } + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c index cb0534c3..c3a161b4 100644 --- a/src/bdd/cudd/cuddSat.c +++ b/src/bdd/cudd/cuddSat.c @@ -8,37 +8,64 @@ problems.] Description [External procedures included in this file: - <ul> - <li> Cudd_Eval() - <li> Cudd_ShortestPath() - <li> Cudd_LargestCube() - <li> Cudd_ShortestLength() - <li> Cudd_Decreasing() - <li> Cudd_Increasing() - <li> Cudd_EquivDC() - <li> Cudd_bddLeqUnless() - <li> Cudd_EqualSupNorm() - <li> Cudd_bddMakePrime() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddMakePrime() - </ul> - Static procedures included in this module: - <ul> - <li> freePathPair() - <li> getShortest() - <li> getPath() - <li> getLargest() - <li> getCube() - </ul>] + <ul> + <li> Cudd_Eval() + <li> Cudd_ShortestPath() + <li> Cudd_LargestCube() + <li> Cudd_ShortestLength() + <li> Cudd_Decreasing() + <li> Cudd_Increasing() + <li> Cudd_EquivDC() + <li> Cudd_bddLeqUnless() + <li> Cudd_EqualSupNorm() + <li> Cudd_bddMakePrime() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddMakePrime() + </ul> + Static procedures included in this module: + <ul> + <li> freePathPair() + <li> getShortest() + <li> getPath() + <li> getLargest() + <li> getCube() + </ul>] Author [Seh-Woong Jeong, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -48,11 +75,12 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_BIGGY 1000000 +#define DD_BIGGY 1000000 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -63,8 +91,8 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ typedef struct cuddPathPair { - int pos; - int neg; + int pos; + int neg; } cuddPathPair; /*---------------------------------------------------------------------------*/ @@ -72,16 +100,20 @@ typedef struct cuddPathPair { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.36 2009/03/08 02:49:02 fabio Exp $"; #endif -static DdNode *one, *zero; +static DdNode *one, *zero; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ -#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) +#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) + +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -89,14 +121,17 @@ static DdNode *one, *zero; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static enum st_retval freePathPair ARGS((char *key, char *value, char *arg)); -static cuddPathPair getShortest ARGS((DdNode *root, int *cost, int *support, st_table *visited)); -static DdNode * getPath ARGS((DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost)); -static cuddPathPair getLargest ARGS((DdNode *root, st_table *visited)); -static DdNode * getCube ARGS((DdManager *manager, st_table *visited, DdNode *f, int cost)); +static enum st_retval freePathPair (char *key, char *value, char *arg); +static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited); +static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost); +static cuddPathPair getLargest (DdNode *root, st_table *visited); +static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -131,12 +166,12 @@ Cudd_Eval( ptr = Cudd_Regular(f); while (!cuddIsConstant(ptr)) { - if (inputs[ptr->index] == 1) { - ptr = cuddT(ptr); - } else { - comple ^= Cudd_IsComplement(cuddE(ptr)); - ptr = Cudd_Regular(cuddE(ptr)); - } + if (inputs[ptr->index] == 1) { + ptr = cuddT(ptr); + } else { + comple ^= Cudd_IsComplement(cuddE(ptr)); + ptr = Cudd_Regular(cuddE(ptr)); + } } return(Cudd_NotCond(ptr,comple)); @@ -170,55 +205,59 @@ Cudd_ShortestPath( int * support, int * length) { - register DdNode *F; + DdNode *F; st_table *visited; - DdNode *sol; + DdNode *sol; cuddPathPair *rootPair; - int complement, cost; - int i; + int complement, cost; + int i; one = DD_ONE(manager); zero = DD_ZERO(manager); - /* Initialize support. */ + /* Initialize support. Support does not depend on variable order. + ** Hence, it does not need to be reinitialized if reordering occurs. + */ if (support) { - for (i = 0; i < manager->size; i++) { + for (i = 0; i < manager->size; i++) { support[i] = 0; - } + } } if (f == Cudd_Not(one) || f == zero) { - *length = DD_BIGGY; - return(Cudd_Not(one)); + *length = DD_BIGGY; + return(Cudd_Not(one)); } /* From this point on, a path exists. */ - /* Initialize visited table. */ - visited = st_init_table(st_ptrcmp, st_ptrhash); + do { + manager->reordered = 0; - /* Now get the length of the shortest path(s) from f to 1. */ - (void) getShortest(f, weight, support, visited); + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); - complement = Cudd_IsComplement(f); + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, support, visited); - F = Cudd_Regular(f); + complement = Cudd_IsComplement(f); - st_lookup(visited, (char *)F, (char **)&rootPair); - - if (complement) { - cost = rootPair->neg; - } else { - cost = rootPair->pos; - } + F = Cudd_Regular(f); - /* Recover an actual shortest path. */ - do { - manager->reordered = 0; - sol = getPath(manager,visited,f,weight,cost); - } while (manager->reordered == 1); + if (!st_lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL); - st_foreach(visited, (ST_PFSR)freePathPair, NULL); - st_free_table(visited); + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getPath(manager,visited,f,weight,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); *length = cost; return(sol); @@ -248,47 +287,49 @@ Cudd_LargestCube( DdNode * f, int * length) { - register DdNode *F; + register DdNode *F; st_table *visited; - DdNode *sol; + DdNode *sol; cuddPathPair *rootPair; - int complement, cost; + int complement, cost; one = DD_ONE(manager); zero = DD_ZERO(manager); if (f == Cudd_Not(one) || f == zero) { - *length = DD_BIGGY; - return(Cudd_Not(one)); + *length = DD_BIGGY; + return(Cudd_Not(one)); } /* From this point on, a path exists. */ - /* Initialize visited table. */ - visited = st_init_table(st_ptrcmp, st_ptrhash); + do { + manager->reordered = 0; - /* Now get the length of the shortest path(s) from f to 1. */ - (void) getLargest(f, visited); + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); - complement = Cudd_IsComplement(f); + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getLargest(f, visited); - F = Cudd_Regular(f); + complement = Cudd_IsComplement(f); - st_lookup(visited, (char *)F, (char **)&rootPair); - - if (complement) { - cost = rootPair->neg; - } else { - cost = rootPair->pos; - } + F = Cudd_Regular(f); - /* Recover an actual shortest path. */ - do { - manager->reordered = 0; - sol = getCube(manager,visited,f,cost); - } while (manager->reordered == 1); + if (!st_lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL); - st_foreach(visited, (ST_PFSR)freePathPair, NULL); - st_free_table(visited); + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getCube(manager,visited,f,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); *length = cost; return(sol); @@ -304,7 +345,8 @@ Cudd_LargestCube( the DD we want to get the shortest path for; weight\[i\] is the weight of the THEN edge coming from the node whose index is i. All ELSE edges have 0 weight. Returns the length of the shortest - path(s) if successful; CUDD_OUT_OF_MEM otherwise.] + path(s) if such a path is found; a large number if the function is + identically 0, and CUDD_OUT_OF_MEM in case of failure.] SideEffects [None] @@ -317,16 +359,16 @@ Cudd_ShortestLength( DdNode * f, int * weight) { - register DdNode *F; + register DdNode *F; st_table *visited; cuddPathPair *my_pair; - int complement, cost; + int complement, cost; one = DD_ONE(manager); zero = DD_ZERO(manager); if (f == Cudd_Not(one) || f == zero) { - return(DD_BIGGY); + return(DD_BIGGY); } /* From this point on, a path exists. */ @@ -340,15 +382,15 @@ Cudd_ShortestLength( F = Cudd_Regular(f); - st_lookup(visited, (char *)F, (char **)&my_pair); + if (!st_lookup(visited, (const char *)F, (char **)&my_pair)) return(CUDD_OUT_OF_MEM); if (complement) { - cost = my_pair->neg; + cost = my_pair->neg; } else { - cost = my_pair->pos; + cost = my_pair->pos; } - st_foreach(visited, (ST_PFSR)freePathPair, NULL); + st_foreach(visited, freePathPair, NULL); st_free_table(visited); return(cost); @@ -379,7 +421,7 @@ Cudd_Decreasing( { unsigned int topf, level; DdNode *F, *fv, *fvn, *res; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(dd); #ifdef DD_DEBUG @@ -394,40 +436,40 @@ Cudd_Decreasing( */ level = (unsigned) dd->perm[i]; if (topf > level) { - return(DD_ONE(dd)); + return(DD_ONE(dd)); } /* From now on, f is not constant. */ /* Check cache. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_Decreasing; + cacheOp = (DD_CTFP) Cudd_Decreasing; res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); if (res != NULL) { - return(res); + return(res); } /* Compute cofactors. */ fv = cuddT(F); fvn = cuddE(F); if (F != f) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); } if (topf == (unsigned) level) { - /* Special case: if fv is regular, fv(1,...,1) = 1; - ** If in addition fvn is complemented, fvn(1,...,1) = 0. - ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not - ** monotonic decreasing in i. - */ - if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { - return(Cudd_Not(DD_ONE(dd))); - } - res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); + /* Special case: if fv is regular, fv(1,...,1) = 1; + ** If in addition fvn is complemented, fvn(1,...,1) = 0. + ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not + ** monotonic decreasing in i. + */ + if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { + return(Cudd_Not(DD_ONE(dd))); + } + res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); } else { - res = Cudd_Decreasing(dd,fv,i); - if (res == DD_ONE(dd)) { - res = Cudd_Decreasing(dd,fvn,i); - } + res = Cudd_Decreasing(dd,fv,i); + if (res == DD_ONE(dd)) { + res = Cudd_Decreasing(dd,fvn,i); + } } cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); @@ -442,7 +484,7 @@ Cudd_Decreasing( variable.] Description [Determines whether the function represented by BDD f is - positive unate (monotonic decreasing) in variable i. It is based on + positive unate (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the fact that f is monotonic increasing in i if and only if its complement is monotonic decreasing in i.] @@ -499,13 +541,13 @@ Cudd_EquivDC( /* Normalize call to increase cache efficiency. */ if (F > G) { - tmp = F; - F = G; - G = tmp; + tmp = F; + F = G; + G = tmp; } if (Cudd_IsComplement(F)) { - F = Cudd_Not(F); - G = Cudd_Not(G); + F = Cudd_Not(F); + G = Cudd_Not(G); } /* From now on, F is regular. */ @@ -525,36 +567,36 @@ Cudd_EquivDC( /* Compute cofactors. */ if (top == flevel) { - Fv = cuddT(F); - Fvn = cuddE(F); + Fv = cuddT(F); + Fvn = cuddE(F); } else { - Fv = Fvn = F; + Fv = Fvn = F; } if (top == glevel) { - Gv = cuddT(Gr); - Gvn = cuddE(Gr); - if (G != Gr) { - Gv = Cudd_Not(Gv); - Gvn = Cudd_Not(Gvn); - } + Gv = cuddT(Gr); + Gvn = cuddE(Gr); + if (G != Gr) { + Gv = Cudd_Not(Gv); + Gvn = Cudd_Not(Gvn); + } } else { - Gv = Gvn = G; + Gv = Gvn = G; } if (top == dlevel) { - Dv = cuddT(Dr); - Dvn = cuddE(Dr); - if (D != Dr) { - Dv = Cudd_Not(Dv); - Dvn = Cudd_Not(Dvn); - } + Dv = cuddT(Dr); + Dvn = cuddE(Dr); + if (D != Dr) { + Dv = Cudd_Not(Dv); + Dvn = Cudd_Not(Dvn); + } } else { - Dv = Dvn = D; + Dv = Dvn = D; } /* Solve recursively. */ res = Cudd_EquivDC(dd,Fv,Gv,Dv); if (res != 0) { - res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); + res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); } cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); @@ -594,10 +636,10 @@ Cudd_bddLeqUnless( /* Check terminal cases. */ if (f == g || g == One || f == Cudd_Not(One) || D == One || - D == f || D == Cudd_Not(g)) return(1); + D == f || D == Cudd_Not(g)) return(1); /* Check for two-operand cases. */ if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) - return(Cudd_bddLeq(dd,f,g)); + return(Cudd_bddLeq(dd,f,g)); if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); @@ -612,72 +654,72 @@ Cudd_bddLeqUnless( ** lowest address comes first. */ if (Cudd_IsComplement(D)) { - if (Cudd_IsComplement(g)) { - /* Special case: if f is regular and g is complemented, - ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. - */ - if (!Cudd_IsComplement(f)) return(0); - /* !g <= D unless !f or !D <= g unless !f */ - tmp = D; - D = Cudd_Not(f); - if (g < tmp) { - f = Cudd_Not(g); - g = tmp; + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. + */ + if (!Cudd_IsComplement(f)) return(0); + /* !g <= D unless !f or !D <= g unless !f */ + tmp = D; + D = Cudd_Not(f); + if (g < tmp) { + f = Cudd_Not(g); + g = tmp; + } else { + f = Cudd_Not(tmp); + } } else { - f = Cudd_Not(tmp); + if (Cudd_IsComplement(f)) { + /* !D <= !f unless g or !D <= g unless !f */ + tmp = f; + f = Cudd_Not(D); + if (tmp < g) { + D = g; + g = Cudd_Not(tmp); + } else { + D = Cudd_Not(tmp); + } + } else { + /* f <= D unless g or !D <= !f unless g */ + tmp = D; + D = g; + if (tmp < f) { + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else { + g = tmp; + } + } } } else { - if (Cudd_IsComplement(f)) { - /* !D <= !f unless g or !D <= g unless !f */ - tmp = f; - f = Cudd_Not(D); - if (tmp < g) { - D = g; - g = Cudd_Not(tmp); + if (Cudd_IsComplement(g)) { + if (Cudd_IsComplement(f)) { + /* !g <= !f unless D or !g <= D unless !f */ + tmp = f; + f = Cudd_Not(g); + if (D < tmp) { + g = D; + D = Cudd_Not(tmp); + } else { + g = Cudd_Not(tmp); + } + } else { + /* f <= g unless D or !g <= !f unless D */ + if (g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + } } else { - D = Cudd_Not(tmp); - } - } else { - /* f <= D unless g or !D <= !f unless g */ - tmp = D; - D = g; - if (tmp < f) { - g = Cudd_Not(f); - f = Cudd_Not(tmp); - } else { - g = tmp; - } + /* f <= g unless D or f <= D unless g */ + if (D < g) { + tmp = D; + D = g; + g = tmp; + } } } - } else { - if (Cudd_IsComplement(g)) { - if (Cudd_IsComplement(f)) { - /* !g <= !f unless D or !g <= D unless !f */ - tmp = f; - f = Cudd_Not(g); - if (D < tmp) { - g = D; - D = Cudd_Not(tmp); - } else { - g = Cudd_Not(tmp); - } - } else { - /* f <= g unless D or !g <= !f unless D */ - if (g < f) { - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); - } - } - } else { - /* f <= g unless D or f <= D unless g */ - if (D < g) { - tmp = D; - D = g; - g = tmp; - } - } - } /* From now on, D is regular. */ @@ -696,36 +738,36 @@ Cudd_bddLeqUnless( /* Compute cofactors. */ if (top == flevel) { - Ft = cuddT(F); - Fe = cuddE(F); - if (F != f) { - Ft = Cudd_Not(Ft); - Fe = Cudd_Not(Fe); - } + Ft = cuddT(F); + Fe = cuddE(F); + if (F != f) { + Ft = Cudd_Not(Ft); + Fe = Cudd_Not(Fe); + } } else { - Ft = Fe = f; + Ft = Fe = f; } if (top == glevel) { - Gt = cuddT(G); - Ge = cuddE(G); - if (G != g) { - Gt = Cudd_Not(Gt); - Ge = Cudd_Not(Ge); - } + Gt = cuddT(G); + Ge = cuddE(G); + if (G != g) { + Gt = Cudd_Not(Gt); + Ge = Cudd_Not(Ge); + } } else { - Gt = Ge = g; + Gt = Ge = g; } if (top == dlevel) { - Dt = cuddT(D); - De = cuddE(D); + Dt = cuddT(D); + De = cuddE(D); } else { - Dt = De = D; + Dt = De = D; } /* Solve recursively. */ res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); if (res != 0) { - res = Cudd_bddLeqUnless(dd,Fe,Ge,De); + res = Cudd_bddLeqUnless(dd,Fe,Ge,De); } cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); @@ -765,36 +807,27 @@ Cudd_EqualSupNorm( /* Check terminal cases. */ if (f == g) return(1); if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { - if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { - return(1); - } else { - if (pr>0) { - (void) fprintf(dd->out,"Offending nodes:\n"); -#if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out, - "f: address = %lx\t value = %40.30f\n", - (unsigned long) f, cuddV(f)); - (void) fprintf(dd->out, - "g: address = %lx\t value = %40.30f\n", - (unsigned long) g, cuddV(g)); -#else - (void) fprintf(dd->out, - "f: address = %x\t value = %40.30f\n", - (unsigned) f, cuddV(f)); - (void) fprintf(dd->out, - "g: address = %x\t value = %40.30f\n", - (unsigned) g, cuddV(g)); -#endif + if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { + return(1); + } else { + if (pr>0) { + (void) fprintf(dd->out,"Offending nodes:\n"); + (void) fprintf(dd->out, + "f: address = %p\t value = %40.30f\n", + (void *) f, cuddV(f)); + (void) fprintf(dd->out, + "g: address = %p\t value = %40.30f\n", + (void *) g, cuddV(g)); + } + return(0); } - return(0); - } } /* We only insert the result in the cache if the comparison is ** successful. Therefore, if we hit we return 1. */ - r = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_EqualSupNorm,f,g); + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); if (r != NULL) { - return(1); + return(1); } /* Compute the cofactors and solve the recursive subproblems. */ @@ -807,7 +840,7 @@ Cudd_EqualSupNorm( if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_EqualSupNorm,f,g,DD_ONE(dd)); + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); return(1); @@ -838,8 +871,8 @@ Cudd_bddMakePrime( if (!Cudd_bddLeq(dd,cube,f)) return(NULL); do { - dd->reordered = 0; - res = cuddBddMakePrime(dd,cube,f); + dd->reordered = 0; + res = cuddBddMakePrime(dd,cube,f); } while (dd->reordered == 1); return(res); @@ -877,36 +910,36 @@ cuddBddMakePrime( Cudd_Ref(res); scan = cube; while (!Cudd_IsConstant(scan)) { - DdNode *reg = Cudd_Regular(scan); - DdNode *var = dd->vars[reg->index]; - DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); - if (expanded == NULL) { - return(NULL); - } - Cudd_Ref(expanded); - if (Cudd_bddLeq(dd,expanded,f)) { - Cudd_RecursiveDeref(dd,res); - res = expanded; - } else { - Cudd_RecursiveDeref(dd,expanded); - } - cuddGetBranches(scan,&t,&e); - if (t == zero) { - scan = e; - } else if (e == zero) { - scan = t; - } else { - Cudd_RecursiveDeref(dd,res); - return(NULL); /* cube is not a cube */ - } + DdNode *reg = Cudd_Regular(scan); + DdNode *var = dd->vars[reg->index]; + DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); + if (expanded == NULL) { + return(NULL); + } + Cudd_Ref(expanded); + if (Cudd_bddLeq(dd,expanded,f)) { + Cudd_RecursiveDeref(dd,res); + res = expanded; + } else { + Cudd_RecursiveDeref(dd,expanded); + } + cuddGetBranches(scan,&t,&e); + if (t == zero) { + scan = e; + } else if (e == zero) { + scan = t; + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); /* cube is not a cube */ + } } if (scan == DD_ONE(dd)) { - Cudd_Deref(res); - return(res); + Cudd_Deref(res); + return(res); } else { - Cudd_RecursiveDeref(dd,res); - return(NULL); + Cudd_RecursiveDeref(dd,res); + return(NULL); } } /* end of cuddBddMakePrime */ @@ -936,7 +969,7 @@ freePathPair( cuddPathPair *pair; pair = (cuddPathPair *) value; - ABC_FREE(pair); + ABC_FREE(pair); return(ST_CONTINUE); } /* end of freePathPair */ @@ -968,20 +1001,20 @@ getShortest( st_table * visited) { cuddPathPair *my_pair, res_pair, pair_T, pair_E; - DdNode *my_root, *T, *E; - int weight; + DdNode *my_root, *T, *E; + int weight; my_root = Cudd_Regular(root); - if (st_lookup(visited, (char *)my_root, (char **)&my_pair)) { - if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; - } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; - } - return(res_pair); + if (st_lookup(visited, (const char *)my_root, (char **)&my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); } /* In the case of a BDD the following test is equivalent to @@ -990,48 +1023,48 @@ getShortest( ** dichotomy of 0 and != 0. */ if (cuddIsConstant(my_root)) { - if (my_root != zero) { - res_pair.pos = 0; - res_pair.neg = DD_BIGGY; - } else { - res_pair.pos = DD_BIGGY; - res_pair.neg = 0; - } + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } } else { - T = cuddT(my_root); - E = cuddE(my_root); - - pair_T = getShortest(T, cost, support, visited); - pair_E = getShortest(E, cost, support, visited); - weight = WEIGHT(cost, my_root->index); - res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); - res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); - - /* Update support. */ - if (support != NULL) { - support[my_root->index] = 1; - } + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getShortest(T, cost, support, visited); + pair_E = getShortest(E, cost, support, visited); + weight = WEIGHT(cost, my_root->index); + res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); + res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); + + /* Update support. */ + if (support != NULL) { + support[my_root->index] = 1; + } } my_pair = ABC_ALLOC(cuddPathPair, 1); if (my_pair == NULL) { - if (Cudd_IsComplement(root)) { - int tmp = res_pair.pos; - res_pair.pos = res_pair.neg; - res_pair.neg = tmp; - } - return(res_pair); + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); } my_pair->pos = res_pair.pos; my_pair->neg = res_pair.neg; st_insert(visited, (char *)my_root, (char *)my_pair); if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; } return(res_pair); @@ -1064,11 +1097,11 @@ getPath( int * weight, int cost) { - DdNode *sol, *tmp; - DdNode *my_dd, *T, *E; + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; cuddPathPair *T_pair, *E_pair; - int Tcost, Ecost; - int complement; + int Tcost, Ecost; + int complement; my_dd = Cudd_Regular(f); complement = Cudd_IsComplement(f); @@ -1077,50 +1110,50 @@ getPath( cuddRef(sol); while (!cuddIsConstant(my_dd)) { - Tcost = cost - WEIGHT(weight, my_dd->index); - Ecost = cost; - - T = cuddT(my_dd); - E = cuddE(my_dd); - - if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} - - st_lookup(visited, (char *)Cudd_Regular(T), (char **)&T_pair); - if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || - (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { - tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + Tcost = cost - WEIGHT(weight, my_dd->index); + Ecost = cost; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + st_lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - - complement = Cudd_IsComplement(T); - my_dd = Cudd_Regular(T); - cost = Tcost; - continue; - } - st_lookup(visited, (char *)Cudd_Regular(E), (char **)&E_pair); - if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || - (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { - tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + st_lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - complement = Cudd_IsComplement(E); - my_dd = Cudd_Regular(E); - cost = Ecost; - continue; - } - (void) fprintf(manager->err,"We shouldn't be here!!\n"); - manager->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(manager->err,"We shouldn't be here!!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } cuddDeref(sol); @@ -1155,19 +1188,19 @@ getLargest( st_table * visited) { cuddPathPair *my_pair, res_pair, pair_T, pair_E; - DdNode *my_root, *T, *E; + DdNode *my_root, *T, *E; my_root = Cudd_Regular(root); - if (st_lookup(visited, (char *)my_root, (char **)&my_pair)) { - if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; - } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; - } - return(res_pair); + if (st_lookup(visited, (const char *)my_root, (char **)&my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); } /* In the case of a BDD the following test is equivalent to @@ -1176,42 +1209,43 @@ getLargest( ** dichotomy of 0 and != 0. */ if (cuddIsConstant(my_root)) { - if (my_root != zero) { - res_pair.pos = 0; - res_pair.neg = DD_BIGGY; - } else { - res_pair.pos = DD_BIGGY; - res_pair.neg = 0; - } + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } } else { - T = cuddT(my_root); - E = cuddE(my_root); + T = cuddT(my_root); + E = cuddE(my_root); - pair_T = getLargest(T, visited); - pair_E = getLargest(E, visited); - res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; - res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; + pair_T = getLargest(T, visited); + pair_E = getLargest(E, visited); + res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; + res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; } my_pair = ABC_ALLOC(cuddPathPair, 1); - if (my_pair == NULL) { /* simlpy do not cache this result */ - if (Cudd_IsComplement(root)) { - int tmp = res_pair.pos; - res_pair.pos = res_pair.neg; - res_pair.neg = tmp; - } - return(res_pair); + if (my_pair == NULL) { /* simply do not cache this result */ + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); } my_pair->pos = res_pair.pos; my_pair->neg = res_pair.neg; + /* Caching may fail without affecting correctness. */ st_insert(visited, (char *)my_root, (char *)my_pair); if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; } return(res_pair); @@ -1243,11 +1277,11 @@ getCube( DdNode * f, int cost) { - DdNode *sol, *tmp; - DdNode *my_dd, *T, *E; + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; cuddPathPair *T_pair, *E_pair; - int Tcost, Ecost; - int complement; + int Tcost, Ecost; + int complement; my_dd = Cudd_Regular(f); complement = Cudd_IsComplement(f); @@ -1256,55 +1290,57 @@ getCube( cuddRef(sol); while (!cuddIsConstant(my_dd)) { - Tcost = cost - 1; - Ecost = cost - 1; - - T = cuddT(my_dd); - E = cuddE(my_dd); - - if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} - - st_lookup(visited, (char *)Cudd_Regular(T), (char **)&T_pair); - if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || - (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { - tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + Tcost = cost - 1; + Ecost = cost - 1; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + if (!st_lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair)) return(NULL); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - - complement = Cudd_IsComplement(T); - my_dd = Cudd_Regular(T); - cost = Tcost; - continue; - } - st_lookup(visited, (char *)Cudd_Regular(E), (char **)&E_pair); - if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || - (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { - tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + if (!st_lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair)) return(NULL); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - complement = Cudd_IsComplement(E); - my_dd = Cudd_Regular(E); - cost = Ecost; - continue; - } - (void) fprintf(manager->err,"We shouldn't be here!\n"); - manager->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(manager->err,"We shouldn't be here!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } cuddDeref(sol); return(sol); } /* end of getCube */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSign.c b/src/bdd/cudd/cuddSign.c index b2b043a4..75d1f60c 100644 --- a/src/bdd/cudd/cuddSign.c +++ b/src/bdd/cudd/cuddSign.c @@ -4,24 +4,51 @@ PackageName [cudd] - Synopsis [Computation of signatures] + Synopsis [Computation of signatures.] Description [External procedures included in this module: - <ul> - <li> Cudd_CofMinterm(); - </ul> - Static procedures included in this module: - <ul> - <li> ddCofMintermAux() - </ul> - ] + <ul> + <li> Cudd_CofMinterm(); + </ul> + Static procedures included in this module: + <ul> + <li> ddCofMintermAux() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -52,13 +80,13 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.22 2009/02/20 02:14:58 fabio Exp $"; #endif static int size; #ifdef DD_STATS -static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ +static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ static int table_mem; #endif @@ -74,7 +102,7 @@ static int table_mem; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *table)); +static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table); /**AutomaticEnd***************************************************************/ @@ -90,7 +118,7 @@ static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *tab Description [Computes the fraction of minterms in the on-set of all the positive cofactors of DD. Returns the pointer to an array of - doubles if successful; NULL otherwise. The array hs as many + doubles if successful; NULL otherwise. The array has as many positions as there are BDD variables in the manager plus one. The last position of the array contains the fraction of the minterms in the ON-set of the function represented by the BDD or ADD. The other @@ -105,9 +133,9 @@ Cudd_CofMinterm( DdNode * node) { st_table *table; - double *values; - double *result = NULL; - int i, firstLevel; + double *values; + double *result = NULL; + int i, firstLevel; #ifdef DD_STATS long startTime; @@ -118,52 +146,52 @@ Cudd_CofMinterm( table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) { - (void) fprintf(dd->err, - "out-of-memory, couldn't measure DD cofactors.\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } size = dd->size; values = ddCofMintermAux(dd, node, table); if (values != NULL) { - result = ABC_ALLOC(double,size + 1); - if (result != NULL) { + result = ABC_ALLOC(double,size + 1); + if (result != NULL) { #ifdef DD_STATS - table_mem += (size + 1) * sizeof(double); + table_mem += (size + 1) * sizeof(double); #endif - if (Cudd_IsConstant(node)) - firstLevel = 1; - else - firstLevel = cuddI(dd,Cudd_Regular(node)->index); - for (i = 0; i < size; i++) { - if (i >= cuddI(dd,Cudd_Regular(node)->index)) { - result[dd->invperm[i]] = values[i - firstLevel]; + if (Cudd_IsConstant(node)) + firstLevel = 1; + else + firstLevel = cuddI(dd,Cudd_Regular(node)->index); + for (i = 0; i < size; i++) { + if (i >= cuddI(dd,Cudd_Regular(node)->index)) { + result[dd->invperm[i]] = values[i - firstLevel]; + } else { + result[dd->invperm[i]] = values[size - firstLevel]; + } + } + result[size] = values[size - firstLevel]; } else { - result[dd->invperm[i]] = values[size - firstLevel]; - } + dd->errorCode = CUDD_MEMORY_OUT; } - result[size] = values[size - firstLevel]; - } else { - dd->errorCode = CUDD_MEMORY_OUT; - } } #ifdef DD_STATS table_mem += table->num_bins * sizeof(st_table_entry *); #endif if (Cudd_Regular(node)->ref == 1) ABC_FREE(values); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); #ifdef DD_STATS (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", - num_calls, table_mem); + num_calls, table_mem); (void) fprintf(dd->out,"Time to compute measures: %s\n", - util_print_time(util_cpu_time() - startTime)); + util_print_time(util_cpu_time() - startTime)); #endif if (result == NULL) { - (void) fprintf(dd->out, - "out-of-memory, couldn't measure DD cofactors.\n"); - dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->out, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; } return(result); @@ -206,92 +234,93 @@ ddCofMintermAux( DdNode * node, st_table * table) { - DdNode *N; /* regular version of node */ - DdNode *Nv, *Nnv; - double *values; - double *valuesT, *valuesE; - int i; - int localSize, localSizeT, localSizeE; - double vT, vE; + DdNode *N; /* regular version of node */ + DdNode *Nv, *Nnv; + double *values; + double *valuesT, *valuesE; + int i; + int localSize, localSizeT, localSizeE; + double vT, vE; statLine(dd); #ifdef DD_STATS num_calls++; #endif - if (st_lookup(table, (char *) node, (char **) &values)) { - return(values); + if (st_lookup(table, (const char *)node, (char **)&values)) { + return(values); } N = Cudd_Regular(node); if (cuddIsConstant(N)) { - localSize = 1; + localSize = 1; } else { - localSize = size - cuddI(dd,N->index) + 1; + localSize = size - cuddI(dd,N->index) + 1; } values = ABC_ALLOC(double, localSize); if (values == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } if (cuddIsConstant(N)) { - if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { - values[0] = 0.0; - } else { - values[0] = 1.0; - } + if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { + values[0] = 0.0; + } else { + values[0] = 1.0; + } } else { - Nv = Cudd_NotCond(cuddT(N),N!=node); - Nnv = Cudd_NotCond(cuddE(N),N!=node); + Nv = Cudd_NotCond(cuddT(N),N!=node); + Nnv = Cudd_NotCond(cuddE(N),N!=node); - valuesT = ddCofMintermAux(dd, Nv, table); - if (valuesT == NULL) return(NULL); - valuesE = ddCofMintermAux(dd, Nnv, table); - if (valuesE == NULL) return(NULL); + valuesT = ddCofMintermAux(dd, Nv, table); + if (valuesT == NULL) return(NULL); + valuesE = ddCofMintermAux(dd, Nnv, table); + if (valuesE == NULL) return(NULL); - if (Cudd_IsConstant(Nv)) { - localSizeT = 1; - } else { - localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; - } - if (Cudd_IsConstant(Nnv)) { - localSizeE = 1; - } else { - localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; - } - values[0] = valuesT[localSizeT - 1]; - for (i = 1; i < localSize; i++) { - if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { - vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + - cuddI(dd,N->index)]; + if (Cudd_IsConstant(Nv)) { + localSizeT = 1; } else { - vT = valuesT[localSizeT - 1]; + localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; } - if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { - vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + - cuddI(dd,N->index)]; + if (Cudd_IsConstant(Nnv)) { + localSizeE = 1; } else { - vE = valuesE[localSizeE - 1]; + localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; } - values[i] = (vT + vE) / 2.0; - } - if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT); - if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE); + values[0] = valuesT[localSizeT - 1]; + for (i = 1; i < localSize; i++) { + if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { + vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + + cuddI(dd,N->index)]; + } else { + vT = valuesT[localSizeT - 1]; + } + if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { + vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + + cuddI(dd,N->index)]; + } else { + vE = valuesE[localSizeE - 1]; + } + values[i] = (vT + vE) / 2.0; + } + if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT); + if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE); } if (N->ref > 1) { - if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { - ABC_FREE(values); - return(NULL); - } + if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { + ABC_FREE(values); + return(NULL); + } #ifdef DD_STATS - table_mem += localSize * sizeof(double) + sizeof(st_table_entry); + table_mem += localSize * sizeof(double) + sizeof(st_table_entry); #endif } return(values); } /* end of ddCofMintermAux */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSolve.c b/src/bdd/cudd/cuddSolve.c index 18d29dac..47570bf1 100644 --- a/src/bdd/cudd/cuddSolve.c +++ b/src/bdd/cudd/cuddSolve.c @@ -7,24 +7,51 @@ Synopsis [Boolean equation solver and related functions.] Description [External functions included in this modoule: - <ul> - <li> Cudd_SolveEqn() - <li> Cudd_VerifySol() - </ul> - Internal functions included in this module: - <ul> - <li> cuddSolveEqnRecur() - <li> cuddVerifySol() - </ul> ] + <ul> + <li> Cudd_SolveEqn() + <li> Cudd_VerifySol() + </ul> + Internal functions included in this module: + <ul> + <li> cuddSolveEqnRecur() + <li> cuddVerifySol() + </ul> ] SeeAlso [] Author [Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -34,6 +61,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -54,7 +82,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.12 2004/08/13 18:04:51 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -108,15 +136,15 @@ Cudd_SolveEqn( *yIndex = temp = ABC_ALLOC(int, n); if (temp == NULL) { - bdd->errorCode = CUDD_MEMORY_OUT; - (void) fprintf(bdd->out, - "Cudd_SolveEqn: Out of memory for yIndex\n"); - return(NULL); + bdd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(bdd->out, + "Cudd_SolveEqn: Out of memory for yIndex\n"); + return(NULL); } do { - bdd->reordered = 0; - res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); + bdd->reordered = 0; + res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); } while (bdd->reordered == 1); return(res); @@ -148,8 +176,8 @@ Cudd_VerifySol( DdNode *res; do { - bdd->reordered = 0; - res = cuddVerifySol(bdd, F, G, yIndex, n); + bdd->reordered = 0; + res = cuddVerifySol(bdd, F, G, yIndex, n); } while (bdd->reordered == 1); ABC_FREE(yIndex); @@ -199,7 +227,7 @@ cuddSolveEqnRecur( /* Base condition. */ if (Y == one) { - return F; + return F; } /* Cofactor of Y. */ @@ -209,61 +237,61 @@ cuddSolveEqnRecur( /* Universal abstraction of F with respect to the top variable index. */ Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); if (Fm1) { - Fm1 = Cudd_Not(Fm1); - cuddRef(Fm1); + Fm1 = Cudd_Not(Fm1); + cuddRef(Fm1); } else { - return(NULL); + return(NULL); } Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); if (Fn) { - cuddRef(Fn); + cuddRef(Fn); } else { - Cudd_RecursiveDeref(bdd, Fm1); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + return(NULL); } Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); if (Fv) { - cuddRef(Fv); + cuddRef(Fv); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + return(NULL); } Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); if (Fvbar) { - cuddRef(Fvbar); + cuddRef(Fvbar); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + return(NULL); } /* Build i-th component of the solution. */ w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); if (w) { - cuddRef(w); + cuddRef(w); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - Cudd_RecursiveDeref(bdd, Fvbar); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + return(NULL); } T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); if(T) { - cuddRef(T); + cuddRef(T); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - Cudd_RecursiveDeref(bdd, Fvbar); - Cudd_RecursiveDeref(bdd, w); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + Cudd_RecursiveDeref(bdd, w); + return(NULL); } Cudd_RecursiveDeref(bdd,Fm1); @@ -273,16 +301,16 @@ cuddSolveEqnRecur( /* Substitute components of solution already found into solution. */ for (j = n-1; j > i; j--) { - w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); - if(w) { - cuddRef(w); - } else { - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, T); - return(NULL); - } - Cudd_RecursiveDeref(bdd,T); - T = w; + w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); + if(w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, T); + return(NULL); + } + Cudd_RecursiveDeref(bdd,T); + T = w; } G[i] = T; @@ -319,14 +347,14 @@ cuddVerifySol( R = F; cuddRef(R); for(j = n - 1; j >= 0; j--) { - w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); - if (w) { - cuddRef(w); - } else { - return(NULL); - } - Cudd_RecursiveDeref(bdd,R); - R = w; + w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); + if (w) { + cuddRef(w); + } else { + return(NULL); + } + Cudd_RecursiveDeref(bdd,R); + R = w; } cuddDeref(R); @@ -340,5 +368,7 @@ cuddVerifySol( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddSplit.c b/src/bdd/cudd/cuddSplit.c index bad35d60..4ac243b5 100644 --- a/src/bdd/cudd/cuddSplit.c +++ b/src/bdd/cudd/cuddSplit.c @@ -7,28 +7,55 @@ Synopsis [Returns a subset of minterms from a boolean function.] Description [External functions included in this modoule: - <ul> - <li> Cudd_SplitSet() - </ul> - Internal functions included in this module: - <ul> - <li> cuddSplitSetRecur() - </u> + <ul> + <li> Cudd_SplitSet() + </ul> + Internal functions included in this module: + <ul> + <li> cuddSplitSetRecur() + </u> Static functions included in this module: - <ul> - <li> selectMintermsFromUniverse() - <li> mintermsFromUniverse() - <li> bddAnnotateMintermCount() - </ul> ] + <ul> + <li> selectMintermsFromUniverse() + <li> mintermsFromUniverse() + <li> bddAnnotateMintermCount() + </ul> ] SeeAlso [] Author [Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -38,6 +65,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,9 +96,9 @@ ABC_NAMESPACE_IMPL_START /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * selectMintermsFromUniverse ARGS((DdManager *manager, int *varSeen, double n)); -static DdNode * mintermsFromUniverse ARGS((DdManager *manager, DdNode **vars, int numVars, double n, int index)); -static double bddAnnotateMintermCount ARGS((DdManager *manager, DdNode *node, double max, st_table *table)); +static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n); +static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index); +static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table); /**AutomaticEnd***************************************************************/ @@ -117,69 +145,71 @@ Cudd_SplitSet( /* Trivial cases. */ if (m == 0.0) { - return(zero); + return(zero); } if (S == zero) { - return(NULL); + return(NULL); } max = pow(2.0,(double)n); if (m > max) - return(NULL); - - do { - manager->reordered = 0; - /* varSeen is used to mark the variables that are encountered - ** while traversing the BDD S. - */ - varSeen = ABC_ALLOC(int, size); - if (varSeen == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; return(NULL); - } - for (i = 0; i < size; i++) { - varSeen[i] = -1; - } - for (i = 0; i < n; i++) { - index = (xVars[i])->index; - varSeen[manager->invperm[index]] = 0; - } - if (S == one) { - if (m == max) - return(S); - result = selectMintermsFromUniverse(manager,varSeen,m); - if (result) - cuddRef(result); - ABC_FREE(varSeen); - } else { - mtable = st_init_table(st_ptrcmp, st_ptrhash);; - if (mtable == NULL) { - (void) fprintf(manager->out, - "Cudd_SplitSet: out-of-memory.\n"); - ABC_FREE(varSeen); - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - /* The nodes of BDD S are annotated by the number of minterms - ** in their onset. The node and the number of minterms in its - ** onset are stored in mtable. + do { + manager->reordered = 0; + /* varSeen is used to mark the variables that are encountered + ** while traversing the BDD S. */ - num = bddAnnotateMintermCount(manager,S,max,mtable); - if (m == num) { - st_foreach(mtable,(ST_PFSR)cuddStCountfree,NIL(char)); - st_free_table(mtable); - ABC_FREE(varSeen); - return(S); + varSeen = ABC_ALLOC(int, size); + if (varSeen == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + varSeen[i] = -1; + } + for (i = 0; i < n; i++) { + index = (xVars[i])->index; + varSeen[manager->invperm[index]] = 0; + } + + if (S == one) { + if (m == max) { + ABC_FREE(varSeen); + return(S); + } + result = selectMintermsFromUniverse(manager,varSeen,m); + if (result) + cuddRef(result); + ABC_FREE(varSeen); + } else { + mtable = st_init_table(st_ptrcmp,st_ptrhash); + if (mtable == NULL) { + (void) fprintf(manager->out, + "Cudd_SplitSet: out-of-memory.\n"); + ABC_FREE(varSeen); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* The nodes of BDD S are annotated by the number of minterms + ** in their onset. The node and the number of minterms in its + ** onset are stored in mtable. + */ + num = bddAnnotateMintermCount(manager,S,max,mtable); + if (m == num) { + st_foreach(mtable,cuddStCountfree,NIL(char)); + st_free_table(mtable); + ABC_FREE(varSeen); + return(S); + } + + result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); + if (result) + cuddRef(result); + st_foreach(mtable,cuddStCountfree,NULL); + st_free_table(mtable); + ABC_FREE(varSeen); } - - result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); - if (result) - cuddRef(result); - st_foreach(mtable,(ST_PFSR)cuddStCountfree,NULL); - st_free_table(mtable); - ABC_FREE(varSeen); - } } while (manager->reordered == 1); cuddDeref(result); @@ -238,8 +268,8 @@ cuddSplitSetRecur( ** constant 0. */ if (Cudd_IsConstant(p)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - return(q); + q = selectMintermsFromUniverse(manager,varSeen,n); + return(q); } N = Cudd_Regular(p); @@ -251,47 +281,47 @@ cuddSplitSetRecur( Nv = cuddT(N); Nnv = cuddE(N); if (Cudd_IsComplement(p)) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); } /* If both the children of 'p' are constants, extract n minterms from a ** constant node. */ if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - return(NULL); - } - cuddRef(q); - r = cuddBddAndRecur(manager,p,q); - if (r == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + return(NULL); + } + cuddRef(q); + r = cuddBddAndRecur(manager,p,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* Lookup the # of minterms in the onset of the node from the table. */ if (!Cudd_IsConstant(Nv)) { - st_lookup(mtable,(char *)Nv, (char **)&dummy); - numT = *dummy/(2*(1<<index)); + if (!st_lookup(mtable, (const char *)Nv, (char **)&dummy)) return(NULL); + numT = *dummy/(2*(1<<index)); } else if (Nv == one) { - numT = max/(2*(1<<index)); + numT = max/(2*(1<<index)); } else { - numT = 0; + numT = 0; } if (!Cudd_IsConstant(Nnv)) { - st_lookup(mtable,(char *)Nnv, (char **)&dummy); - numE = *dummy/(2*(1<<index)); + if (!st_lookup(mtable, (const char *)Nnv, (char **)&dummy)) return(NULL); + numE = *dummy/(2*(1<<index)); } else if (Nnv == one) { - numE = max/(2*(1<<index)); + numE = max/(2*(1<<index)); } else { - numE = 0; + numE = 0; } v = cuddUniqueInter(manager,variable,one,zero); @@ -299,72 +329,72 @@ cuddSplitSetRecur( /* If perfect match. */ if (numT == n) { - q = cuddBddAndRecur(manager,v,Nv); - if (q == NULL) { + q = cuddBddAndRecur(manager,v,Nv); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); + cuddDeref(q); + return(q); } if (numE == n) { - q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv); - if (q == NULL) { + q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); + cuddDeref(q); + return(q); } /* If n is greater than numT, extract the difference from the ELSE child ** and retain the function represented by the THEN branch. */ if (numT < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,(n-numT),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,Nv,q); - if (r == NULL) { + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nnv,(n-numT),max,index+1); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + r = cuddBddIteRecur(manager,v,Nv,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* If n is greater than numE, extract the difference from the THEN child ** and retain the function represented by the ELSE branch. */ if (numE < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv, (n-numE),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,q,Nnv); - if (r == NULL) { + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nv, (n-numE),max,index+1); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + r = cuddBddIteRecur(manager,v,q,Nnv); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* None of the above cases; (n < numT and n < numE) and either of @@ -372,41 +402,41 @@ cuddSplitSetRecur( ** required minterms the constant branch. */ if (Cudd_IsConstant(Nv) && !Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,v,q); - if (result == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + result = cuddBddAndRecur(manager,v,q); + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(result); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); + cuddDeref(result); + return(result); } else if (!Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,Cudd_Not(v),q); - if (result == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + result = cuddBddAndRecur(manager,Cudd_Not(v),q); + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(result); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); + cuddDeref(result); + return(result); } /* Both Nv and Nnv are not constants. So choose the one which @@ -414,29 +444,29 @@ cuddSplitSetRecur( */ positive = 0; if (numT < numE) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv,n,max,index+1); - positive = 1; + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nv,n,max,index+1); + positive = 1; } else { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,n,max,index+1); + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nnv,n,max,index+1); } if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); + Cudd_RecursiveDeref(manager,v); + return(NULL); } cuddRef(q); if (positive) { - result = cuddBddAndRecur(manager,v,q); + result = cuddBddAndRecur(manager,v,q); } else { - result = cuddBddAndRecur(manager,Cudd_Not(v),q); + result = cuddBddAndRecur(manager,Cudd_Not(v),q); } if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); } cuddRef(result); Cudd_RecursiveDeref(manager,q); @@ -485,22 +515,22 @@ selectMintermsFromUniverse( ** cuddSplitSetRecur. */ for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) - numVars++; + if(varSeen[i] == 0) + numVars++; } vars = ABC_ALLOC(DdNode *, numVars); if (!vars) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } j = 0; for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) { - vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); - cuddRef(vars[j]); - j++; - } + if(varSeen[i] == 0) { + vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); + cuddRef(vars[j]); + j++; + } } /* Compute a function which has n minterms and depends on at most @@ -508,10 +538,10 @@ selectMintermsFromUniverse( */ result = mintermsFromUniverse(manager,vars,numVars,n, 0); if (result) - cuddRef(result); + cuddRef(result); for (i = 0; i < numVars; i++) - Cudd_RecursiveDeref(manager,vars[i]); + Cudd_RecursiveDeref(manager,vars[i]); ABC_FREE(vars); return(result); @@ -548,37 +578,37 @@ mintermsFromUniverse( max2 = max / 2.0; if (n == max) - return(one); + return(one); if (n == 0.0) - return(zero); + return(zero); /* if n == 2^(numVars-1), return a single variable */ if (n == max2) - return vars[index]; + return vars[index]; else if (n > max2) { - /* When n > 2^(numVars-1), a single variable vars[index] - ** contains 2^(numVars-1) minterms. The rest are extracted - ** from a constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddIteRecur(manager,vars[index],one,q); + /* When n > 2^(numVars-1), a single variable vars[index] + ** contains 2^(numVars-1) minterms. The rest are extracted + ** from a constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddIteRecur(manager,vars[index],one,q); } else { - /* When n < 2^(numVars-1), a literal of variable vars[index] - ** is selected. The required n minterms are extracted from a - ** constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddAndRecur(manager,vars[index],q); + /* When n < 2^(numVars-1), a literal of variable vars[index] + ** is selected. The required n minterms are extracted from a + ** constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddAndRecur(manager,vars[index],q); } if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - return(NULL); + Cudd_RecursiveDeref(manager,q); + return(NULL); } cuddRef(result); Cudd_RecursiveDeref(manager,q); @@ -616,47 +646,49 @@ bddAnnotateMintermCount( statLine(manager); N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == DD_ONE(manager)) { - return(max); - } else { - return(0.0); - } + if (node == DD_ONE(manager)) { + return(max); + } else { + return(0.0); + } } - if (st_lookup(table,(char *)node,(char **)&dummy)) { - return(*dummy); - } + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + return(*dummy); + } Nv = cuddT(N); Nnv = cuddE(N); if (N != node) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); } /* Recur on the two branches. */ min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; if (min_v == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); + return ((double)CUDD_OUT_OF_MEM); min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; if (min_nv == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); + return ((double)CUDD_OUT_OF_MEM); min_N = min_v + min_nv; pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + manager->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min_N; if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min_N); } /* end of bddAnnotateMintermCount */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSubsetHB.c b/src/bdd/cudd/cuddSubsetHB.c index 86ed380f..68902b09 100644 --- a/src/bdd/cudd/cuddSubsetHB.c +++ b/src/bdd/cudd/cuddSubsetHB.c @@ -5,39 +5,66 @@ PackageName [cudd] Synopsis [Procedure to subset the given BDD by choosing the heavier - branches] + branches.] Description [External procedures provided by this module: <ul> - <li> Cudd_SubsetHeavyBranch() - <li> Cudd_SupersetHeavyBranch() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSubsetHeavyBranch() - </ul> - Static procedures included in this module: - <ul> - <li> ResizeCountMintermPages(); - <li> ResizeNodeDataPages() - <li> ResizeCountNodePages() - <li> SubsetCountMintermAux() - <li> SubsetCountMinterm() - <li> SubsetCountNodesAux() - <li> SubsetCountNodes() - <li> BuildSubsetBdd() - </ul> - ] + <li> Cudd_SubsetHeavyBranch() + <li> Cudd_SupersetHeavyBranch() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSubsetHeavyBranch() + </ul> + Static procedures included in this module: + <ul> + <li> ResizeCountMintermPages(); + <li> ResizeNodeDataPages() + <li> ResizeCountNodePages() + <li> SubsetCountMintermAux() + <li> SubsetCountMinterm() + <li> SubsetCountNodesAux() + <li> SubsetCountNodes() + <li> BuildSubsetBdd() + </ul> + ] SeeAlso [cuddSubsetSP.c] Author [Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -52,12 +79,13 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DEFAULT_PAGE_SIZE 2048 -#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 +#define DEFAULT_PAGE_SIZE 2048 +#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 #define INITIAL_PAGES 128 @@ -89,38 +117,38 @@ typedef struct NodeData NodeData_t; /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.37 2009/02/20 02:14:58 fabio Exp $"; #endif static int memOut; #ifdef DEBUG -static int num_calls; +static int num_calls; #endif -static DdNode *zero, *one; /* constant functions */ -static double **mintermPages; /* pointers to the pages */ -static int **nodePages; /* pointers to the pages */ -static int **lightNodePages; /* pointers to the pages */ -static double *currentMintermPage; /* pointer to the current - page */ -static double max; /* to store the 2^n value of the number - * of variables */ - -static int *currentNodePage; /* pointer to the current - page */ -static int *currentLightNodePage; /* pointer to the - * current page */ -static int pageIndex; /* index to next element */ -static int page; /* index to current page */ -static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ +static DdNode *zero, *one; /* constant functions */ +static double **mintermPages; /* pointers to the pages */ +static int **nodePages; /* pointers to the pages */ +static int **lightNodePages; /* pointers to the pages */ +static double *currentMintermPage; /* pointer to the current + page */ +static double max; /* to store the 2^n value of the number + * of variables */ + +static int *currentNodePage; /* pointer to the current + page */ +static int *currentLightNodePage; /* pointer to the + * current page */ +static int pageIndex; /* index to next element */ +static int page; /* index to current page */ +static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ static int maxPages; /* number of page pointers */ -static NodeData_t *currentNodeDataPage; /* pointer to the current - page */ -static int nodeDataPage; /* index to next element */ -static int nodeDataPageIndex; /* index to next element */ -static NodeData_t **nodeDataPages; /* index to current page */ -static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; +static NodeData_t *currentNodeDataPage; /* pointer to the current + page */ +static int nodeDataPage; /* index to next element */ +static int nodeDataPageIndex; /* index to next element */ +static NodeData_t **nodeDataPages; /* index to current page */ +static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; /* page size */ static int maxNodeDataPages; /* number of page pointers */ @@ -135,15 +163,15 @@ static int maxNodeDataPages; /* number of page pointers */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ResizeNodeDataPages ARGS(()); -static void ResizeCountMintermPages ARGS(()); -static void ResizeCountNodePages ARGS(()); -static double SubsetCountMintermAux ARGS((DdNode *node, double max, st_table *table)); -static st_table * SubsetCountMinterm ARGS((DdNode *node, int nvars)); -static int SubsetCountNodesAux ARGS((DdNode *node, st_table *table, double max)); -static int SubsetCountNodes ARGS((DdNode *node, st_table *table, int nvars)); -static void StoreNodes ARGS((st_table *storeTable, DdManager *dd, DdNode *node)); -static DdNode * BuildSubsetBdd ARGS((DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable)); +static void ResizeNodeDataPages (void); +static void ResizeCountMintermPages (void); +static void ResizeCountNodePages (void); +static double SubsetCountMintermAux (DdNode *node, double max, st_table *table); +static st_table * SubsetCountMinterm (DdNode *node, int nvars); +static int SubsetCountNodesAux (DdNode *node, st_table *table, double max); +static int SubsetCountNodes (DdNode *node, st_table *table, int nvars); +static void StoreNodes (st_table *storeTable, DdManager *dd, DdNode *node); +static DdNode * BuildSubsetBdd (DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable); /**AutomaticEnd***************************************************************/ @@ -188,8 +216,8 @@ Cudd_SubsetHeavyBranch( memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); } while ((dd->reordered == 1) && (!memOut)); return(subset); @@ -236,15 +264,15 @@ Cudd_SupersetHeavyBranch( { DdNode *subset, *g; - g = Cudd_Not(f); + g = Cudd_Not(f); memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); } while ((dd->reordered == 1) && (!memOut)); - + return(Cudd_NotCond(subset, (subset != NULL))); - + } /* end of Cudd_SupersetHeavyBranch */ @@ -286,18 +314,17 @@ cuddSubsetHeavyBranch( int numNodes; NodeData_t *currNodeQual; DdNode *subset; - double minN; st_table *storeTable, *approxTable; char *key, *value; st_generator *stGen; - + if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } - one = Cudd_ReadOne(dd); + one = Cudd_ReadOne(dd); zero = Cudd_Not(one); /* If user does not know numVars value, set it to the maximum @@ -306,12 +333,12 @@ cuddSubsetHeavyBranch( * log gives. */ if (numVars == 0) { - /* set default value */ - numVars = DBL_MAX_EXP - 1; + /* set default value */ + numVars = DBL_MAX_EXP - 1; } if (Cudd_IsConstant(f)) { - return(f); + return(f); } max = pow(2.0, (double)numVars); @@ -320,29 +347,27 @@ cuddSubsetHeavyBranch( stored in a st_table */ visitedTable = SubsetCountMinterm(f, numVars); if ((visitedTable == NULL) || memOut) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } numNodes = SubsetCountNodes(f, visitedTable, numVars); if (memOut) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - if (st_lookup(visitedTable, (char *)f, (char **)&currNodeQual)) { - minN = *(((NodeData_t *)currNodeQual)->mintermPointer); - } else { - fprintf(dd->err, - "Something is wrong, ought to be node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (st_lookup(visitedTable, (const char *)f, (char **)&currNodeQual) == 0) { + fprintf(dd->err, + "Something is wrong, ought to be node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; } size = ABC_ALLOC(int, 1); if (size == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } *size = numNodes; @@ -354,53 +379,53 @@ cuddSubsetHeavyBranch( /* insert the constant */ cuddRef(one); if (st_insert(storeTable, (char *)Cudd_ReadOne(dd), NIL(char)) == - ST_OUT_OF_MEM) { - fprintf(dd->out, "Something wrong, st_table insert failed\n"); + ST_OUT_OF_MEM) { + fprintf(dd->out, "Something wrong, st_table insert failed\n"); } /* table to store approximations of nodes */ approxTable = st_init_table(st_ptrcmp, st_ptrhash); subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold, - storeTable, approxTable); + storeTable, approxTable); if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); } stGen = st_init_gen(approxTable); if (stGen == NULL) { - st_free_table(approxTable); - return(NULL); + st_free_table(approxTable); + return(NULL); } while(st_gen(stGen, (const char **)&key, (char **)&value)) { - Cudd_RecursiveDeref(dd, (DdNode *)value); + Cudd_RecursiveDeref(dd, (DdNode *)value); } st_free_gen(stGen); stGen = NULL; st_free_table(approxTable); stGen = st_init_gen(storeTable); if (stGen == NULL) { - st_free_table(storeTable); - return(NULL); + st_free_table(storeTable); + return(NULL); } while(st_gen(stGen, (const char **)&key, (char **)&value)) { - Cudd_RecursiveDeref(dd, (DdNode *)key); + Cudd_RecursiveDeref(dd, (DdNode *)key); } st_free_gen(stGen); stGen = NULL; st_free_table(storeTable); for (i = 0; i <= page; i++) { - ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages[i]); } ABC_FREE(mintermPages); for (i = 0; i <= page; i++) { - ABC_FREE(nodePages[i]); + ABC_FREE(nodePages[i]); } ABC_FREE(nodePages); for (i = 0; i <= page; i++) { - ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages[i]); } ABC_FREE(lightNodePages); for (i = 0; i <= nodeDataPage; i++) { - ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages[i]); } ABC_FREE(nodeDataPages); st_free_table(visitedTable); @@ -413,9 +438,9 @@ cuddSubsetHeavyBranch( if (subset != NULL) { #ifdef DD_DEBUG if (!Cudd_bddLeq(dd, subset, f)) { - fprintf(dd->err, "Wrong subset\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } #endif cuddDeref(subset); @@ -446,8 +471,7 @@ cuddSubsetHeavyBranch( ******************************************************************************/ static void -ResizeNodeDataPages( - ) +ResizeNodeDataPages(void) { int i; NodeData_t **newNodeDataPages; @@ -458,30 +482,30 @@ ResizeNodeDataPages( * INITIAL_PAGES */ if (nodeDataPage == maxNodeDataPages) { - newNodeDataPages = ABC_ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); - if (newNodeDataPages == NULL) { - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxNodeDataPages; i++) { - newNodeDataPages[i] = nodeDataPages[i]; + newNodeDataPages = ABC_ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); + if (newNodeDataPages == NULL) { + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDataPages; i++) { + newNodeDataPages[i] = nodeDataPages[i]; + } + /* Increase total page count */ + maxNodeDataPages += INITIAL_PAGES; + ABC_FREE(nodeDataPages); + nodeDataPages = newNodeDataPages; } - /* Increase total page count */ - maxNodeDataPages += INITIAL_PAGES; - ABC_FREE(nodeDataPages); - nodeDataPages = newNodeDataPages; - } } /* Allocate a new page */ currentNodeDataPage = nodeDataPages[nodeDataPage] = - ABC_ALLOC(NodeData_t ,nodeDataPageSize); + ABC_ALLOC(NodeData_t ,nodeDataPageSize); if (currentNodeDataPage == NULL) { - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - memOut = 1; - return; + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + memOut = 1; + return; } /* reset page index */ nodeDataPageIndex = 0; @@ -499,15 +523,14 @@ ResizeNodeDataPages( counts. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary.] - SideEffects [Changes the size of minterm pages, page, page index, maximum + SideEffects [Changes the size of minterm pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeCountMintermPages( - ) +ResizeCountMintermPages(void) { int i; double **newMintermPages; @@ -518,29 +541,29 @@ ResizeCountMintermPages( * INITIAL_PAGES */ if (page == maxPages) { - newMintermPages = ABC_ALLOC(double *,maxPages + INITIAL_PAGES); - if (newMintermPages == NULL) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxPages; i++) { - newMintermPages[i] = mintermPages[i]; + newMintermPages = ABC_ALLOC(double *,maxPages + INITIAL_PAGES); + if (newMintermPages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newMintermPages[i] = mintermPages[i]; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + ABC_FREE(mintermPages); + mintermPages = newMintermPages; } - /* Increase total page count */ - maxPages += INITIAL_PAGES; - ABC_FREE(mintermPages); - mintermPages = newMintermPages; - } } /* Allocate a new page */ currentMintermPage = mintermPages[page] = ABC_ALLOC(double,pageSize); if (currentMintermPage == NULL) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - memOut = 1; - return; + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + memOut = 1; + return; } /* reset page index */ pageIndex = 0; @@ -564,8 +587,7 @@ ResizeCountMintermPages( ******************************************************************************/ static void -ResizeCountNodePages( - ) +ResizeCountNodePages(void) { int i; int **newNodePages; @@ -577,59 +599,59 @@ ResizeCountNodePages( * by INITIAL_PAGES. */ if (page == maxPages) { - newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); - if (newNodePages == NULL) { - for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; - } else { - for (i = 0; i < maxPages; i++) { - newNodePages[i] = nodePages[i]; + newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = nodePages[i]; + } + ABC_FREE(nodePages); + nodePages = newNodePages; } - ABC_FREE(nodePages); - nodePages = newNodePages; - } - newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); - if (newNodePages == NULL) { + newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = lightNodePages[i]; + } + ABC_FREE(lightNodePages); + lightNodePages = newNodePages; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + } + /* Allocate a new page */ + currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); + if (currentNodePage == NULL) { for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); ABC_FREE(nodePages); for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); ABC_FREE(lightNodePages); memOut = 1; return; - } else { - for (i = 0; i < maxPages; i++) { - newNodePages[i] = lightNodePages[i]; - } - ABC_FREE(lightNodePages); - lightNodePages = newNodePages; - } - /* Increase total page count */ - maxPages += INITIAL_PAGES; - } - /* Allocate a new page */ - currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); - if (currentNodePage == NULL) { - for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; } /* Allocate a new page */ currentLightNodePage = lightNodePages[page] = ABC_ALLOC(int,pageSize); if (currentLightNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; + for (i = 0; i <= page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; } /* reset page index */ pageIndex = 0; @@ -661,9 +683,9 @@ SubsetCountMintermAux( st_table * table /* visitedTable table */) { - DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ - double min,*pmin; /* minterm count */ - double min1, min2; /* minterm count */ + DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ + double min,*pmin; /* minterm count */ + double min1, min2; /* minterm count */ NodeData_t *dummy; NodeData_t *newEntry; int i; @@ -674,79 +696,79 @@ SubsetCountMintermAux( /* Constant case */ if (Cudd_IsConstant(node)) { - if (node == zero) { - return(0.0); - } else { - return(max); - } + if (node == zero) { + return(0.0); + } else { + return(max); + } } else { - /* check if entry for this node exists */ - if (st_lookup(table,(char *)node, (char **)&dummy)) { - min = *(dummy->mintermPointer); - return(min); - } - - /* Make the node regular to extract cofactors */ - N = Cudd_Regular(node); - - /* store the cofactors */ - Nv = Cudd_T(N); - Nnv = Cudd_E(N); - - Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); - Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); - - min1 = SubsetCountMintermAux(Nv, max,table)/2.0; - if (memOut) return(0.0); - min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; - if (memOut) return(0.0); - min = (min1+min2); - - /* if page index is at the bottom, then create a new page */ - if (pageIndex == pageSize) ResizeCountMintermPages(); - if (memOut) { - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0.0); - } - - /* point to the correct location in the page */ - pmin = currentMintermPage+pageIndex; - pageIndex++; + /* check if entry for this node exists */ + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + min = *(dummy->mintermPointer); + return(min); + } - /* store the minterm count of this node in the page */ - *pmin = min; + /* Make the node regular to extract cofactors */ + N = Cudd_Regular(node); + + /* store the cofactors */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + min1 = SubsetCountMintermAux(Nv, max,table)/2.0; + if (memOut) return(0.0); + min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; + if (memOut) return(0.0); + min = (min1+min2); + + /* if page index is at the bottom, then create a new page */ + if (pageIndex == pageSize) ResizeCountMintermPages(); + if (memOut) { + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } - /* Note I allocate the struct here. Freeing taken care of later */ - if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - st_free_table(table); - return(0.0); - } + /* point to the correct location in the page */ + pmin = currentMintermPage+pageIndex; + pageIndex++; - newEntry = currentNodeDataPage + nodeDataPageIndex; - nodeDataPageIndex++; + /* store the minterm count of this node in the page */ + *pmin = min; - /* points to the correct location in the page */ - newEntry->mintermPointer = pmin; - /* initialize this field of the Node Quality structure */ - newEntry->nodesPointer = NULL; + /* Note I allocate the struct here. Freeing taken care of later */ + if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + st_free_table(table); + return(0.0); + } - /* insert entry for the node in the table */ - if (st_insert(table,(char *)node, (char *)newEntry) == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0.0); - } - return(min); + newEntry = currentNodeDataPage + nodeDataPageIndex; + nodeDataPageIndex++; + + /* points to the correct location in the page */ + newEntry->mintermPointer = pmin; + /* initialize this field of the Node Quality structure */ + newEntry->nodesPointer = NULL; + + /* insert entry for the node in the table */ + if (st_insert(table,(char *)node, (char *)newEntry) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + return(min); } } /* end of SubsetCountMintermAux */ @@ -771,7 +793,6 @@ SubsetCountMinterm( int nvars /* number of variables node depends on */) { st_table *table; - double num; int i; @@ -780,44 +801,44 @@ SubsetCountMinterm( #endif max = pow(2.0,(double) nvars); - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) goto OUT_OF_MEM; maxPages = INITIAL_PAGES; mintermPages = ABC_ALLOC(double *,maxPages); if (mintermPages == NULL) { - st_free_table(table); - goto OUT_OF_MEM; + st_free_table(table); + goto OUT_OF_MEM; } page = 0; currentMintermPage = ABC_ALLOC(double,pageSize); mintermPages[page] = currentMintermPage; if (currentMintermPage == NULL) { - ABC_FREE(mintermPages); - st_free_table(table); - goto OUT_OF_MEM; + ABC_FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; } pageIndex = 0; maxNodeDataPages = INITIAL_PAGES; nodeDataPages = ABC_ALLOC(NodeData_t *, maxNodeDataPages); if (nodeDataPages == NULL) { - for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - st_free_table(table); - goto OUT_OF_MEM; + for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; } nodeDataPage = 0; currentNodeDataPage = ABC_ALLOC(NodeData_t ,nodeDataPageSize); nodeDataPages[nodeDataPage] = currentNodeDataPage; if (currentNodeDataPage == NULL) { - for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - ABC_FREE(nodeDataPages); - st_free_table(table); - goto OUT_OF_MEM; + for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + ABC_FREE(nodeDataPages); + st_free_table(table); + goto OUT_OF_MEM; } nodeDataPageIndex = 0; - num = SubsetCountMintermAux(node,max,table); + (void) SubsetCountMintermAux(node,max,table); if (memOut) goto OUT_OF_MEM; return(table); @@ -860,94 +881,94 @@ SubsetCountNodesAux( int *pmin, *pminBar, *val; if ((node == NULL) || Cudd_IsConstant(node)) - return(0); + return(0); /* if this node has been processed do nothing */ - if (st_lookup(table, (char *)node, (char **)&dummyN) == 1) { - val = dummyN->nodesPointer; - if (val != NULL) - return(0); + if (st_lookup(table, (const char *)node, (char **)&dummyN) == 1) { + val = dummyN->nodesPointer; + if (val != NULL) + return(0); } else { - return(0); + return(0); } N = Cudd_Regular(node); Nv = Cudd_T(N); Nnv = Cudd_E(N); - + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); /* find the minterm counts for the THEN and ELSE branches */ if (Cudd_IsConstant(Nv)) { - if (Nv == zero) { - minNv = 0.0; - } else { - minNv = max; - } + if (Nv == zero) { + minNv = 0.0; + } else { + minNv = max; + } } else { - if (st_lookup(table, (char *)Nv, (char **)&dummyNv) == 1) - minNv = *(dummyNv->mintermPointer); - else { - return(0); - } + if (st_lookup(table, (const char *)Nv, (char **)&dummyNv) == 1) + minNv = *(dummyNv->mintermPointer); + else { + return(0); + } } if (Cudd_IsConstant(Nnv)) { - if (Nnv == zero) { - minNnv = 0.0; - } else { - minNnv = max; - } + if (Nnv == zero) { + minNnv = 0.0; + } else { + minNnv = max; + } } else { - if (st_lookup(table, (char *)Nnv, (char **)&dummyNnv) == 1) { - minNnv = *(dummyNnv->mintermPointer); - } - else { - return(0); - } + if (st_lookup(table, (const char *)Nnv, (char **)&dummyNnv) == 1) { + minNnv = *(dummyNnv->mintermPointer); + } + else { + return(0); + } } /* recur based on which has larger minterm, */ if (minNv >= minNnv) { - tval = SubsetCountNodesAux(Nv, table, max); - if (memOut) return(0); - eval = SubsetCountNodesAux(Nnv, table, max); - if (memOut) return(0); - - /* store the node count of the lighter child. */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pmin = currentLightNodePage + pageIndex; - *pmin = eval; /* Here the ELSE child is lighter */ - dummyN->lightChildNodesPointer = pmin; + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = eval; /* Here the ELSE child is lighter */ + dummyN->lightChildNodesPointer = pmin; } else { - eval = SubsetCountNodesAux(Nnv, table, max); - if (memOut) return(0); - tval = SubsetCountNodesAux(Nv, table, max); - if (memOut) return(0); - - /* store the node count of the lighter child. */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pmin = currentLightNodePage + pageIndex; - *pmin = tval; /* Here the THEN child is lighter */ - dummyN->lightChildNodesPointer = pmin; + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = tval; /* Here the THEN child is lighter */ + dummyN->lightChildNodesPointer = pmin; } /* updating the page index for node count storage. */ @@ -962,36 +983,36 @@ SubsetCountNodesAux( branch. Its complement will be reached later on a lighter branch. Hence the complement has zero node count. */ - if (st_lookup(table, (char *)Cudd_Not(node), (char **)&dummyNBar) == 1) { - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pminBar = currentLightNodePage + pageIndex; - *pminBar = 0; - dummyNBar->lightChildNodesPointer = pminBar; - /* The lighter child has less nodes than the parent. - * So if parent 0 then lighter child zero - */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pminBar = currentNodePage + pageIndex; - *pminBar = 0; - dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ + if (st_lookup(table, (const char *)Cudd_Not(node), (char **)&dummyNBar) == 1) { + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentLightNodePage + pageIndex; + *pminBar = 0; + dummyNBar->lightChildNodesPointer = pminBar; + /* The lighter child has less nodes than the parent. + * So if parent 0 then lighter child zero + */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentNodePage + pageIndex; + *pminBar = 0; + dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ - pageIndex++; + pageIndex++; } return(*pmin); } /*end of SubsetCountNodesAux */ @@ -1017,7 +1038,7 @@ SubsetCountNodes( st_table * table /* node quality table */, int nvars /* number of variables node depends on */) { - int num; + int num; int i; #ifdef DEBUG @@ -1028,41 +1049,41 @@ SubsetCountNodes( maxPages = INITIAL_PAGES; nodePages = ABC_ALLOC(int *,maxPages); if (nodePages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } lightNodePages = ABC_ALLOC(int *,maxPages); if (lightNodePages == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } page = 0; currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); if (currentNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(lightNodePages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(lightNodePages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } currentLightNodePage = lightNodePages[page] = ABC_ALLOC(int,pageSize); if (currentLightNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(currentNodePage); - ABC_FREE(lightNodePages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(currentNodePage); + ABC_FREE(lightNodePages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } pageIndex = 0; @@ -1094,18 +1115,17 @@ StoreNodes( DdManager * dd, DdNode * node) { - char *dummy; DdNode *N, *Nt, *Ne; if (Cudd_IsConstant(dd)) { - return; + return; } N = Cudd_Regular(node); - if (st_lookup(storeTable, (char *)N, (char **)&dummy)) { - return; + if (st_lookup(storeTable, (char *)N, NIL(char *))) { + return; } cuddRef(N); if (st_insert(storeTable, (char *)N, NIL(char)) == ST_OUT_OF_MEM) { - fprintf(dd->err,"Something wrong, st_table insert failed\n"); + fprintf(dd->err,"Something wrong, st_table insert failed\n"); } Nt = Cudd_T(N); @@ -1120,7 +1140,7 @@ StoreNodes( /**Function******************************************************************** - Synopsis [Builds the subset BDD using the heavy branch method.] + Synopsis [Builds the subset BDD using the heavy branch method.] Description [The procedure carries out the building of the subset BDD starting at the root. Using the three different counts labelling each node, @@ -1166,12 +1186,12 @@ BuildSubsetBdd( } if (Cudd_IsConstant(node)) - return(node); + return(node); /* Look up minterm count for this node. */ - if (!st_lookup(visitedTable, (char *)node, (char **)&currNodeQual)) { - fprintf(dd->err, - "Something is wrong, ought to be in node quality table\n"); + if (!st_lookup(visitedTable, (const char *)node, (char **)&currNodeQual)) { + fprintf(dd->err, + "Something is wrong, ought to be in node quality table\n"); } /* Get children. */ @@ -1185,37 +1205,36 @@ BuildSubsetBdd( if (!Cudd_IsConstant(Nv)) { /* find out minterms and nodes contributed by then child */ - if (!st_lookup(visitedTable, (char *)Nv, - (char **)&currNodeQualT)) { - fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(visitedTable, (const char *)Nv, (char **)&currNodeQualT)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + else { + minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); } - else { - minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); - } } else { - if (Nv == zero) { - minNv = 0; - } else { - minNv = max; - } + if (Nv == zero) { + minNv = 0; + } else { + minNv = max; + } } if (!Cudd_IsConstant(Nnv)) { /* find out minterms and nodes contributed by else child */ - if (!st_lookup(visitedTable, (char *)Nnv, (char **)&currNodeQualE)) { - fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } else { - minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); - } - } else { - if (Nnv == zero) { - minNnv = 0; + if (!st_lookup(visitedTable, (const char *)Nnv, (char **)&currNodeQualE)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } else { + minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); + } } else { - minNnv = max; - } + if (Nnv == zero) { + minNnv = 0; + } else { + minNnv = max; + } } /* keep track of size of subset by subtracting the number of @@ -1223,57 +1242,57 @@ BuildSubsetBdd( */ *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer); if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes - the Then branch in case of a tie */ + the Then branch in case of a tie */ /* recur with the Then branch */ - ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, - visitedTable, threshold, storeTable, approxTable); - if (ThenBranch == NULL) { - return(NULL); - } - cuddRef(ThenBranch); - /* The Else branch is either a node that already exists in the - * subset, or one whose approximation has been computed, or - * Zero. - */ - if (st_lookup(storeTable, (char *)Cudd_Regular(Nnv), (char **)&dummy)) { - ElseBranch = Nnv; - cuddRef(ElseBranch); - } else { - if (st_lookup(approxTable, (char *)Nnv, (char **)&dummy)) { - ElseBranch = (DdNode *)dummy; - cuddRef(ElseBranch); - } else { - ElseBranch = zero; - cuddRef(ElseBranch); - } - } - + ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, + visitedTable, threshold, storeTable, approxTable); + if (ThenBranch == NULL) { + return(NULL); + } + cuddRef(ThenBranch); + /* The Else branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, (char *)Cudd_Regular(Nnv), &dummy)) { + ElseBranch = Nnv; + cuddRef(ElseBranch); + } else { + if (st_lookup(approxTable, (char *)Nnv, &dummy)) { + ElseBranch = (DdNode *)dummy; + cuddRef(ElseBranch); + } else { + ElseBranch = zero; + cuddRef(ElseBranch); + } + } + } else { /* recur with the Else branch */ ElseBranch = (DdNode *)BuildSubsetBdd(dd, Nnv, size, - visitedTable, threshold, storeTable, approxTable); - if (ElseBranch == NULL) { - return(NULL); - } - cuddRef(ElseBranch); - /* The Then branch is either a node that already exists in the - * subset, or one whose approximation has been computed, or - * Zero. - */ - if (st_lookup(storeTable, (char *)Cudd_Regular(Nv), (char **)&dummy)) { - ThenBranch = Nv; - cuddRef(ThenBranch); - } else { - if (st_lookup(approxTable, (char *)Nv, (char **)&dummy)) { - ThenBranch = (DdNode *)dummy; - cuddRef(ThenBranch); - } else { - ThenBranch = zero; - cuddRef(ThenBranch); - } - } + visitedTable, threshold, storeTable, approxTable); + if (ElseBranch == NULL) { + return(NULL); + } + cuddRef(ElseBranch); + /* The Then branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, (char *)Cudd_Regular(Nv), &dummy)) { + ThenBranch = Nv; + cuddRef(ThenBranch); + } else { + if (st_lookup(approxTable, (char *)Nv, &dummy)) { + ThenBranch = (DdNode *)dummy; + cuddRef(ThenBranch); + } else { + ThenBranch = zero; + cuddRef(ThenBranch); + } + } } /* construct the Bdd with the top variable and the two children */ @@ -1288,29 +1307,31 @@ BuildSubsetBdd( Cudd_RecursiveDeref(dd, ThenBranch); Cudd_RecursiveDeref(dd, ElseBranch); - + if (neW == NULL) - return(NULL); + return(NULL); else { /* store this node in the store table */ - if (!st_lookup(storeTable, (char *)Cudd_Regular(neW), (char **)&dummy)) { - cuddRef(neW); - st_insert(storeTable, (char *)Cudd_Regular(neW), (char *)NIL(char)); - + if (!st_lookup(storeTable, (char *)Cudd_Regular(neW), &dummy)) { + cuddRef(neW); + if (!st_insert(storeTable, (char *)Cudd_Regular(neW), NIL(char))) + return (NULL); } - /* store the approximation for this node */ - if (N != Cudd_Regular(neW)) { - if (st_lookup(approxTable, (char *)node, (char **)&dummy)) { - fprintf(dd->err, "This node should not be in the approximated table\n"); - } else { - cuddRef(neW); - st_insert(approxTable, (char *)node, (char *)neW); + /* store the approximation for this node */ + if (N != Cudd_Regular(neW)) { + if (st_lookup(approxTable, (char *)node, &dummy)) { + fprintf(dd->err, "This node should not be in the approximated table\n"); + } else { + cuddRef(neW); + if (!st_insert(approxTable, (char *)node, (char *)neW)) + return(NULL); + } } - } cuddDeref(neW); return(neW); } } /* end of BuildSubsetBdd */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSubsetSP.c b/src/bdd/cudd/cuddSubsetSP.c index d336187b..cddc58ed 100644 --- a/src/bdd/cudd/cuddSubsetSP.c +++ b/src/bdd/cudd/cuddSubsetSP.c @@ -9,35 +9,62 @@ Description [External procedures included in this module: - <ul> - <li> Cudd_SubsetShortPaths() - <li> Cudd_SupersetShortPaths() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSubsetShortPaths() - </ul> - Static procedures included in this module: - <ul> - <li> BuildSubsetBdd() - <li> CreatePathTable() - <li> AssessPathLength() - <li> CreateTopDist() - <li> CreateBotDist() - <li> ResizeNodeDistPages() - <li> ResizeQueuePages() - <li> stPathTableDdFree() - </ul> - ] + <ul> + <li> Cudd_SubsetShortPaths() + <li> Cudd_SupersetShortPaths() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSubsetShortPaths() + </ul> + Static procedures included in this module: + <ul> + <li> BuildSubsetBdd() + <li> CreatePathTable() + <li> AssessPathLength() + <li> CreateTopDist() + <li> CreateBotDist() + <li> ResizeNodeDistPages() + <li> ResizeQueuePages() + <li> stPathTableDdFree() + </ul> + ] SeeAlso [cuddSubsetHB.c] Author [Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -47,25 +74,26 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ #define DEFAULT_PAGE_SIZE 2048 /* page size to store the BFS queue element type */ #define DEFAULT_NODE_DIST_PAGE_SIZE 2048 /* page sizesto store NodeDist_t type */ -#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store - * maximum distance of a node - * from the root or the - * constant - */ +#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store + * maximum distance of a node + * from the root or the + * constant + */ #define INITIAL_PAGES 128 /* number of initial pages for the - * queue/NodeDist_t type */ + * queue/NodeDist_t type */ /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ -/* structure created to store subset results for each node and distances with +/* structure created to store subset results for each node and distances with * odd and even parity of the node from the root and sink. Main data structure * in this procedure. */ @@ -98,7 +126,7 @@ typedef struct NodeDist NodeDist_t; /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.34 2009/02/19 16:23:19 fabio Exp $"; #endif #ifdef DD_DEBUG @@ -108,21 +136,21 @@ static int thishit; #endif -static int memOut; /* flag to indicate out of memory */ +static int memOut; /* flag to indicate out of memory */ static DdNode *zero, *one; /* constant functions */ static NodeDist_t **nodeDistPages; /* pointers to the pages */ -static int nodeDistPageIndex; /* index to next element */ -static int nodeDistPage; /* index to current page */ -static int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; /* page size */ -static int maxNodeDistPages; /* number of page pointers */ +static int nodeDistPageIndex; /* index to next element */ +static int nodeDistPage; /* index to current page */ +static int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; /* page size */ +static int maxNodeDistPages; /* number of page pointers */ static NodeDist_t *currentNodeDistPage; /* current page */ static DdNode ***queuePages; /* pointers to the pages */ -static int queuePageIndex; /* index to next element */ -static int queuePage; /* index to current page */ -static int queuePageSize = DEFAULT_PAGE_SIZE; /* page size */ -static int maxQueuePages; /* number of page pointers */ +static int queuePageIndex; /* index to next element */ +static int queuePage; /* index to current page */ +static int queuePageSize = DEFAULT_PAGE_SIZE; /* page size */ +static int maxQueuePages; /* number of page pointers */ static DdNode **currentQueuePage; /* current page */ @@ -130,23 +158,30 @@ static DdNode **currentQueuePage; /* current page */ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ResizeNodeDistPages ARGS(()); -static void ResizeQueuePages ARGS(()); -static void CreateTopDist ARGS((st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp)); -static int CreateBotDist ARGS((DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp)); -static st_table * CreatePathTable ARGS((DdNode *node, unsigned int *pathLengthArray, FILE *fp)); -static unsigned int AssessPathLength ARGS((unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp)); -static DdNode * BuildSubsetBdd ARGS((DdManager *dd, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable)); -static enum st_retval stPathTableDdFree ARGS((char *key, char *value, char *arg)); +static void ResizeNodeDistPages (void); +static void ResizeQueuePages (void); +static void CreateTopDist (st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp); +static int CreateBotDist (DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp); +static st_table * CreatePathTable (DdNode *node, unsigned int *pathLengthArray, FILE *fp); +static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp); +static DdNode * BuildSubsetBdd (DdManager *dd, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable); +static enum st_retval stPathTableDdFree (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of Exported functions */ @@ -193,8 +228,8 @@ Cudd_SubsetShortPaths( memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); } while((dd->reordered ==1) && (!memOut)); return(subset); @@ -246,8 +281,8 @@ Cudd_SupersetShortPaths( g = Cudd_Not(f); memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); } while((dd->reordered ==1) && (!memOut)); return(Cudd_NotCond(subset, (subset != NULL))); @@ -291,7 +326,7 @@ cuddSubsetShortPaths( unsigned int *pathLengthArray; unsigned int maxpath, oddLen, evenLen, pathLength, *excess; int i; - NodeDist_t *nodeStat; + NodeDist_t *nodeStat; struct AssortedInfo *info; st_table *subsetNodeTable; @@ -302,17 +337,17 @@ cuddSubsetShortPaths( /* set default value */ numVars = Cudd_ReadSize(dd); } - + if (threshold > numVars) { - threshold = threshold - numVars; + threshold = threshold - numVars; } if (f == NULL) { - fprintf(dd->err, "Cannot partition, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot partition, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) - return (f); + return (f); pathLengthArray = ABC_ALLOC(unsigned int, numVars+1); for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0; @@ -325,101 +360,103 @@ cuddSubsetShortPaths( pathTable = CreatePathTable(f, pathLengthArray, dd->err); if ((pathTable == NULL) || (memOut)) { - if (pathTable != NULL) - st_free_table(pathTable); - ABC_FREE(pathLengthArray); - return (NIL(DdNode)); + if (pathTable != NULL) + st_free_table(pathTable); + ABC_FREE(pathLengthArray); + return (NIL(DdNode)); } excess = ABC_ALLOC(unsigned int, 1); *excess = 0; maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess, - dd->err); + dd->err); if (maxpath != (unsigned) (numVars + 1)) { - info = ABC_ALLOC(struct AssortedInfo, 1); - info->maxpath = maxpath; - info->findShortestPath = 0; - info->thresholdReached = *excess; - info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); - info->threshold = threshold; + info = ABC_ALLOC(struct AssortedInfo, 1); + info->maxpath = maxpath; + info->findShortestPath = 0; + info->thresholdReached = *excess; + info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); + info->threshold = threshold; #ifdef DD_DEBUG - (void) fprintf(dd->out, "Path length array\n"); - for (i = 0; i < (numVars+1); i++) { - if (pathLengthArray[i]) - (void) fprintf(dd->out, "%d ",i); - } - (void) fprintf(dd->out, "\n"); - for (i = 0; i < (numVars+1); i++) { - if (pathLengthArray[i]) - (void) fprintf(dd->out, "%d ",pathLengthArray[i]); - } - (void) fprintf(dd->out, "\n"); - (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", - maxpath, info->thresholdReached); + (void) fprintf(dd->out, "Path length array\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",i); + } + (void) fprintf(dd->out, "\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",pathLengthArray[i]); + } + (void) fprintf(dd->out, "\n"); + (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", + maxpath, info->thresholdReached); #endif - N = Cudd_Regular(f); - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - fprintf(dd->err, "Something wrong, root node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } else { - if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); - else - oddLen = MAXSHORTINT; - - if ((nodeStat->evenTopDist != MAXSHORTINT) && - (nodeStat->evenBotDist != MAXSHORTINT)) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); - else - evenLen = MAXSHORTINT; - - pathLength = (oddLen <= evenLen) ? oddLen : evenLen; - if (pathLength > maxpath) { - (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %d, %d\n", maxpath, pathLength); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + N = Cudd_Regular(f); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + fprintf(dd->err, "Something wrong, root node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + ABC_FREE(excess); + ABC_FREE(info); + return(NULL); + } else { + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + if (pathLength > maxpath) { + (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } } - } #ifdef DD_DEBUG - numCalls = 0; - hits = 0; - thishit = 0; + numCalls = 0; + hits = 0; + thishit = 0; #endif - /* initialize a table to store computed nodes */ - if (hardlimit) { - subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); - } else { - subsetNodeTable = NIL(st_table); - } - subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable); - if (subset != NULL) { - cuddRef(subset); - } - /* record the number of times a computed result for a node is hit */ + /* initialize a table to store computed nodes */ + if (hardlimit) { + subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); + } else { + subsetNodeTable = NIL(st_table); + } + subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable); + if (subset != NULL) { + cuddRef(subset); + } + /* record the number of times a computed result for a node is hit */ #ifdef DD_DEBUG - (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", - hits, thishit, numCalls); + (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", + hits, thishit, numCalls); #endif - if (subsetNodeTable != NIL(st_table)) { - st_free_table(subsetNodeTable); - } - st_free_table(info->maxpathTable); - st_foreach(pathTable, (ST_PFSR)stPathTableDdFree, (char *)dd); + if (subsetNodeTable != NIL(st_table)) { + st_free_table(subsetNodeTable); + } + st_free_table(info->maxpathTable); + st_foreach(pathTable, stPathTableDdFree, (char *)dd); - ABC_FREE(info); + ABC_FREE(info); } else {/* if threshold larger than size of dd */ - subset = f; - cuddRef(subset); + subset = f; + cuddRef(subset); } ABC_FREE(excess); st_free_table(pathTable); @@ -430,21 +467,21 @@ cuddSubsetShortPaths( #ifdef DD_DEBUG /* check containment of subset in f */ if (subset != NULL) { - DdNode *check; - check = Cudd_bddIteConstant(dd, subset, f, one); - if (check != one) { - (void) fprintf(dd->err, "Wrong partition\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } + DdNode *check; + check = Cudd_bddIteConstant(dd, subset, f, one); + if (check != one) { + (void) fprintf(dd->err, "Wrong partition\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } } #endif if (subset != NULL) { - cuddDeref(subset); - return(subset); + cuddDeref(subset); + return(subset); } else { - return(NULL); + return(NULL); } } /* end of cuddSubsetShortPaths */ @@ -465,15 +502,14 @@ cuddSubsetShortPaths( next page when the end of the page is reached and allocates new pages when necessary. ] - SideEffects [Changes the size of pages, page, page index, maximum + SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeNodeDistPages( - ) +ResizeNodeDistPages(void) { int i; NodeDist_t **newNodeDistPages; @@ -482,34 +518,34 @@ ResizeNodeDistPages( nodeDistPage++; /* If the current page index is larger than the number of pages - * allocated, allocate a new page array. Page numbers are incremented by + * allocated, allocate a new page array. Page numbers are incremented by * INITIAL_PAGES */ if (nodeDistPage == maxNodeDistPages) { - newNodeDistPages = ABC_ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES); - if (newNodeDistPages == NULL) { - for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxNodeDistPages; i++) { - newNodeDistPages[i] = nodeDistPages[i]; + newNodeDistPages = ABC_ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES); + if (newNodeDistPages == NULL) { + for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDistPages; i++) { + newNodeDistPages[i] = nodeDistPages[i]; + } + /* Increase total page count */ + maxNodeDistPages += INITIAL_PAGES; + ABC_FREE(nodeDistPages); + nodeDistPages = newNodeDistPages; } - /* Increase total page count */ - maxNodeDistPages += INITIAL_PAGES; - ABC_FREE(nodeDistPages); - nodeDistPages = newNodeDistPages; - } } /* Allocate a new page */ currentNodeDistPage = nodeDistPages[nodeDistPage] = ABC_ALLOC(NodeDist_t, - nodeDistPageSize); + nodeDistPageSize); if (currentNodeDistPage == NULL) { - for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - memOut = 1; - return; + for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + memOut = 1; + return; } /* reset page index */ nodeDistPageIndex = 0; @@ -520,56 +556,55 @@ ResizeNodeDistPages( /**Function******************************************************************** - Synopsis [Resize the number of pages allocated to store nodes in the BFS + Synopsis [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd .] - Description [Resize the number of pages allocated to store nodes in the BFS + Description [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary.] - SideEffects [Changes the size of pages, page, page index, maximum + SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeQueuePages( - ) +ResizeQueuePages(void) { int i; DdNode ***newQueuePages; queuePage++; /* If the current page index is larger than the number of pages - * allocated, allocate a new page array. Page numbers are incremented by + * allocated, allocate a new page array. Page numbers are incremented by * INITIAL_PAGES */ if (queuePage == maxQueuePages) { - newQueuePages = ABC_ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES); - if (newQueuePages == NULL) { - for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - memOut = 1; - return; - } else { - for (i = 0; i < maxQueuePages; i++) { - newQueuePages[i] = queuePages[i]; + newQueuePages = ABC_ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES); + if (newQueuePages == NULL) { + for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxQueuePages; i++) { + newQueuePages[i] = queuePages[i]; + } + /* Increase total page count */ + maxQueuePages += INITIAL_PAGES; + ABC_FREE(queuePages); + queuePages = newQueuePages; } - /* Increase total page count */ - maxQueuePages += INITIAL_PAGES; - ABC_FREE(queuePages); - queuePages = newQueuePages; - } } /* Allocate a new page */ currentQueuePage = queuePages[queuePage] = ABC_ALLOC(DdNode *,queuePageSize); if (currentQueuePage == NULL) { - for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - memOut = 1; - return; + for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + memOut = 1; + return; } /* reset page index */ queuePageIndex = 0; @@ -619,145 +654,145 @@ CreateTopDist( /* set queue index to the next available entry for addition */ /* set queue page to page of addition */ if ((queuePages[parentPage] == childPage) && (parentQueueIndex == - childQueueIndex)) { - fprintf(fp, "Should not happen that they are equal\n"); + childQueueIndex)) { + fprintf(fp, "Should not happen that they are equal\n"); } assert(queuePageIndex == childQueueIndex); assert(currentQueuePage == childPage); #endif /* number children added to queue is initialized , needed for - * numParents in the next call + * numParents in the next call */ childrenCount = 0; /* process all the nodes in this level */ while (numParents) { - numParents--; - if (parentQueueIndex == queuePageSize) { - parentPage++; - parentQueueIndex = 0; - } - /* a parent to process */ - node = *(queuePages[parentPage] + parentQueueIndex); - parentQueueIndex++; - /* get its children */ - N = Cudd_Regular(node); - Nv = Cudd_T(N); - Nnv = Cudd_E(N); - - Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); - Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); - - processingDone = 2; - while (processingDone) { - /* processing the THEN and the ELSE children, the THEN - * child first - */ - if (processingDone == 2) { - child = Nv; - } else { - child = Nnv; + numParents--; + if (parentQueueIndex == queuePageSize) { + parentPage++; + parentQueueIndex = 0; } - - regChild = Cudd_Regular(child); - /* dont process if the child is a constant */ - if (!Cudd_IsConstant(child)) { - /* check is already visited, if not add a new entry in - * the path Table - */ - if (!st_lookup(pathTable, (char *)regChild, (char **)&nodeStat)) { - /* if not in table, has never been visited */ - /* create entry for table */ - if (nodeDistPageIndex == nodeDistPageSize) - ResizeNodeDistPages(); - if (memOut) { - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - return; - } - /* New entry for child in path Table is created here */ - nodeStat = currentNodeDistPage + nodeDistPageIndex; - nodeDistPageIndex++; - - /* Initialize fields of the node data */ - nodeStat->oddTopDist = MAXSHORTINT; - nodeStat->evenTopDist = MAXSHORTINT; - nodeStat->evenBotDist = MAXSHORTINT; - nodeStat->oddBotDist = MAXSHORTINT; - nodeStat->regResult = NULL; - nodeStat->compResult = NULL; - /* update the table entry element, the distance keeps - * track of the parity of the path from the root + /* a parent to process */ + node = *(queuePages[parentPage] + parentQueueIndex); + parentQueueIndex++; + /* get its children */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + processingDone = 2; + while (processingDone) { + /* processing the THEN and the ELSE children, the THEN + * child first */ - if (Cudd_IsComplement(child)) { - nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + if (processingDone == 2) { + child = Nv; } else { - nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + child = Nnv; } - /* insert entry element for child in the table */ - if (st_insert(pathTable, (char *)regChild, - (char *)nodeStat) == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - return; - } - - /* Create list element for this child to process its children. - * If this node has been processed already, then it appears - * in the path table and hence is never added to the list - * again. - */ - - if (queuePageIndex == queuePageSize) ResizeQueuePages(); - if (memOut) { - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - st_free_table(pathTable); - return; - } - *(currentQueuePage + queuePageIndex) = child; - queuePageIndex++; - - childrenCount++; - } else { - /* if not been met in a path with this parity before */ - /* put in list */ - if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == - MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && - (nodeStat->evenTopDist == MAXSHORTINT))) { - - if (queuePageIndex == queuePageSize) ResizeQueuePages(); - if (memOut) { - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - st_free_table(pathTable); - return; - - } - *(currentQueuePage + queuePageIndex) = child; - queuePageIndex++; - - /* update the distance with the appropriate parity */ - if (Cudd_IsComplement(child)) { - nodeStat->oddTopDist = (DdHalfWord) topLen + 1; - } else { - nodeStat->evenTopDist = (DdHalfWord) topLen + 1; - } - childrenCount++; - } - - } /* end of else (not found in st_table) */ - } /*end of if Not constant child */ - processingDone--; - } /*end of while processing Nv, Nnv */ + regChild = Cudd_Regular(child); + /* dont process if the child is a constant */ + if (!Cudd_IsConstant(child)) { + /* check is already visited, if not add a new entry in + * the path Table + */ + if (!st_lookup(pathTable, (const char *)regChild, (char **)&nodeStat)) { + /* if not in table, has never been visited */ + /* create entry for table */ + if (nodeDistPageIndex == nodeDistPageSize) + ResizeNodeDistPages(); + if (memOut) { + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + return; + } + /* New entry for child in path Table is created here */ + nodeStat = currentNodeDistPage + nodeDistPageIndex; + nodeDistPageIndex++; + + /* Initialize fields of the node data */ + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + /* update the table entry element, the distance keeps + * track of the parity of the path from the root + */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + + /* insert entry element for child in the table */ + if (st_insert(pathTable, (char *)regChild, + (char *)nodeStat) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + return; + } + + /* Create list element for this child to process its children. + * If this node has been processed already, then it appears + * in the path table and hence is never added to the list + * again. + */ + + if (queuePageIndex == queuePageSize) ResizeQueuePages(); + if (memOut) { + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + st_free_table(pathTable); + return; + } + *(currentQueuePage + queuePageIndex) = child; + queuePageIndex++; + + childrenCount++; + } else { + /* if not been met in a path with this parity before */ + /* put in list */ + if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == + MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && + (nodeStat->evenTopDist == MAXSHORTINT))) { + + if (queuePageIndex == queuePageSize) ResizeQueuePages(); + if (memOut) { + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + st_free_table(pathTable); + return; + + } + *(currentQueuePage + queuePageIndex) = child; + queuePageIndex++; + + /* update the distance with the appropriate parity */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + childrenCount++; + } + + } /* end of else (not found in st_table) */ + } /*end of if Not constant child */ + processingDone--; + } /*end of while processing Nv, Nnv */ } /*end of while numParents */ #ifdef DD_DEBUG @@ -766,11 +801,11 @@ CreateTopDist( #endif if (childrenCount != 0) { - topLen++; - childPage = currentQueuePage; - childQueueIndex = queuePageIndex; - CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen, - childPage, childQueueIndex, childrenCount, fp); + topLen++; + childPage = currentQueuePage; + childQueueIndex = queuePageIndex; + CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen, + childPage, childQueueIndex, childrenCount, fp); } return; @@ -813,29 +848,29 @@ CreateBotDist( int processingDone; if (Cudd_IsConstant(node)) - return(1); + return(1); N = Cudd_Regular(node); /* each node has one table entry */ /* update as you go down the min dist of each node from the root in each (odd and even) parity */ - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - fprintf(fp, "Something wrong, the entry doesn't exist\n"); - return(0); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + fprintf(fp, "Something wrong, the entry doesn't exist\n"); + return(0); } /* compute length of odd parity distances */ if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); else - oddLen = MAXSHORTINT; + oddLen = MAXSHORTINT; /* compute length of even parity distances */ if (!((nodeStat->evenTopDist == MAXSHORTINT) || - (nodeStat->evenBotDist == MAXSHORTINT))) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + (nodeStat->evenBotDist == MAXSHORTINT))) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); else - evenLen = MAXSHORTINT; + evenLen = MAXSHORTINT; /* assign pathlength to minimum of the two */ pathLength = (oddLen <= evenLen) ? oddLen : evenLen; @@ -846,116 +881,115 @@ CreateBotDist( /* process each child */ processingDone = 0; while (processingDone != 2) { - if (!processingDone) { - child = Nv; - } else { - child = Nnv; - } - - realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); - regChild = Cudd_Regular(child); - if (Cudd_IsConstant(realChild)) { - /* Found a minterm; count parity and shortest distance - ** from the constant. - */ - if (Cudd_IsComplement(child)) - nodeStat->oddBotDist = 1; - else - nodeStat->evenBotDist = 1; - } else { - /* If node not in table, recur. */ - if (!st_lookup(pathTable, (char *) regChild, - (char **)&nodeStatChild)) { - fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); - return(0); + if (!processingDone) { + child = Nv; + } else { + child = Nnv; } - if (nodeStatChild->oddBotDist == MAXSHORTINT) { - if (nodeStatChild->evenBotDist == MAXSHORTINT) { - if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) - return(0); + realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); + regChild = Cudd_Regular(child); + if (Cudd_IsConstant(realChild)) { + /* Found a minterm; count parity and shortest distance + ** from the constant. + */ + if (Cudd_IsComplement(child)) + nodeStat->oddBotDist = 1; + else + nodeStat->evenBotDist = 1; } else { - fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); - return(0); - } - } + /* If node not in table, recur. */ + if (!st_lookup(pathTable, (const char *)regChild, (char **)&nodeStatChild)) { + fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); + return(0); + } + + if (nodeStatChild->oddBotDist == MAXSHORTINT) { + if (nodeStatChild->evenBotDist == MAXSHORTINT) { + if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) + return(0); + } else { + fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); + return(0); + } + } - /* Update shortest distance from the constant depending on - ** parity. */ - - if (Cudd_IsComplement(child)) { - /* If parity on the edge then add 1 to even distance - ** of child to get odd parity distance and add 1 to - ** odd distance of child to get even parity - ** distance. Change distance of current node only if - ** the calculated distance is less than existing - ** distance. */ - if (nodeStatChild->oddBotDist != MAXSHORTINT) - botDist = nodeStatChild->oddBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->evenBotDist > botDist ) - nodeStat->evenBotDist = botDist; - - if (nodeStatChild->evenBotDist != MAXSHORTINT) - botDist = nodeStatChild->evenBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->oddBotDist > botDist) - nodeStat->oddBotDist = botDist; + /* Update shortest distance from the constant depending on + ** parity. */ - } else { - /* If parity on the edge then add 1 to even distance - ** of child to get even parity distance and add 1 to - ** odd distance of child to get odd parity distance. - ** Change distance of current node only if the - ** calculated distance is lesser than existing - ** distance. */ - if (nodeStatChild->evenBotDist != MAXSHORTINT) - botDist = nodeStatChild->evenBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->evenBotDist > botDist) - nodeStat->evenBotDist = botDist; - - if (nodeStatChild->oddBotDist != MAXSHORTINT) - botDist = nodeStatChild->oddBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->oddBotDist > botDist) - nodeStat->oddBotDist = botDist; - } - } /* end of else (if not constant child ) */ - processingDone++; + if (Cudd_IsComplement(child)) { + /* If parity on the edge then add 1 to even distance + ** of child to get odd parity distance and add 1 to + ** odd distance of child to get even parity + ** distance. Change distance of current node only if + ** the calculated distance is less than existing + ** distance. */ + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist ) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + + } else { + /* If parity on the edge then add 1 to even distance + ** of child to get even parity distance and add 1 to + ** odd distance of child to get odd parity distance. + ** Change distance of current node only if the + ** calculated distance is lesser than existing + ** distance. */ + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + } + } /* end of else (if not constant child ) */ + processingDone++; } /* end of while processing Nv, Nnv */ /* Compute shortest path length on the fly. */ if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); else - oddLen = MAXSHORTINT; + oddLen = MAXSHORTINT; if ((nodeStat->evenTopDist != MAXSHORTINT) && - (nodeStat->evenBotDist != MAXSHORTINT)) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); else - evenLen = MAXSHORTINT; + evenLen = MAXSHORTINT; /* Update path length array that has number of nodes of a particular ** path length. */ if (oddLen < pathLength ) { - if (pathLength != MAXSHORTINT) - pathLengthArray[pathLength]--; - if (oddLen != MAXSHORTINT) - pathLengthArray[oddLen]++; - pathLength = oddLen; + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (oddLen != MAXSHORTINT) + pathLengthArray[oddLen]++; + pathLength = oddLen; } if (evenLen < pathLength ) { - if (pathLength != MAXSHORTINT) - pathLengthArray[pathLength]--; - if (evenLen != MAXSHORTINT) - pathLengthArray[evenLen]++; + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (evenLen != MAXSHORTINT) + pathLengthArray[evenLen]++; } return(1); @@ -999,21 +1033,21 @@ CreatePathTable( int childQueueIndex, parentQueueIndex; /* Creating path Table for storing data about nodes */ - pathTable = st_init_table(st_ptrcmp, st_ptrhash);; + pathTable = st_init_table(st_ptrcmp,st_ptrhash); /* initializing pages for info about each node */ maxNodeDistPages = INITIAL_PAGES; nodeDistPages = ABC_ALLOC(NodeDist_t *, maxNodeDistPages); if (nodeDistPages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } nodeDistPage = 0; currentNodeDistPage = nodeDistPages[nodeDistPage] = - ABC_ALLOC(NodeDist_t, nodeDistPageSize); + ABC_ALLOC(NodeDist_t, nodeDistPageSize); if (currentNodeDistPage == NULL) { - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - goto OUT_OF_MEM; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + goto OUT_OF_MEM; } nodeDistPageIndex = 0; @@ -1021,14 +1055,14 @@ CreatePathTable( maxQueuePages = INITIAL_PAGES; queuePages = ABC_ALLOC(DdNode **, maxQueuePages); if (queuePages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } queuePage = 0; currentQueuePage = queuePages[queuePage] = ABC_ALLOC(DdNode *, queuePageSize); if (currentQueuePage == NULL) { - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - goto OUT_OF_MEM; + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + goto OUT_OF_MEM; } queuePageIndex = 0; @@ -1045,12 +1079,12 @@ CreatePathTable( if (nodeDistPageIndex == nodeDistPageSize) ResizeNodeDistPages(); if (memOut) { - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - goto OUT_OF_MEM; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; } nodeStat = currentNodeDistPage + nodeDistPageIndex; @@ -1065,22 +1099,22 @@ CreatePathTable( insertValue = st_insert(pathTable, (char *)N, (char *)nodeStat); if (insertValue == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - goto OUT_OF_MEM; + memOut = 1; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; } else if (insertValue == 1) { - fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); - return(NULL); + fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); + return(NULL); } if (Cudd_IsComplement(node)) { - nodeStat->oddTopDist = 0; + nodeStat->oddTopDist = 0; } else { - nodeStat->evenTopDist = 0; + nodeStat->evenTopDist = 0; } numParents = 1; /* call the function that counts the distance of each node from the @@ -1090,10 +1124,10 @@ CreatePathTable( numCalls = 0; #endif CreateTopDist(pathTable, parentPage, parentQueueIndex, (int) topLen, - childPage, childQueueIndex, numParents, fp); + childPage, childQueueIndex, numParents, fp); if (memOut) { - fprintf(fp, "Out of Memory and cant count path lengths\n"); - goto OUT_OF_MEM; + fprintf(fp, "Out of Memory and cant count path lengths\n"); + goto OUT_OF_MEM; } #ifdef DD_DEBUG @@ -1151,24 +1185,24 @@ AssessPathLength( * below zero */ while ((i < (unsigned) numVars+1) && (temp > 0)) { - if (pathLengthArray[i] > 0) { - maxpath = i; - temp = temp - pathLengthArray[i]; - } - i++; + if (pathLengthArray[i] > 0) { + maxpath = i; + temp = temp - pathLengthArray[i]; + } + i++; } /* if all nodes of max path are needed */ if (temp >= 0) { - maxpath++; /* now maxpath becomes the next maxppath or max number - of variables */ - *excess = 0; + maxpath++; /* now maxpath becomes the next maxppath or max number + of variables */ + *excess = 0; } else { /* normal case when subset required is less than size of - original BDD */ - *excess = temp + pathLengthArray[maxpath]; + original BDD */ + *excess = temp + pathLengthArray[maxpath]; } if (maxpath == 0) { - fprintf(fp, "Path Length array seems to be all zeroes, check\n"); + fprintf(fp, "Path Length array seems to be all zeroes, check\n"); } return(maxpath); @@ -1227,14 +1261,12 @@ BuildSubsetBdd( { DdNode *N, *Nv, *Nnv; DdNode *ThenBranch, *ElseBranch, *childBranch; - DdNode *child, *regChild; - DdNode *regNnv = NULL, *regNv = NULL; // Suppress "might be used uninitialized" + DdNode *child, *regChild, *regNnv, *regNv; NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv; DdNode *neW, *topv, *regNew; char *entry; unsigned int topid; - unsigned int childPathLength, oddLen, evenLen; - unsigned int NnvPathLength = -1, NvPathLength = -1; // Suppress "might be used uninitialized" + unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength; unsigned int NvBotDist, NnvBotDist; int tiebreakChild; int processingDone, thenDone, elseDone; @@ -1244,14 +1276,14 @@ BuildSubsetBdd( numCalls++; #endif if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); /* Find node in table. */ - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - (void) fprintf(dd->err, "Something wrong, node must be in table \n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + (void) fprintf(dd->err, "Something wrong, node must be in table \n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } /* If the node in the table has been visited, then return the corresponding ** Dd. Since a node can become a subset of itself, its @@ -1263,22 +1295,22 @@ BuildSubsetBdd( /* If this node is reached with an odd parity, get odd parity results. */ if (Cudd_IsComplement(node)) { - if (nodeStat->compResult != NULL) { + if (nodeStat->compResult != NULL) { #ifdef DD_DEBUG - hits++; + hits++; #endif - return(nodeStat->compResult); - } + return(nodeStat->compResult); + } } else { - /* if this node is reached with an even parity, get even parity - * results - */ - if (nodeStat->regResult != NULL) { + /* if this node is reached with an even parity, get even parity + * results + */ + if (nodeStat->regResult != NULL) { #ifdef DD_DEBUG - hits++; + hits++; #endif - return(nodeStat->regResult); - } + return(nodeStat->regResult); + } } @@ -1299,220 +1331,220 @@ BuildSubsetBdd( ElseBranch = NULL; /* if then child constant, branch is the child */ if (Cudd_IsConstant(Nv)) { - /*shortest path found */ - if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { - info->findShortestPath = 0; - } + /*shortest path found */ + if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } - ThenBranch = Nv; - cuddRef(ThenBranch); - if (ThenBranch == NULL) { - return(NULL); - } + ThenBranch = Nv; + cuddRef(ThenBranch); + if (ThenBranch == NULL) { + return(NULL); + } - thenDone++; - processingDone++; - NvBotDist = MAXSHORTINT; + thenDone++; + processingDone++; + NvBotDist = MAXSHORTINT; } else { - /* Derive regular child for table lookup. */ - regNv = Cudd_Regular(Nv); - /* Get node data for shortest path length. */ - if (!st_lookup(pathTable, (char *)regNv, (char **)&nodeStatNv) ) { - (void) fprintf(dd->err, "Something wrong, node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - /* Derive shortest path length for child. */ - if ((nodeStatNv->oddTopDist != MAXSHORTINT) && - (nodeStatNv->oddBotDist != MAXSHORTINT)) { - oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); - } else { - oddLen = MAXSHORTINT; - } + /* Derive regular child for table lookup. */ + regNv = Cudd_Regular(Nv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, (const char *)regNv, (char **)&nodeStatNv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNv->oddTopDist != MAXSHORTINT) && + (nodeStatNv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } - if ((nodeStatNv->evenTopDist != MAXSHORTINT) && - (nodeStatNv->evenBotDist != MAXSHORTINT)) { - evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); - } else { - evenLen = MAXSHORTINT; - } + if ((nodeStatNv->evenTopDist != MAXSHORTINT) && + (nodeStatNv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } - NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; - NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: - nodeStatNv->evenBotDist; + NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: + nodeStatNv->evenBotDist; } /* if else child constant, branch is the child */ if (Cudd_IsConstant(Nnv)) { - /*shortest path found */ - if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { - info->findShortestPath = 0; - } + /*shortest path found */ + if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } - ElseBranch = Nnv; - cuddRef(ElseBranch); - if (ElseBranch == NULL) { - return(NULL); - } + ElseBranch = Nnv; + cuddRef(ElseBranch); + if (ElseBranch == NULL) { + return(NULL); + } - elseDone++; - processingDone++; - NnvBotDist = MAXSHORTINT; - } else { - /* Derive regular child for table lookup. */ - regNnv = Cudd_Regular(Nnv); - /* Get node data for shortest path length. */ - if (!st_lookup(pathTable, (char *)regNnv, (char **)&nodeStatNnv) ) { - (void) fprintf(dd->err, "Something wrong, node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - /* Derive shortest path length for child. */ - if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && - (nodeStatNnv->oddBotDist != MAXSHORTINT)) { - oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + elseDone++; + processingDone++; + NnvBotDist = MAXSHORTINT; } else { - oddLen = MAXSHORTINT; - } + /* Derive regular child for table lookup. */ + regNnv = Cudd_Regular(Nnv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, (const char *)regNnv, (char **)&nodeStatNnv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && + (nodeStatNnv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } - if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && - (nodeStatNnv->evenBotDist != MAXSHORTINT)) { - evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); - } else { - evenLen = MAXSHORTINT; - } + if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && + (nodeStatNnv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } - NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; - NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : - nodeStatNnv->evenBotDist; + NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : + nodeStatNnv->evenBotDist; } tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0; /* while both children not processed */ while (processingDone != 2) { - if (!processingDone) { - /* if no child processed */ - /* pick the child with shortest path length and record which one - * picked - */ - if ((NvPathLength < NnvPathLength) || - ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { - child = Nv; - regChild = regNv; - thenDone = 1; - childPathLength = NvPathLength; - } else { - child = Nnv; - regChild = regNnv; - elseDone = 1; - childPathLength = NnvPathLength; - } /* then path length less than else path length */ - } else { - /* if one child processed, process the other */ - if (thenDone) { - child = Nnv; - regChild = regNnv; - elseDone = 1; - childPathLength = NnvPathLength; + if (!processingDone) { + /* if no child processed */ + /* pick the child with shortest path length and record which one + * picked + */ + if ((NvPathLength < NnvPathLength) || + ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } else { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } /* then path length less than else path length */ } else { - child = Nv; - regChild = regNv; - thenDone = 1; - childPathLength = NvPathLength; - } /* end of else pick the Then child if ELSE child processed */ - } /* end of else one child has been processed */ - - /* ignore (replace with constant 0) all nodes which lie on paths larger - * than the maximum length of the path required - */ - if (childPathLength > info->maxpath) { - /* record nodes visited */ - childBranch = zero; - } else { - if (childPathLength < info->maxpath) { - if (info->findShortestPath) { - info->findShortestPath = 0; - } - childBranch = BuildSubsetBdd(dd, pathTable, child, info, - subsetNodeTable); - - } else { /* Case: path length of node = maxpath */ - /* If the node labeled with maxpath is found in the - ** maxpathTable, use it to build the subset BDD. */ - if (st_lookup(info->maxpathTable, (char *)regChild, - (char **)&entry)) { - /* When a node that is already been chosen is hit, - ** the quest for a complete path is over. */ - if (info->findShortestPath) { - info->findShortestPath = 0; - } - childBranch = BuildSubsetBdd(dd, pathTable, child, info, - subsetNodeTable); + /* if one child processed, process the other */ + if (thenDone) { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } else { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } /* end of else pick the Then child if ELSE child processed */ + } /* end of else one child has been processed */ + + /* ignore (replace with constant 0) all nodes which lie on paths larger + * than the maximum length of the path required + */ + if (childPathLength > info->maxpath) { + /* record nodes visited */ + childBranch = zero; } else { - /* If node is not found in the maxpathTable and - ** the threshold has been reached, then if the - ** path needs to be completed, continue. Else - ** replace the node with a zero. */ - if (info->thresholdReached <= 0) { - if (info->findShortestPath) { - if (st_insert(info->maxpathTable, (char *)regChild, - (char *)NIL(char)) == ST_OUT_OF_MEM) { - memOut = 1; - (void) fprintf(dd->err, "OUT of memory\n"); - info->thresholdReached = 0; - childBranch = zero; - } else { - info->thresholdReached--; - childBranch = BuildSubsetBdd(dd, pathTable, - child, info,subsetNodeTable); + if (childPathLength < info->maxpath) { + if (info->findShortestPath) { + info->findShortestPath = 0; } - } else { /* not find shortest path, we dont need this - node */ - childBranch = zero; + childBranch = BuildSubsetBdd(dd, pathTable, child, info, + subsetNodeTable); + + } else { /* Case: path length of node = maxpath */ + /* If the node labeled with maxpath is found in the + ** maxpathTable, use it to build the subset BDD. */ + if (st_lookup(info->maxpathTable, (char *)regChild, + (char **)&entry)) { + /* When a node that is already been chosen is hit, + ** the quest for a complete path is over. */ + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, pathTable, child, info, + subsetNodeTable); + } else { + /* If node is not found in the maxpathTable and + ** the threshold has been reached, then if the + ** path needs to be completed, continue. Else + ** replace the node with a zero. */ + if (info->thresholdReached <= 0) { + if (info->findShortestPath) { + if (st_insert(info->maxpathTable, (char *)regChild, + (char *)NIL(char)) == ST_OUT_OF_MEM) { + memOut = 1; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + childBranch = BuildSubsetBdd(dd, pathTable, + child, info,subsetNodeTable); + } + } else { /* not find shortest path, we dont need this + node */ + childBranch = zero; + } + } else { /* Threshold hasn't been reached, + ** need the node. */ + if (st_insert(info->maxpathTable, (char *)regChild, + (char *)NIL(char)) == ST_OUT_OF_MEM) { + memOut = 1; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + if (info->thresholdReached <= 0) { + info->findShortestPath = 1; + } + childBranch = BuildSubsetBdd(dd, pathTable, + child, info, subsetNodeTable); + + } /* end of st_insert successful */ + } /* end of threshold hasnt been reached yet */ + } /* end of else node not found in maxpath table */ + } /* end of if (path length of node = maxpath) */ + } /* end if !(childPathLength > maxpath) */ + if (childBranch == NULL) { + /* deref other stuff incase reordering has taken place */ + if (ThenBranch != NULL) { + Cudd_RecursiveDeref(dd, ThenBranch); + ThenBranch = NULL; } - } else { /* Threshold hasn't been reached, - ** need the node. */ - if (st_insert(info->maxpathTable, (char *)regChild, - (char *)NIL(char)) == ST_OUT_OF_MEM) { - memOut = 1; - (void) fprintf(dd->err, "OUT of memory\n"); - info->thresholdReached = 0; - childBranch = zero; - } else { - info->thresholdReached--; - if (info->thresholdReached <= 0) { - info->findShortestPath = 1; - } - childBranch = BuildSubsetBdd(dd, pathTable, - child, info, subsetNodeTable); - - } /* end of st_insert successful */ - } /* end of threshold hasnt been reached yet */ - } /* end of else node not found in maxpath table */ - } /* end of if (path length of node = maxpath) */ - } /* end if !(childPathLength > maxpath) */ - if (childBranch == NULL) { - /* deref other stuff incase reordering has taken place */ - if (ThenBranch != NULL) { - Cudd_RecursiveDeref(dd, ThenBranch); - ThenBranch = NULL; - } - if (ElseBranch != NULL) { - Cudd_RecursiveDeref(dd, ElseBranch); - ElseBranch = NULL; + if (ElseBranch != NULL) { + Cudd_RecursiveDeref(dd, ElseBranch); + ElseBranch = NULL; + } + return(NULL); } - return(NULL); - } - cuddRef(childBranch); + cuddRef(childBranch); - if (child == Nv) { - ThenBranch = childBranch; - } else { - ElseBranch = childBranch; - } - processingDone++; + if (child == Nv) { + ThenBranch = childBranch; + } else { + ElseBranch = childBranch; + } + processingDone++; - } /*end of while processing Nv, Nnv */ + } /*end of while processing Nv, Nnv */ info->findShortestPath = 0; topid = Cudd_NodeReadIndex(N); @@ -1520,7 +1552,7 @@ BuildSubsetBdd( cuddRef(topv); neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); if (neW != NULL) { - cuddRef(neW); + cuddRef(neW); } Cudd_RecursiveDeref(dd, topv); Cudd_RecursiveDeref(dd, ThenBranch); @@ -1529,76 +1561,76 @@ BuildSubsetBdd( /* Hard Limit of threshold has been imposed */ if (subsetNodeTable != NIL(st_table)) { - /* check if a new node is created */ - regNew = Cudd_Regular(neW); - /* subset node table keeps all new nodes that have been created to keep - * a running count of how many nodes have been built in the subset. - */ - if (!st_lookup(subsetNodeTable, (char *)regNew, (char **)&entry)) { - if (!Cudd_IsConstant(regNew)) { - if (st_insert(subsetNodeTable, (char *)regNew, - (char *)NULL) == ST_OUT_OF_MEM) { - (void) fprintf(dd->err, "Out of memory\n"); - return (NULL); - } - if (st_count(subsetNodeTable) > info->threshold) { - info->thresholdReached = 0; - } + /* check if a new node is created */ + regNew = Cudd_Regular(neW); + /* subset node table keeps all new nodes that have been created to keep + * a running count of how many nodes have been built in the subset. + */ + if (!st_lookup(subsetNodeTable, (char *)regNew, (char **)&entry)) { + if (!Cudd_IsConstant(regNew)) { + if (st_insert(subsetNodeTable, (char *)regNew, + (char *)NULL) == ST_OUT_OF_MEM) { + (void) fprintf(dd->err, "Out of memory\n"); + return (NULL); + } + if (st_count(subsetNodeTable) > info->threshold) { + info->thresholdReached = 0; + } + } } } - } if (neW == NULL) { - return(NULL); + return(NULL); } else { - /*store computed result in regular form*/ - if (Cudd_IsComplement(node)) { - nodeStat->compResult = neW; - cuddRef(nodeStat->compResult); - /* if the new node is the same as the corresponding node in the - * original bdd then its complement need not be computed as it - * cannot be larger than the node itself - */ - if (neW == node) { + /*store computed result in regular form*/ + if (Cudd_IsComplement(node)) { + nodeStat->compResult = neW; + cuddRef(nodeStat->compResult); + /* if the new node is the same as the corresponding node in the + * original bdd then its complement need not be computed as it + * cannot be larger than the node itself + */ + if (neW == node) { #ifdef DD_DEBUG - thishit++; + thishit++; #endif - /* if a result for the node has already been computed, then - * it can only be smaller than teh node itself. hence store - * the node result in order not to break recombination - */ - if (nodeStat->regResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->regResult); - } - nodeStat->regResult = Cudd_Not(neW); - cuddRef(nodeStat->regResult); - } + /* if a result for the node has already been computed, then + * it can only be smaller than teh node itself. hence store + * the node result in order not to break recombination + */ + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + nodeStat->regResult = Cudd_Not(neW); + cuddRef(nodeStat->regResult); + } - } else { - nodeStat->regResult = neW; - cuddRef(nodeStat->regResult); - if (neW == node) { + } else { + nodeStat->regResult = neW; + cuddRef(nodeStat->regResult); + if (neW == node) { #ifdef DD_DEBUG - thishit++; + thishit++; #endif - if (nodeStat->compResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->compResult); - } - nodeStat->compResult = Cudd_Not(neW); - cuddRef(nodeStat->compResult); + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + nodeStat->compResult = Cudd_Not(neW); + cuddRef(nodeStat->compResult); + } } - } - cuddDeref(neW); - return(neW); + cuddDeref(neW); + return(neW); } /* end of else i.e. Subset != NULL */ } /* end of BuildSubsetBdd */ /**Function******************************************************************** - Synopsis [Procedure to free the result dds stored in the NodeDist pages.] + Synopsis [Procedure to free te result dds stored in the NodeDist pages.] Description [None] @@ -1619,13 +1651,15 @@ stPathTableDdFree( nodeStat = (NodeDist_t *)value; dd = (DdManager *)arg; if (nodeStat->regResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->regResult); + Cudd_RecursiveDeref(dd, nodeStat->regResult); } if (nodeStat->compResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->compResult); + Cudd_RecursiveDeref(dd, nodeStat->compResult); } return(ST_CONTINUE); } /* end of stPathTableFree */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSymmetry.c b/src/bdd/cudd/cuddSymmetry.c index 535ba978..a7ef7845 100644 --- a/src/bdd/cudd/cuddSymmetry.c +++ b/src/bdd/cudd/cuddSymmetry.c @@ -7,34 +7,61 @@ Synopsis [Functions for symmetry-based variable reordering.] Description [External procedures included in this file: - <ul> - <li> Cudd_SymmProfile() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSymmCheck() - <li> cuddSymmSifting() - <li> cuddSymmSiftingConv() - </ul> - Static procedures included in this module: - <ul> - <li> ddSymmUniqueCompare() - <li> ddSymmSiftingAux() - <li> ddSymmSiftingConvAux() - <li> ddSymmSiftingUp() - <li> ddSymmSiftingDown() - <li> ddSymmGroupMove() - <li> ddSymmGroupMoveBackward() - <li> ddSymmSiftingBackward() - <li> ddSymmSummary() - </ul>] + <ul> + <li> Cudd_SymmProfile() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSymmCheck() + <li> cuddSymmSifting() + <li> cuddSymmSiftingConv() + </ul> + Static procedures included in this module: + <ul> + <li> ddSymmUniqueCompare() + <li> ddSymmSiftingAux() + <li> ddSymmSiftingConvAux() + <li> ddSymmSiftingUp() + <li> ddSymmSiftingDown() + <li> ddSymmGroupMove() + <li> ddSymmGroupMoveBackward() + <li> ddSymmSiftingBackward() + <li> ddSymmSummary() + </ul>] Author [Shipra Panda, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -44,6 +71,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -63,14 +91,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.26 2009/02/19 16:23:54 fabio Exp $"; #endif -static int *entry; +static int *entry; -extern int ddTotalNumberSwapping; +extern int ddTotalNumberSwapping; #ifdef DD_STATS -extern int ddTotalNISwaps; +extern int ddTotalNISwaps; #endif /*---------------------------------------------------------------------------*/ @@ -83,15 +111,15 @@ extern int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddSymmUniqueCompare ARGS((int *ptrX, int *ptrY)); -static int ddSymmSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static int ddSymmSiftingConvAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddSymmSiftingUp ARGS((DdManager *table, int y, int xLow)); -static Move * ddSymmSiftingDown ARGS((DdManager *table, int x, int xHigh)); -static int ddSymmGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int ddSymmGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int ddSymmSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void ddSymmSummary ARGS((DdManager *table, int lower, int upper, int *symvars, int *symgroups)); +static int ddSymmUniqueCompare (int *ptrX, int *ptrY); +static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSymmSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSymmSiftingDown (DdManager *table, int x, int xHigh); +static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddSymmGroupMoveBackward (DdManager *table, int x, int y); +static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); /**AutomaticEnd***************************************************************/ @@ -121,22 +149,22 @@ Cudd_SymmProfile( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtables[i].next != (unsigned) i) { - x = i; - (void) fprintf(table->out,"Group:"); - do { - (void) fprintf(table->out," %d",table->invperm[x]); - TotalSymm++; - gbot = x; - x = table->subtables[x].next; - } while (x != i); - TotalSymmGroups++; + if (table->subtables[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d",table->invperm[x]); + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); + TotalSymmGroups++; #ifdef DD_DEBUG - assert(table->subtables[gbot].next == (unsigned) i); + assert(table->subtables[gbot].next == (unsigned) i); #endif - i = gbot; - (void) fprintf(table->out,"\n"); - } + i = gbot; + (void) fprintf(table->out,"\n"); + } } (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); @@ -167,11 +195,11 @@ cuddSymmCheck( int y) { DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; - int comple; /* f0 is complemented */ - int xsymmy; /* x and y may be positively symmetric */ - int xsymmyp; /* x and y may be negatively symmetric */ - int arccount; /* number of arcs from layer x to layer y */ - int TotalRefCount; /* total reference count of layer y minus 1 */ + int comple; /* f0 is complemented */ + int xsymmy; /* x and y may be positively symmetric */ + int xsymmyp; /* x and y may be negatively symmetric */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ int yindex; int i; DdNodePtr *list; @@ -188,12 +216,12 @@ cuddSymmCheck( ** function, it has one arc coming from a layer different from x. */ if (table->subtables[x].keys == 1) { - return(0); + return(0); } yindex = table->invperm[y]; if (table->subtables[y].keys == 1) { - if (table->vars[yindex]->ref == 1) - return(0); + if (table->vars[yindex]->ref == 1) + return(0); } xsymmy = xsymmyp = 1; @@ -201,45 +229,45 @@ cuddSymmCheck( slots = table->subtables[x].slots; list = table->subtables[x].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - f0 = Cudd_Regular(cuddE(f)); - comple = Cudd_IsComplement(cuddE(f)); - if ((int) f1->index == yindex) { - arccount++; - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - if ((int) f0->index != yindex) { - /* If f is an isolated projection function it is - ** allowed to bypass layer y. - */ - if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) - return(0); /* f bypasses layer y */ - } - f11 = f10 = f1; - } - if ((int) f0->index == yindex) { - arccount++; - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - - if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { - xsymmy &= f01 == f10; - xsymmyp &= f11 == f00; - if ((xsymmy == 0) && (xsymmyp == 0)) - return(0); - } - - f = f->next; - } /* while */ + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + if ((int) f1->index == yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) + return(0); /* f bypasses layer y */ + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { + xsymmy &= f01 == f10; + xsymmyp &= f11 == f00; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + } + + f = f->next; + } /* while */ } /* for */ /* Calculate the total reference counts of y */ @@ -247,19 +275,19 @@ cuddSymmCheck( slots = table->subtables[y].slots; list = table->subtables[y].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - TotalRefCount += f->ref; - f = f->next; - } + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (arccount == TotalRefCount) { - xindex = table->invperm[x]; - (void) fprintf(table->out, - "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + xindex = table->invperm[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif @@ -294,18 +322,17 @@ int cuddSymmSifting( DdManager * table, int lower, - int upper, - int TimeStop) + int upper) { - int i; - int *var; - int size; - int x; - int result; - int symvars; - int symgroups; + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->size; @@ -314,53 +341,54 @@ cuddSymmSifting( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); /* Initialize the symmetry of each subtable to itself. */ for (i = lower; i <= upper; i++) { - table->subtables[i].next = i; + table->subtables[i].next = i; } for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - if ( TimeStop && TimeStop < clock() ) - break; - x = table->perm[var[i]]; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + // enable timeout during variable reodering - alanmi 2/13/11 + if ( table->TimeStop && table->TimeStop < clock() ) + break; + x = table->perm[var[i]]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - if (x < lower || x > upper) continue; - if (table->subtables[x].next == (unsigned) x) { - result = ddSymmSiftingAux(table,x,lower,upper); - if (!result) goto ddSymmSiftingOutOfMem; + if (x < lower || x > upper) continue; + if (table->subtables[x].next == (unsigned) x) { + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } ABC_FREE(var); @@ -370,9 +398,9 @@ cuddSymmSifting( #ifdef DD_STATS (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", - symgroups); + symgroups); #endif return(1+symvars); @@ -416,17 +444,17 @@ cuddSymmSiftingConv( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; - int symvars; - int symgroups; - int classes; - int initialSize; + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; + int classes; + int initialSize; #ifdef DD_STATS - int previousSize; + int previousSize; #endif initialSize = table->keys - table->isolated; @@ -437,111 +465,111 @@ cuddSymmSiftingConv( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); /* Initialize the symmetry of each subtable to itself ** for first pass of converging symmetric sifting. */ for (i = lower; i <= upper; i++) { - table->subtables[i].next = i; + table->subtables[i].next = i; } for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - if (x < lower || x > upper) continue; - /* Only sift if not in symmetry group already. */ - if (table->subtables[x].next == (unsigned) x) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtables[x].next == (unsigned) x) { #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSymmSiftingAux(table,x,lower,upper); - if (!result) goto ddSymmSiftingConvOutOfMem; + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } /* Sifting now until convergence. */ while ((unsigned) initialSize > table->keys - table->isolated) { - initialSize = table->keys - table->isolated; + initialSize = table->keys - table->isolated; #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif /* Here we consider only one representative for each symmetry class. */ - for (x = lower, classes = 0; x <= upper; x++, classes++) { - while ((unsigned) x < table->subtables[x].next) { - x = table->subtables[x].next; + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtables[x].next) { + x = table->subtables[x].next; + } + /* Here x is the largest index in a group. + ** Groups consist of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invperm[x]; + entry[i] = table->subtables[x].keys; + var[classes] = i; } - /* Here x is the largest index in a group. - ** Groups consist of adjacent variables. - ** Hence, the next increment of x will move it to a new group. - */ - i = table->invperm[x]; - entry[i] = table->subtables[x].keys; - var[classes] = i; - } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); - /* Now sift. */ - for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - if ((unsigned) x >= table->subtables[x].next) { + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + if ((unsigned) x >= table->subtables[x].next) { #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSymmSiftingConvAux(table,x,lower,upper); - if (!result ) goto ddSymmSiftingConvOutOfMem; + result = ddSymmSiftingConvAux(table,x,lower,upper); + if (!result ) goto ddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } - } /* for */ + } + } /* for */ } ddSymmSummary(table, lower, upper, &symvars, &symgroups); #ifdef DD_STATS (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", - symgroups); + symgroups); #endif ABC_FREE(var); @@ -583,7 +611,7 @@ ddSymmUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -612,12 +640,12 @@ ddSymmSiftingAux( int xHigh) { Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; int i; - int topbot; /* index to either top or bottom of symmetry group */ + int topbot; /* index to either top or bottom of symmetry group */ int initGroupSize, finalGroupSize; @@ -632,259 +660,259 @@ ddSymmSiftingAux( moveUp = NULL; if ((x - xLow) > (xHigh - x)) { - /* Will go down first, unless x == xHigh: - ** Look for consecutive symmetries above x. - */ - for (i = x; i > xLow; i--) { - if (!cuddSymmCheck(table,i-1,i)) - break; - topbot = table->subtables[i-1].next; /* find top of i-1's group */ - table->subtables[i-1].next = i; - table->subtables[x].next = topbot; /* x is bottom of group so its */ - /* next is top of i-1's group */ - i = topbot + 1; /* add 1 for i--; new i is top of symm group */ - } + /* Will go down first, unless x == xHigh: + ** Look for consecutive symmetries above x. + */ + for (i = x; i > xLow; i--) { + if (!cuddSymmCheck(table,i-1,i)) + break; + topbot = table->subtables[i-1].next; /* find top of i-1's group */ + table->subtables[i-1].next = i; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of i-1's group */ + i = topbot + 1; /* add 1 for i--; new i is top of symm group */ + } } else { - /* Will go up first unless x == xlow: - ** Look for consecutive symmetries below x. - */ - for (i = x; i < xHigh; i++) { - if (!cuddSymmCheck(table,i,i+1)) - break; - /* find bottom of i+1's symm group */ - topbot = i + 1; - while ((unsigned) topbot < table->subtables[topbot].next) { - topbot = table->subtables[topbot].next; + /* Will go up first unless x == xlow: + ** Look for consecutive symmetries below x. + */ + for (i = x; i < xHigh; i++) { + if (!cuddSymmCheck(table,i,i+1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[i].next; + table->subtables[i].next = i + 1; + i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ } - table->subtables[topbot].next = table->subtables[i].next; - table->subtables[i].next = i + 1; - i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ - } } /* Now x may be in the middle of a symmetry group. ** Find bottom of x's symm group. */ while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; + x = table->subtables[x].next; if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtables[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ - initGroupSize = 1; + initGroupSize = 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* after this point x --> xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveDown == NULL) return(1); + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* after this point x --> xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveDown == NULL) return(1); - x = moveDown->y; - /* Find bottom of x's group */ - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } + x = moveDown->y; + /* Find bottom of x's group */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ - /* Find top of x's symm group */ - i = x; /* bottom */ - x = table->subtables[x].next; /* top */ + /* Find top of x's symm group */ + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ - if (x == xLow) return(1); /* just one big group */ + if (x == xLow) return(1); /* just one big group */ - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* after this point x --> xLow, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp == NULL) return(1); + moveUp = ddSymmSiftingUp(table,x,xLow); + /* after this point x --> xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveUp == NULL) return(1); - x = moveUp->x; - /* Find top of x's group */ - i = table->subtables[x].next; + x = moveUp->x; + /* Find top of x's group */ + i = table->subtables[x].next; #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; /* x is top here */ - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } - } else { - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; /* x is top here */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + x = table->subtables[i].next; } - x = table->subtables[i].next; - } #ifdef DD_DEBUG /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); } - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (!result) goto ddSymmSiftingAuxOutOfMem; } else { /* moving up first: shorter */ /* Find top of x's symmetry group */ - x = table->subtables[x].next; + x = table->subtables[x].next; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xHigh, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = table->subtables[x].next; + } #ifdef DD_DEBUG /* x is bottom of the symmetry group and i is top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - initGroupSize = x - i + 1; - - moveDown = ddSymmSiftingDown(table,x,xHigh); - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + initGroupSize = x - i + 1; - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; } - } else { - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); } - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (!result) goto ddSymmSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSymmSiftingAuxOutOfMem: if (moveDown != MV_OOM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != MV_OOM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -914,10 +942,10 @@ ddSymmSiftingConvAux( int xHigh) { Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; int i; int initGroupSize, finalGroupSize; @@ -929,148 +957,148 @@ ddSymmSiftingConvAux( if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x is bottom of symmetry group */ - assert((unsigned) x >= table->subtables[x].next); + /* x is bottom of symmetry group */ + assert((unsigned) x >= table->subtables[x].next); #endif i = table->subtables[x].next; - initGroupSize = x - i + 1; + initGroupSize = x - i + 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveDown == NULL) return(1); + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveDown == NULL) return(1); - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } #ifdef DD_DEBUG - /* x should be the top of the symmetric group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetric group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = x; /* bottom */ - x = table->subtables[x].next; /* top */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ - if (x == xLow) return(1); + if (x == xLow) return(1); - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xLow, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp == NULL) return(1); + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveUp == NULL) return(1); - x = moveUp->x; - i = table->subtables[x].next; + x = moveUp->x; + i = table->subtables[x].next; #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) - goto ddSymmSiftingConvAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) + goto ddSymmSiftingConvAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; + x = table->subtables[x].next; } - } else { - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); } - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } else { /* moving up first: shorter */ - /* Find top of x's symmetry group */ - x = table->subtables[x].next; + /* Find top of x's symmetry group */ + x = table->subtables[x].next; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xHigh, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG /* x is bottom of the symmetry group and i is top */ assert((unsigned) x >= table->subtables[x].next); @@ -1078,69 +1106,69 @@ ddSymmSiftingConvAux( #endif initGroupSize = x - i + 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; } - } else { - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); } - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSymmSiftingConvAuxOutOfMem: if (moveDown != MV_OOM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != MV_OOM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -1171,8 +1199,8 @@ ddSymmSiftingUp( { Move *moves; Move *move; - int x; - int size; + int x; + int size; int i; int gxtop,gybot; int limitSize; @@ -1180,7 +1208,7 @@ ddSymmSiftingUp( int zindex; int z; int isolated; - int L; /* lower bound on DD size */ + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; #endif @@ -1198,92 +1226,92 @@ ddSymmSiftingUp( limitSize = L = table->keys - table->isolated; gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L -= table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } } x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { #ifdef DD_DEBUG - gybot = y; - while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; - checkL = table->keys - table->isolated; - for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } } - } - assert(L == checkL); + assert(L == checkL); #endif - gxtop = table->subtables[x].next; - if (cuddSymmCheck(table,x,y)) { - /* Symmetry found, attach symm groups */ - table->subtables[x].next = y; - i = table->subtables[y].next; - while (table->subtables[i].next != (unsigned) y) - i = table->subtables[i].next; - table->subtables[i].next = gxtop; - } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { - /* x and y have self symmetry */ - xindex = table->invperm[x]; - size = cuddSwapInPlace(table,x,y); + gxtop = table->subtables[x].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG - assert(table->subtables[x].next == (unsigned) x); - assert(table->subtables[y].next == (unsigned) y); + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); #endif - if (size == 0) goto ddSymmSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSymmSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } else { /* Group move */ - size = ddSymmGroupMove(table,x,y,&moves); - if (size == 0) goto ddSymmSiftingUpOutOfMem; - /* Update the lower bound. */ - z = moves->y; - do { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L += table->subtables[z].keys - isolated; + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + z = moves->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) moves->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; } - z = table->subtables[z].next; - } while (z != (int) moves->y); - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } - y = gxtop; - x = cuddNextLow(table,y); + y = gxtop; + x = cuddNextLow(table,y); } return(moves); ddSymmSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(MV_OOM); @@ -1313,11 +1341,11 @@ ddSymmSiftingDown( { Move *moves; Move *move; - int y; - int size; + int y; + int size; int limitSize; int gxtop,gybot; - int R; /* upper bound on node decrease */ + int R; /* upper bound on node decrease */ int xindex, yindex; int isolated; int z; @@ -1333,98 +1361,98 @@ ddSymmSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - gxtop = table->subtables[x].next; - checkR = 0; - for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; - } - } - assert(R == checkR); -#endif - gybot = table->subtables[y].next; - while (table->subtables[gybot].next != (unsigned) y) - gybot = table->subtables[gybot].next; - if (cuddSymmCheck(table,x,y)) { - /* Symmetry found, attach symm groups */ gxtop = table->subtables[x].next; - table->subtables[x].next = y; - table->subtables[gybot].next = gxtop; - } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { - /* x and y have self symmetry */ - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - size = cuddSwapInPlace(table,x,y); + assert(R == checkR); +#endif + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG - assert(table->subtables[x].next == (unsigned) x); - assert(table->subtables[y].next == (unsigned) y); + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); #endif - if (size == 0) goto ddSymmSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSymmSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } else { /* Group move */ - /* Update upper bound on node decrease: first phase. */ - gxtop = table->subtables[x].next; - z = gxtop + 1; - do { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R -= table->subtables[z].keys - isolated; - } - z++; - } while (z <= gybot); - size = ddSymmGroupMove(table,x,y,&moves); - if (size == 0) goto ddSymmSiftingDownOutOfMem; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - /* Update upper bound on node decrease: second phase. */ - gxtop = table->subtables[gybot].next; - for (z = gxtop + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + if (size == 0) goto ddSymmSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } } - } - x = gybot; - y = cuddNextHigh(table,x); + x = gybot; + y = cuddNextHigh(table,x); } return(moves); ddSymmSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(MV_OOM); @@ -1451,13 +1479,13 @@ ddSymmGroupMove( Move ** moves) { Move *move; - int size = 0; // Suppress "might be used uninitialized" + int size; int i,j; int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx = 0,swapy = 0; // Suppress "might be used uninitialized" + int swapx,swapy; -#if DD_DEBUG - assert(x < y); /* we assume that x < y */ +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ #endif /* Find top, bottom, and size for the two groups. */ xbot = x; @@ -1465,39 +1493,39 @@ ddSymmGroupMove( xsize = xbot - xtop + 1; ybot = y; while ((unsigned) ybot < table->subtables[ybot].next) - ybot = table->subtables[ybot].next; + ybot = table->subtables[ybot].next; ytop = y; ysize = ybot - ytop + 1; /* Sift the variables of the second group up through the first group. */ for (i = 1; i <= ysize; i++) { for (j = 1; j <= xsize; j++) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) return(0); - swapx = x; swapy = y; - y = x; + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + swapx = x; swapy = y; + y = x; + x = y - 1; + } + y = ytop + i; x = y - 1; } - y = ytop + i; - x = y - 1; - } /* fix symmetries */ y = xtop; /* ytop is now where xtop used to be */ for (i = 0; i < ysize-1 ; i++) { - table->subtables[y].next = y + 1; - y = y + 1; + table->subtables[y].next = y + 1; + y = y + 1; } table->subtables[y].next = xtop; /* y is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ x = y + 1; newxtop = x; for (i = 0; i < xsize - 1 ; i++) { - table->subtables[x].next = x + 1; - x = x + 1; + table->subtables[x].next = x + 1; + x = x + 1; } table->subtables[x].next = newxtop; /* x is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ /* Store group move */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) return(0); @@ -1530,11 +1558,11 @@ ddSymmGroupMoveBackward( int x, int y) { - int size = 0; // Suppress "might be used uninitialized" + int size; int i,j; - int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG assert(x < y); /* We assume that x < y */ #endif @@ -1544,38 +1572,38 @@ ddSymmGroupMoveBackward( xsize = xbot - xtop + 1; ybot = y; while ((unsigned) ybot < table->subtables[ybot].next) - ybot = table->subtables[ybot].next; + ybot = table->subtables[ybot].next; ytop = y; ysize = ybot - ytop + 1; /* Sift the variables of the second group up through the first group. */ for (i = 1; i <= ysize; i++) { for (j = 1; j <= xsize; j++) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) return(0); - y = x; - x = cuddNextLow(table,y); - } - y = ytop + i; - x = y - 1; + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = y - 1; } /* Fix symmetries. */ y = xtop; for (i = 0; i < ysize-1 ; i++) { - table->subtables[y].next = y + 1; - y = y + 1; + table->subtables[y].next = y + 1; + y = y + 1; } table->subtables[y].next = xtop; /* y is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ x = y + 1; newxtop = x; for (i = 0; i < xsize-1 ; i++) { - table->subtables[x].next = x + 1; - x = x + 1; + table->subtables[x].next = x + 1; + x = x + 1; } table->subtables[x].next = newxtop; /* x is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ return(size); @@ -1605,23 +1633,23 @@ ddSymmSiftingBackward( int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (move->size == size) return(1); + if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); #ifdef DD_DEBUG - assert(table->subtables[move->x].next == move->x); - assert(table->subtables[move->y].next == move->y); + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); #endif - } else { /* Group move necessary */ - res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); - } - if (!res) return(0); + } else { /* Group move necessary */ + res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); + } + if (!res) return(0); } return(1); @@ -1652,19 +1680,19 @@ ddSymmSummary( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtables[i].next != (unsigned) i) { - TotalSymmGroups++; - x = i; - do { - TotalSymm++; - gbot = x; - x = table->subtables[x].next; - } while (x != i); + if (table->subtables[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); #ifdef DD_DEBUG - assert(table->subtables[gbot].next == (unsigned) i); + assert(table->subtables[gbot].next == (unsigned) i); #endif - i = gbot; - } + i = gbot; + } } *symvars = TotalSymm; *symgroups = TotalSymmGroups; @@ -1672,5 +1700,7 @@ ddSymmSummary( return; } /* end of ddSymmSummary */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddTable.c b/src/bdd/cudd/cuddTable.c index 6ec6f6e7..040e4670 100644 --- a/src/bdd/cudd/cuddTable.c +++ b/src/bdd/cudd/cuddTable.c @@ -7,72 +7,99 @@ Synopsis [Unique table management functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_Prime() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAllocNode() - <li> cuddInitTable() - <li> cuddFreeTable() - <li> cuddGarbageCollect() - <li> cuddGarbageCollectZdd() - <li> cuddZddGetNode() - <li> cuddZddGetNodeIVO() - <li> cuddUniqueInter() - <li> cuddUniqueInterIVO() - <li> cuddUniqueInterZdd() - <li> cuddUniqueConst() - <li> cuddRehash() - <li> cuddShrinkSubtable() - <li> cuddInsertSubtables() - <li> cuddDestroySubtables() - <li> cuddResizeTableZdd() - <li> cuddSlowTableGrowth() - </ul> - Static procedures included in this module: - <ul> - <li> ddRehashZdd() - <li> ddResizeTable() - <li> cuddFindParent() - <li> cuddOrderedInsert() - <li> cuddOrderedThread() - <li> cuddRotateLeft() - <li> cuddRotateRight() - <li> cuddDoRebalance() - <li> cuddCheckCollisionOrdering() - </ul>] + <ul> + <li> Cudd_Prime() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAllocNode() + <li> cuddInitTable() + <li> cuddFreeTable() + <li> cuddGarbageCollect() + <li> cuddZddGetNode() + <li> cuddZddGetNodeIVO() + <li> cuddUniqueInter() + <li> cuddUniqueInterIVO() + <li> cuddUniqueInterZdd() + <li> cuddUniqueConst() + <li> cuddRehash() + <li> cuddShrinkSubtable() + <li> cuddInsertSubtables() + <li> cuddDestroySubtables() + <li> cuddResizeTableZdd() + <li> cuddSlowTableGrowth() + </ul> + Static procedures included in this module: + <ul> + <li> ddRehashZdd() + <li> ddResizeTable() + <li> cuddFindParent() + <li> cuddOrderedInsert() + <li> cuddOrderedThread() + <li> cuddRotateLeft() + <li> cuddRotateRight() + <li> cuddDoRebalance() + <li> cuddCheckCollisionOrdering() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /* Constants for red/black trees. */ #define DD_STACK_SIZE 128 #define DD_RED 0 #define DD_BLACK 1 #define DD_PAGE_SIZE 8192 #define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) -#define DD_INSERT_COMPARE(x,y) \ - (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) +#endif #endif /*---------------------------------------------------------------------------*/ @@ -94,7 +121,7 @@ typedef union hack { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.122 2009/02/19 16:24:28 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -103,7 +130,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /* Macros for red/black trees. */ +#define DD_INSERT_COMPARE(x,y) \ + (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) #define DD_COLOR(p) ((p)->index) #define DD_IS_BLACK(p) ((p)->index == DD_BLACK) #define DD_IS_RED(p) ((p)->index == DD_RED) @@ -111,6 +141,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 #define DD_RIGHT(p) cuddE(p) #define DD_NEXT(p) ((p)->next) #endif +#endif /**AutomaticStart*************************************************************/ @@ -119,20 +150,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ddRehashZdd ARGS((DdManager *unique, int i)); -static int ddResizeTable ARGS((DdManager *unique, int index)); -static int cuddFindParent ARGS((DdManager *table, DdNode *node)); -DD_INLINE static void ddFixLimits ARGS((DdManager *unique)); -static void cuddOrderedInsert ARGS((DdNodePtr *root, DdNodePtr node)); -static DdNode * cuddOrderedThread ARGS((DdNode *root, DdNode *list)); -static void cuddRotateLeft ARGS((DdNodePtr *nodeP)); -static void cuddRotateRight ARGS((DdNodePtr *nodeP)); -static void cuddDoRebalance ARGS((DdNodePtr **stack, int stackN)); -static void ddPatchTree ARGS((DdManager *dd, MtrNode *treenode)); +static void ddRehashZdd (DdManager *unique, int i); +static int ddResizeTable (DdManager *unique, int index); +static int cuddFindParent (DdManager *table, DdNode *node); +DD_INLINE static void ddFixLimits (DdManager *unique); +#ifdef DD_RED_BLACK_FREE_LIST +static void cuddOrderedInsert (DdNodePtr *root, DdNodePtr node); +static DdNode * cuddOrderedThread (DdNode *root, DdNode *list); +static void cuddRotateLeft (DdNodePtr *nodeP); +static void cuddRotateRight (DdNodePtr *nodeP); +static void cuddDoRebalance (DdNodePtr **stack, int stackN); +#endif +static void ddPatchTree (DdManager *dd, MtrNode *treenode); #ifdef DD_DEBUG -static int cuddCheckCollisionOrdering ARGS((DdManager *unique, int i, int j)); +static int cuddCheckCollisionOrdering (DdManager *unique, int i, int j); #endif -static void ddReportRefMess ARGS((DdManager *unique, int i, char *caller)); +static void ddReportRefMess (DdManager *unique, int i, const char *caller); /**AutomaticEnd***************************************************************/ @@ -161,18 +194,18 @@ Cudd_Prime( do { p++; if (p&1) { - pn = 1; - i = 3; - while ((unsigned) (i * i) <= p) { - if (p % i == 0) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { pn = 0; - break; - } - i += 2; } - } else { - pn = 0; - } } while (!pn); return(p); @@ -205,87 +238,89 @@ cuddAllocNode( int i; DdNodePtr *mem; DdNode *list, *node; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); - - if (unique->nextFree == NULL) { /* free list is empty */ - /* Check for exceeded limits. */ - if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > - unique->maxLive) { - unique->errorCode = CUDD_TOO_MANY_NODES; - return(NULL); - } - if (unique->stash == NULL || unique->memused > unique->maxmemhard) { - (void) cuddGarbageCollect(unique,1); - mem = NULL; - } - if (unique->nextFree == NULL) { - if (unique->memused > unique->maxmemhard) { - unique->errorCode = CUDD_MAX_MEM_EXCEEDED; - return(NULL); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->nextFree == NULL) { /* free list is empty */ + /* Check for exceeded limits. */ + if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > + unique->maxLive) { + unique->errorCode = CUDD_TOO_MANY_NODES; + return(NULL); } - /* Try to allocate a new block. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); - MMoutOfMemory = saveHandler; - if (mem == NULL) { - /* No more memory: Try collecting garbage. If this succeeds, - ** we end up with mem still NULL, but unique->nextFree != - ** NULL. */ - if (cuddGarbageCollect(unique,1) == 0) { - /* Last resort: Free the memory stashed away, if there - ** any. If this succeeeds, mem != NULL and - ** unique->nextFree still NULL. */ - if (unique->stash != NULL) { - ABC_FREE(unique->stash); - unique->stash = NULL; - /* Inhibit resizing of tables. */ - cuddSlowTableGrowth(unique); - /* Now try again. */ - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + if (unique->stash == NULL || unique->memused > unique->maxmemhard) { + (void) cuddGarbageCollect(unique,1); + mem = NULL; + } + if (unique->nextFree == NULL) { + if (unique->memused > unique->maxmemhard) { + unique->errorCode = CUDD_MAX_MEM_EXCEEDED; + return(NULL); } + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; if (mem == NULL) { - /* Out of luck. Call the default handler to do - ** whatever it specifies for a failed malloc. - ** If this handler returns, then set error code, - ** print warning, and return. */ - (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); - unique->errorCode = CUDD_MEMORY_OUT; + /* No more memory: Try collecting garbage. If this succeeds, + ** we end up with mem still NULL, but unique->nextFree != + ** NULL. */ + if (cuddGarbageCollect(unique,1) == 0) { + /* Last resort: Free the memory stashed away, if there + ** any. If this succeeeds, mem != NULL and + ** unique->nextFree still NULL. */ + if (unique->stash != NULL) { + ABC_FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + /* Now try again. */ + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. + ** If this handler returns, then set error code, + ** print warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + unique->errorCode = CUDD_MEMORY_OUT; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "cuddAllocNode: out of memory"); - (void) fprintf(unique->err, "Memory in use = %ld\n", - unique->memused); -#endif - return(NULL); + (void) fprintf(unique->err, + "cuddAllocNode: out of memory"); + (void) fprintf(unique->err, "Memory in use = %lu\n", + unique->memused); +#endif + return(NULL); + } + } + } + if (mem != NULL) { /* successful allocation; slice memory */ + ptruint offset; + unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNodePtr) unique->memoryList; + unique->memoryList = mem; + + /* Here we rely on the fact that a DdNode is as large + ** as 4 pointers. */ + offset = (ptruint) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK-1].next = NULL; + + unique->nextFree = &list[0]; } - } - } - if (mem != NULL) { /* successful allocation; slice memory */ - ptruint offset; - unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); - mem[0] = (DdNodePtr) unique->memoryList; - unique->memoryList = mem; - - /* Here we rely on the fact that a DdNode is as large - ** as 4 pointers. */ - offset = (ptruint) mem & (sizeof(DdNode) - 1); - mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); - assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); - list = (DdNode *) mem; - - i = 1; - do { - list[i - 1].next = &list[i]; - } while (++i < DD_MEM_CHUNK); - - list[DD_MEM_CHUNK-1].next = NULL; - - unique->nextFree = &list[0]; } } - } unique->allocated++; node = unique->nextFree; unique->nextFree = node->next; @@ -313,15 +348,15 @@ cuddInitTable( unsigned int numSlots /* Initial size of the BDD subtables */, unsigned int looseUpTo /* Limit for fast table growth */) { - DdManager *unique = ABC_ALLOC(DdManager,1); - int i, j; - DdNodePtr *nodelist; - DdNode *sentinel; + DdManager *unique = ABC_ALLOC(DdManager,1); + int i, j; + DdNodePtr *nodelist; + DdNode *sentinel; unsigned int slots; int shift; if (unique == NULL) { - return(NULL); + return(NULL); } sentinel = &(unique->sentinel); sentinel->ref = 0; @@ -332,7 +367,7 @@ cuddInitTable( unique->epsilon = DD_EPSILON; unique->maxGrowth = DD_MAX_REORDER_GROWTH; unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH; - unique->reordCycle = 0; /* do not use alternate threshold */ + unique->reordCycle = 0; /* do not use alternate threshold */ unique->size = numVars; unique->sizeZ = numVarsZ; unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars); @@ -341,14 +376,14 @@ cuddInitTable( /* Adjust the requested number of slots to a power of 2. */ slots = 8; while (slots < numSlots) { - slots <<= 1; + slots <<= 1; } unique->initSlots = slots; shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots); unique->slots = (numVars + numVarsZ + 1) * slots; unique->keys = 0; - unique->maxLive = ~0; /* very large number */ + unique->maxLive = ~0; /* very large number */ unique->keysZ = 0; unique->dead = 0; unique->deadZ = 0; @@ -360,39 +395,60 @@ cuddInitTable( unique->reclaimed = 0; unique->subtables = ABC_ALLOC(DdSubtable,unique->maxSize); if (unique->subtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique); + return(NULL); } unique->subtableZ = ABC_ALLOC(DdSubtable,unique->maxSizeZ); if (unique->subtableZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique); + return(NULL); } unique->perm = ABC_ALLOC(int,unique->maxSize); if (unique->perm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique); + return(NULL); } unique->invperm = ABC_ALLOC(int,unique->maxSize); if (unique->invperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique); + return(NULL); } unique->permZ = ABC_ALLOC(int,unique->maxSizeZ); if (unique->permZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique); + return(NULL); } unique->invpermZ = ABC_ALLOC(int,unique->maxSizeZ); if (unique->invpermZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique); + return(NULL); } unique->map = NULL; unique->stack = ABC_ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1); if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique); + return(NULL); } unique->stack[0] = NULL; /* to suppress harmless UMR */ @@ -400,55 +456,85 @@ cuddInitTable( unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2); unique->deathRow = ABC_ALLOC(DdNodePtr,unique->deathRowDepth); if (unique->deathRow == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); } for (i = 0; i < unique->deathRowDepth; i++) { - unique->deathRow[i] = NULL; + unique->deathRow[i] = NULL; } unique->nextDead = 0; unique->deadMask = unique->deathRowDepth - 1; #endif for (i = 0; (unsigned) i < numVars; i++) { - unique->subtables[i].slots = slots; - unique->subtables[i].shift = shift; - unique->subtables[i].keys = 0; - unique->subtables[i].dead = 0; - unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[i].bindVar = 0; - unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[i].pairIndex = 0; - unique->subtables[i].varHandled = 0; - unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].keys = 0; + unique->subtables[i].dead = 0; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; - nodelist = unique->subtables[i].nodelist = ABC_ALLOC(DdNodePtr,slots); - if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = sentinel; - } - unique->perm[i] = i; - unique->invperm[i] = i; + nodelist = unique->subtables[i].nodelist = ABC_ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; j < i; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + unique->perm[i] = i; + unique->invperm[i] = i; } for (i = 0; (unsigned) i < numVarsZ; i++) { - unique->subtableZ[i].slots = slots; - unique->subtableZ[i].shift = shift; - unique->subtableZ[i].keys = 0; - unique->subtableZ[i].dead = 0; - unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - nodelist = unique->subtableZ[i].nodelist = ABC_ALLOC(DdNodePtr,slots); - if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - unique->permZ[i] = i; - unique->invpermZ[i] = i; + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].dead = 0; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->subtableZ[i].nodelist = ABC_ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + for (j = 0; j < i; j++) { + ABC_FREE(unique->subtableZ[j].nodelist); + } + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + unique->permZ[i] = i; + unique->invpermZ[i] = i; } unique->constants.slots = slots; unique->constants.shift = shift; @@ -457,30 +543,43 @@ cuddInitTable( unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; nodelist = unique->constants.nodelist = ABC_ALLOC(DdNodePtr,slots); if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); + for (j = 0; (unsigned) j < numVars; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + for (j = 0; (unsigned) j < numVarsZ; j++) { + ABC_FREE(unique->subtableZ[j].nodelist); + } + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); } for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; + nodelist[j] = NULL; } unique->memoryList = NULL; unique->nextFree = NULL; unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ) - * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * - slots * sizeof(DdNodePtr) + - (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); + * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * + slots * sizeof(DdNodePtr) + + (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); #ifndef DD_NO_DEATH_ROW unique->memused += unique->deathRowDepth * sizeof(DdNodePtr); #endif /* Initialize fields concerned with automatic dynamic reordering */ unique->reorderings = 0; - unique->autoDyn = 0; /* initially disabled */ - unique->autoDynZ = 0; /* initially disabled */ - unique->realign = 0; /* initially disabled */ - unique->realignZ = 0; /* initially disabled */ + unique->autoDyn = 0; /* initially disabled */ + unique->autoDynZ = 0; /* initially disabled */ + unique->realign = 0; /* initially disabled */ + unique->realignZ = 0; /* initially disabled */ unique->reordered = 0; unique->autoMethod = CUDD_REORDER_SIFT; unique->autoMethodZ = CUDD_REORDER_SIFT; @@ -513,7 +612,7 @@ cuddInitTable( unique->errorCode = CUDD_NO_ERROR; /* Initialize statistical counters. */ - unique->maxmemhard = (long) ((~ (unsigned long) 0) >> 1); + unique->maxmemhard = ~ 0UL; unique->garbageCollections = 0; unique->GCTime = 0; unique->reordTime = 0; @@ -560,18 +659,18 @@ cuddFreeTable( if (unique->univ != NULL) cuddZddFreeUniv(unique); while (memlist != NULL) { - next = (DdNodePtr *) memlist[0]; /* link to next block */ - ABC_FREE(memlist); - memlist = next; + next = (DdNodePtr *) memlist[0]; /* link to next block */ + ABC_FREE(memlist); + memlist = next; } unique->nextFree = NULL; unique->memoryList = NULL; for (i = 0; i < unique->size; i++) { - ABC_FREE(unique->subtables[i].nodelist); + ABC_FREE(unique->subtables[i].nodelist); } for (i = 0; i < unique->sizeZ; i++) { - ABC_FREE(unique->subtableZ[i].nodelist); + ABC_FREE(unique->subtableZ[i].nodelist); } ABC_FREE(unique->constants.nodelist); ABC_FREE(unique->subtables); @@ -591,15 +690,15 @@ cuddFreeTable( if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ); if (unique->linear != NULL) ABC_FREE(unique->linear); while (unique->preGCHook != NULL) - Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); + Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); while (unique->postGCHook != NULL) - Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); + Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); while (unique->preReorderingHook != NULL) - Cudd_RemoveHook(unique,unique->preReorderingHook->f, - CUDD_PRE_REORDERING_HOOK); + Cudd_RemoveHook(unique,unique->preReorderingHook->f, + CUDD_PRE_REORDERING_HOOK); while (unique->postReorderingHook != NULL) - Cudd_RemoveHook(unique,unique->postReorderingHook->f, - CUDD_POST_REORDERING_HOOK); + Cudd_RemoveHook(unique,unique->postReorderingHook->f, + CUDD_POST_REORDERING_HOOK); ABC_FREE(unique); } /* end of cuddFreeTable */ @@ -607,9 +706,9 @@ cuddFreeTable( /**Function******************************************************************** - Synopsis [Performs garbage collection on a unique table.] + Synopsis [Performs garbage collection on the unique tables.] - Description [Performs garbage collection on a unique table. + Description [Performs garbage collection on the BDD and ZDD unique tables. If clearCache is 0, the cache is not cleared. This should only be specified if the cache has been cleared right before calling cuddGarbageCollect. (As in the case of dynamic reordering.) @@ -617,7 +716,7 @@ cuddFreeTable( SideEffects [None] - SeeAlso [cuddGarbageCollectZdd] + SeeAlso [] ******************************************************************************/ int @@ -625,18 +724,24 @@ cuddGarbageCollect( DdManager * unique, int clearCache) { - DdHook *hook; - DdCache *cache = unique->cache; - DdNode *sentinel = &(unique->sentinel); - DdNodePtr *nodelist; - int i, j, deleted, totalDeleted; - DdCache *c; - DdNode *node,*next; - DdNodePtr *lastP; - int slots; - long localTime; + DdHook *hook; + DdCache *cache = unique->cache; + DdNode *sentinel = &(unique->sentinel); + DdNodePtr *nodelist; + int i, j, deleted, totalDeleted, totalDeletedZ; + DdCache *c; + DdNode *node,*next; + DdNodePtr *lastP; + int slots; + long localTime; #ifndef DD_UNSORTED_FREE_LIST - DdNodePtr tree; +#ifdef DD_RED_BLACK_FREE_LIST + DdNodePtr tree; +#else + DdNodePtr *memListTrav, *nxtNode; + DdNode *downTrav, *sentry; + int k; +#endif #endif #ifndef DD_NO_DEATH_ROW @@ -645,18 +750,18 @@ cuddGarbageCollect( hook = unique->preGCHook; while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - - if (unique->dead == 0) { - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); + int res = (hook->f)(unique,"DD",NULL); if (res == 0) return(0); hook = hook->next; } + + if (unique->dead + unique->deadZ == 0) { + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } return(0); } @@ -664,14 +769,14 @@ cuddGarbageCollect( ** more aggressively, to reduce the frequency of garbage collection. */ if (clearCache && unique->gcFrac == DD_GC_FRAC_LO && - unique->slots <= unique->looseUpTo && unique->stash != NULL) { - unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); + unique->slots <= unique->looseUpTo && unique->stash != NULL) { + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif - unique->gcFrac = DD_GC_FRAC_HI; - return(0); + unique->gcFrac = DD_GC_FRAC_HI; + return(0); } localTime = util_cpu_time(); @@ -679,115 +784,124 @@ cuddGarbageCollect( unique->garbageCollections++; #ifdef DD_VERBOSE (void) fprintf(unique->err, - "garbage collecting (%d dead out of %d, min %d)...", - unique->dead, unique->keys, unique->minDead); + "garbage collecting (%d dead BDD nodes out of %d, min %d)...", + unique->dead, unique->keys, unique->minDead); + (void) fprintf(unique->err, + " (%d dead ZDD nodes out of %d)...", + unique->deadZ, unique->keysZ); #endif /* Remove references to garbage collected nodes from the cache. */ if (clearCache) { - slots = unique->cacheSlots; - for (i = 0; i < slots; i++) { - c = &cache[i]; - if (c->data != NULL) { - if (cuddClean(c->f)->ref == 0 || - cuddClean(c->g)->ref == 0 || - (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || - (c->data != DD_NON_CONSTANT && - Cudd_Regular(c->data)->ref == 0)) { - c->data = NULL; - unique->cachedeletions++; - } + slots = unique->cacheSlots; + for (i = 0; i < slots; i++) { + c = &cache[i]; + if (c->data != NULL) { + if (cuddClean(c->f)->ref == 0 || + cuddClean(c->g)->ref == 0 || + (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || + (c->data != DD_NON_CONSTANT && + Cudd_Regular(c->data)->ref == 0)) { + c->data = NULL; + unique->cachedeletions++; + } + } } - } - cuddLocalCacheClearDead(unique); + cuddLocalCacheClearDead(unique); } /* Now return dead nodes to free list. Count them for sanity check. */ totalDeleted = 0; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST tree = NULL; #endif +#endif for (i = 0; i < unique->size; i++) { - if (unique->subtables[i].dead == 0) continue; - nodelist = unique->subtables[i].nodelist; - - deleted = 0; - slots = unique->subtables[i].slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != sentinel) { - next = node->next; - if (node->ref == 0) { - deleted++; + if (unique->subtables[i].dead == 0) continue; + nodelist = unique->subtables[i].nodelist; + + deleted = 0; + slots = unique->subtables[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != sentinel) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = sentinel; } - node = next; + if ((unsigned) deleted != unique->subtables[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); } - *lastP = sentinel; - } - if ((unsigned) deleted != unique->subtables[i].dead) { - ddReportRefMess(unique, i, "cuddGarbageCollect"); - } - totalDeleted += deleted; - unique->subtables[i].keys -= deleted; - unique->subtables[i].dead = 0; + totalDeleted += deleted; + unique->subtables[i].keys -= deleted; + unique->subtables[i].dead = 0; } if (unique->constants.dead != 0) { - nodelist = unique->constants.nodelist; - deleted = 0; - slots = unique->constants.slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != NULL) { - next = node->next; - if (node->ref == 0) { - deleted++; + nodelist = unique->constants.nodelist; + deleted = 0; + slots = unique->constants.slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); - } - node = next; + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; } - *lastP = NULL; - } - if ((unsigned) deleted != unique->constants.dead) { - ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); - } - totalDeleted += deleted; - unique->constants.keys -= deleted; - unique->constants.dead = 0; + if ((unsigned) deleted != unique->constants.dead) { + ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->constants.keys -= deleted; + unique->constants.dead = 0; } if ((unsigned) totalDeleted != unique->dead) { - ddReportRefMess(unique, -1, "cuddGarbageCollect"); + ddReportRefMess(unique, -1, "cuddGarbageCollect"); } unique->keys -= totalDeleted; unique->dead = 0; @@ -795,198 +909,110 @@ cuddGarbageCollect( unique->nodesFreed += (double) totalDeleted; #endif -#ifndef DD_UNSORTED_FREE_LIST - unique->nextFree = cuddOrderedThread(tree,unique->nextFree); -#endif - - unique->GCTime += util_cpu_time() - localTime; - - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - -#ifdef DD_VERBOSE - (void) fprintf(unique->err," done\n"); -#endif - - return(totalDeleted); - -} /* end of cuddGarbageCollect */ - - -/**Function******************************************************************** - - Synopsis [Performs garbage collection on a ZDD unique table.] - - Description [Performs garbage collection on a ZDD unique table. - If clearCache is 0, the cache is not cleared. This should only be - specified if the cache has been cleared right before calling - cuddGarbageCollectZdd. (As in the case of dynamic reordering.) - Returns the total number of deleted nodes.] - - SideEffects [None] - - SeeAlso [cuddGarbageCollect] - -******************************************************************************/ -int -cuddGarbageCollectZdd( - DdManager * unique, - int clearCache) -{ - DdHook *hook; - DdCache *cache = unique->cache; - DdNodePtr *nodelist; - int i, j, deleted, totalDeleted; - DdCache *c; - DdNode *node,*next; - DdNodePtr *lastP; - int slots; - long localTime; -#ifndef DD_UNSORTED_FREE_LIST - DdNodePtr tree; -#endif - - hook = unique->preGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - - if (unique->deadZ == 0) { - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - return(0); - } - - /* If many nodes are being reclaimed, we want to resize the tables - ** more aggressively, to reduce the frequency of garbage collection. - */ - if (clearCache && unique->slots <= unique->looseUpTo) { - unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); -#ifdef DD_VERBOSE - if (unique->gcFrac == DD_GC_FRAC_LO) { - (void) fprintf(unique->err,"GC fraction = %.2f\t", - DD_GC_FRAC_HI); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); - } -#endif - unique->gcFrac = DD_GC_FRAC_HI; - } - - localTime = util_cpu_time(); - - unique->garbageCollections++; -#ifdef DD_VERBOSE - (void) fprintf(unique->err,"garbage collecting (%d dead out of %d)...", - unique->deadZ,unique->keysZ); -#endif - - /* Remove references to garbage collected nodes from the cache. */ - if (clearCache) { - slots = unique->cacheSlots; - for (i = 0; i < slots; i++) { - c = &cache[i]; - if (c->data != NULL) { - if (cuddClean(c->f)->ref == 0 || - cuddClean(c->g)->ref == 0 || - (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || - (c->data != DD_NON_CONSTANT && - Cudd_Regular(c->data)->ref == 0)) { - c->data = NULL; - unique->cachedeletions++; - } - } - } - } - - /* Now return dead nodes to free list. Count them for sanity check. */ - totalDeleted = 0; -#ifndef DD_UNSORTED_FREE_LIST - tree = NULL; -#endif + totalDeletedZ = 0; for (i = 0; i < unique->sizeZ; i++) { - if (unique->subtableZ[i].dead == 0) continue; - nodelist = unique->subtableZ[i].nodelist; - - deleted = 0; - slots = unique->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != NULL) { - next = node->next; - if (node->ref == 0) { - deleted++; + if (unique->subtableZ[i].dead == 0) continue; + nodelist = unique->subtableZ[i].nodelist; + + deleted = 0; + slots = unique->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); - } - node = next; + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; } - *lastP = NULL; - } - if ((unsigned) deleted != unique->subtableZ[i].dead) { - ddReportRefMess(unique, i, "cuddGarbageCollectZdd"); - } - totalDeleted += deleted; - unique->subtableZ[i].keys -= deleted; - unique->subtableZ[i].dead = 0; + if ((unsigned) deleted != unique->subtableZ[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeletedZ += deleted; + unique->subtableZ[i].keys -= deleted; + unique->subtableZ[i].dead = 0; } /* No need to examine the constant table for ZDDs. ** If we did we should be careful not to count whatever dead ** nodes we found there among the dead ZDD nodes. */ - if ((unsigned) totalDeleted != unique->deadZ) { - ddReportRefMess(unique, -1, "cuddGarbageCollectZdd"); + if ((unsigned) totalDeletedZ != unique->deadZ) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); } - unique->keysZ -= totalDeleted; + unique->keysZ -= totalDeletedZ; unique->deadZ = 0; #ifdef DD_STATS - unique->nodesFreed += (double) totalDeleted; + unique->nodesFreed += (double) totalDeletedZ; #endif + #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST unique->nextFree = cuddOrderedThread(tree,unique->nextFree); +#else + memListTrav = unique->memoryList; + sentry = NULL; + while (memListTrav != NULL) { + ptruint offset; + nxtNode = (DdNodePtr *)memListTrav[0]; + offset = (ptruint) memListTrav & (sizeof(DdNode) - 1); + memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + downTrav = (DdNode *)memListTrav; + k = 0; + do { + if (downTrav[k].ref == 0) { + if (sentry == NULL) { + unique->nextFree = sentry = &downTrav[k]; + } else { + /* First hook sentry->next to the dead node and then + ** reassign sentry to the dead node. */ + sentry = (sentry->next = &downTrav[k]); + } + } + } while (++k < DD_MEM_CHUNK); + memListTrav = nxtNode; + } + sentry->next = NULL; +#endif #endif unique->GCTime += util_cpu_time() - localTime; hook = unique->postGCHook; while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; } #ifdef DD_VERBOSE (void) fprintf(unique->err," done\n"); #endif - return(totalDeleted); + return(totalDeleted+totalDeletedZ); -} /* end of cuddGarbageCollectZdd */ +} /* end of cuddGarbageCollect */ /**Function******************************************************************** @@ -1009,10 +1035,10 @@ cuddZddGetNode( DdNode * T, DdNode * E) { - DdNode *node; + DdNode *node; if (T == DD_ZERO(zdd)) - return(E); + return(E); node = cuddUniqueInterZdd(zdd, id, T, E); return(node); @@ -1042,26 +1068,26 @@ cuddZddGetNodeIVO( DdNode * g, DdNode * h) { - DdNode *f, *r, *t; - DdNode *zdd_one = DD_ONE(dd); - DdNode *zdd_zero = DD_ZERO(dd); + DdNode *f, *r, *t; + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero); if (f == NULL) { - return(NULL); + return(NULL); } cuddRef(f); t = cuddZddProduct(dd, f, g); if (t == NULL) { - Cudd_RecursiveDerefZdd(dd, f); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f); + return(NULL); } cuddRef(t); Cudd_RecursiveDerefZdd(dd, f); r = cuddZddUnion(dd, t, h); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); } cuddRef(r); Cudd_RecursiveDerefZdd(dd, t); @@ -1110,7 +1136,7 @@ cuddUniqueInter( #endif if (index >= unique->size) { - if (!ddResizeTable(unique,index)) return(NULL); + if (!ddResizeTable(unique,index)) return(NULL); } level = unique->perm[index]; @@ -1127,116 +1153,115 @@ cuddUniqueInter( looking = *previousP; while (T < cuddT(looking)) { - previousP = &(looking->next); - looking = *previousP; + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } if (T == cuddT(looking) && E == cuddE(looking)) { - if (looking->ref == 0) { - cuddReclaim(unique,looking); - } - return(looking); + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); } /* countDead is 0 if deads should be counted and ~0 if they should not. */ if (unique->autoDyn && unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn) { #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) return(NULL); - retval = Cudd_CheckKeys(unique); - if (retval != 0) return(NULL); + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); #endif - retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ - if (retval == 0) unique->reordered = 2; + retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) unique->reordered = 2; - retval = Cudd_CheckKeys(unique); - if (retval != 0) unique->reordered = 2; + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; #endif - return(NULL); + return(NULL); } if (subtable->keys > subtable->maxKeys) { if (unique->gcEnabled && - ((unique->dead > unique->minDead) || - ((unique->dead > unique->minDead / 2) && - (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ - (void) cuddGarbageCollect(unique,1); - } else { - cuddRehash(unique,(int)level); - } - /* Update pointer to insertion point. In the case of rehashing, - ** the slot may have changed. In the case of garbage collection, - ** the predecessor may have been dead. */ - pos = ddHash(T, E, subtable->shift); - nodelist = subtable->nodelist; - previousP = &(nodelist[pos]); - looking = *previousP; - - while (T < cuddT(looking)) { - previousP = &(looking->next); + ((unique->dead > unique->minDead) || + ((unique->dead > unique->minDead / 2) && + (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,(int)level); + } + /* Update pointer to insertion point. In the case of rehashing, + ** the slot may have changed. In the case of garbage collection, + ** the predecessor may have been dead. */ + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } + } } gcNumber = unique->garbageCollections; looking = cuddAllocNode(unique); if (looking == NULL) { - return(NULL); + return(NULL); } unique->keys++; subtable->keys++; if (gcNumber != unique->garbageCollections) { - DdNode *looking2; - pos = ddHash(T, E, subtable->shift); - nodelist = subtable->nodelist; - previousP = &(nodelist[pos]); - looking2 = *previousP; - - while (T < cuddT(looking2)) { - previousP = &(looking2->next); + DdNode *looking2; + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); looking2 = *previousP; + + while (T < cuddT(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking2) && E < cuddE(looking2)) { - previousP = &(looking2->next); - looking2 = *previousP; + } + while (T == cuddT(looking2) && E < cuddE(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif + } } - } - looking->ref = 0; looking->index = index; cuddT(looking) = T; cuddE(looking) = E; looking->next = *previousP; *previousP = looking; - cuddSatInc(T->ref); /* we know T is a regular pointer */ + cuddSatInc(T->ref); /* we know T is a regular pointer */ cuddRef(E); #ifdef DD_DEBUG @@ -1275,9 +1300,9 @@ cuddUniqueInterIVO( DdNode *v; v = cuddUniqueInter(unique, index, DD_ONE(unique), - Cudd_Not(DD_ONE(unique))); + Cudd_Not(DD_ONE(unique))); if (v == NULL) - return(NULL); + return(NULL); cuddRef(v); result = cuddBddIteRecur(unique, v, T, E); Cudd_RecursiveDeref(unique, v); @@ -1322,7 +1347,7 @@ cuddUniqueInterZdd( #endif if (index >= unique->sizeZ) { - if (!cuddResizeTableZdd(unique,index)) return(NULL); + if (!cuddResizeTableZdd(unique,index)) return(NULL); } level = unique->permZ[index]; @@ -1335,11 +1360,11 @@ cuddUniqueInterZdd( if (subtable->keys > subtable->maxKeys) { if (unique->gcEnabled && ((unique->deadZ > unique->minDead) || - (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ - (void) cuddGarbageCollectZdd(unique,1); - } else { - ddRehashZdd(unique,(int)level); - } + (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + ddRehashZdd(unique,(int)level); + } } pos = ddHash(T, E, subtable->shift); @@ -1348,14 +1373,14 @@ cuddUniqueInterZdd( while (looking != NULL) { if (cuddT(looking) == T && cuddE(looking) == E) { - if (looking->ref == 0) { - cuddReclaimZdd(unique,looking); + if (looking->ref == 0) { + cuddReclaimZdd(unique,looking); + } + return(looking); } - return(looking); - } - looking = looking->next; + looking = looking->next; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } @@ -1363,20 +1388,20 @@ cuddUniqueInterZdd( if (unique->autoDynZ && unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) { #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) return(NULL); - retval = Cudd_CheckKeys(unique); - if (retval != 0) return(NULL); + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); #endif - retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ - if (retval == 0) unique->reordered = 2; + retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) unique->reordered = 2; - retval = Cudd_CheckKeys(unique); - if (retval != 0) unique->reordered = 2; + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; #endif - return(NULL); + return(NULL); } unique->keysZ++; @@ -1384,7 +1409,6 @@ cuddUniqueInterZdd( looking = cuddAllocNode(unique); if (looking == NULL) return(NULL); - looking->ref = 0; looking->index = index; cuddT(looking) = T; cuddE(looking) = E; @@ -1427,17 +1451,17 @@ cuddUniqueConst( if (unique->constants.keys > unique->constants.maxKeys) { if (unique->gcEnabled && ((unique->dead > unique->minDead) || - (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ - (void) cuddGarbageCollect(unique,1); - } else { - cuddRehash(unique,CUDD_CONST_INDEX); - } + (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,CUDD_CONST_INDEX); + } } cuddAdjust(value); /* for the case of crippled infinities */ if (ddAbs(value) < unique->epsilon) { - value = 0.0; + value = 0.0; } split.value = value; @@ -1452,15 +1476,15 @@ cuddUniqueConst( */ while (looking != NULL) { if (looking->type.value == value || - ddEqualVal(looking->type.value,value,unique->epsilon)) { - if (looking->ref == 0) { - cuddReclaim(unique,looking); + ddEqualVal(looking->type.value,value,unique->epsilon)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); } - return(looking); - } - looking = looking->next; + looking = looking->next; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } @@ -1469,7 +1493,6 @@ cuddUniqueConst( looking = cuddAllocNode(unique); if (looking == NULL) return(NULL); - looking->ref = 0; looking->index = CUDD_CONST_INDEX; looking->type.value = value; looking->next = nodelist[pos]; @@ -1504,144 +1527,143 @@ cuddRehash( DdNode *node, *next; DdNode *sentinel = &(unique->sentinel); hack split; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) { - unique->gcFrac = DD_GC_FRAC_LO; - unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); + unique->gcFrac = DD_GC_FRAC_LO; + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif } if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) { - unique->gcFrac = DD_GC_FRAC_MIN; - unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif - cuddShrinkDeathRow(unique); - if (cuddGarbageCollect(unique,1) > 0) return; + cuddShrinkDeathRow(unique); + if (cuddGarbageCollect(unique,1) > 0) return; } if (i != CUDD_CONST_INDEX) { - oldslots = unique->subtables[i].slots; - oldshift = unique->subtables[i].shift; - oldnodelist = unique->subtables[i].nodelist; - - /* Compute the new size of the subtable. */ - slots = oldslots << 1; - shift = oldshift - 1; + oldslots = unique->subtables[i].slots; + oldshift = unique->subtables[i].shift; + oldnodelist = unique->subtables[i].nodelist; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - (void) fprintf(unique->err, - "Unable to resize subtable %d for lack of memory\n", - i); - /* Prevent frequent resizing attempts. */ - (void) cuddGarbageCollect(unique,1); - if (unique->stash != NULL) { - ABC_FREE(unique->stash); - unique->stash = NULL; - /* Inhibit resizing of tables. */ - cuddSlowTableGrowth(unique); - } - return; - } - unique->subtables[i].nodelist = nodelist; - unique->subtables[i].slots = slots; - unique->subtables[i].shift = shift; - unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + /* Compute the new size of the subtable. */ + slots = oldslots << 1; + shift = oldshift - 1; - /* Move the nodes from the old table to the new table. - ** This code depends on the type of hash function. - ** It assumes that the effect of doubling the size of the table - ** is to retain one more bit of the 32-bit hash value. - ** The additional bit is the LSB. */ - for (j = 0; (unsigned) j < oldslots; j++) { - DdNodePtr *evenP, *oddP; - node = oldnodelist[j]; - evenP = &(nodelist[j<<1]); - oddP = &(nodelist[(j<<1)+1]); - while (node != sentinel) { - next = node->next; - pos = ddHash(cuddT(node), cuddE(node), shift); - if (pos & 1) { - *oddP = node; - oddP = &(node->next); - } else { - *evenP = node; - evenP = &(node->next); + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize subtable %d for lack of memory\n", + i); + /* Prevent frequent resizing attempts. */ + (void) cuddGarbageCollect(unique,1); + if (unique->stash != NULL) { + ABC_FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + } + return; } - node = next; + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + + /* Move the nodes from the old table to the new table. + ** This code depends on the type of hash function. + ** It assumes that the effect of doubling the size of the table + ** is to retain one more bit of the 32-bit hash value. + ** The additional bit is the LSB. */ + for (j = 0; (unsigned) j < oldslots; j++) { + DdNodePtr *evenP, *oddP; + node = oldnodelist[j]; + evenP = &(nodelist[j<<1]); + oddP = &(nodelist[(j<<1)+1]); + while (node != sentinel) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + if (pos & 1) { + *oddP = node; + oddP = &(node->next); + } else { + *evenP = node; + evenP = &(node->next); + } + node = next; + } + *evenP = *oddP = sentinel; } - *evenP = *oddP = sentinel; - } - ABC_FREE(oldnodelist); + ABC_FREE(oldnodelist); #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "rehashing layer %d: keys %d dead %d new size %d\n", - i, unique->subtables[i].keys, - unique->subtables[i].dead, slots); + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtables[i].keys, + unique->subtables[i].dead, slots); #endif } else { - oldslots = unique->constants.slots; - oldshift = unique->constants.shift; - oldnodelist = unique->constants.nodelist; - - /* The constant subtable is never subjected to reordering. - ** Therefore, when it is resized, it is because it has just - ** reached the maximum load. We can safely just double the size, - ** with no need for the loop we use for the other tables. - */ - slots = oldslots << 1; - shift = oldshift - 1; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - int j; - (void) fprintf(unique->err, - "Unable to resize constant subtable for lack of memory\n"); - (void) cuddGarbageCollect(unique,1); - for (j = 0; j < unique->size; j++) { - unique->subtables[j].maxKeys <<= 1; + oldslots = unique->constants.slots; + oldshift = unique->constants.shift; + oldnodelist = unique->constants.nodelist; + + /* The constant subtable is never subjected to reordering. + ** Therefore, when it is resized, it is because it has just + ** reached the maximum load. We can safely just double the size, + ** with no need for the loop we use for the other tables. + */ + slots = oldslots << 1; + shift = oldshift - 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize constant subtable for lack of memory\n"); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->size; j++) { + unique->subtables[j].maxKeys <<= 1; + } + unique->constants.maxKeys <<= 1; + return; } - unique->constants.maxKeys <<= 1; - return; - } - unique->constants.slots = slots; - unique->constants.shift = shift; - unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - unique->constants.nodelist = nodelist; - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - split.value = cuddV(node); - pos = ddHash(split.bits[0], split.bits[1], shift); - node->next = nodelist[pos]; - nodelist[pos] = node; - node = next; + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->constants.nodelist = nodelist; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; } - } - ABC_FREE(oldnodelist); + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + split.value = cuddV(node); + pos = ddHash(split.bits[0], split.bits[1], shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + ABC_FREE(oldnodelist); #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "rehashing constants: keys %d dead %d new size %d\n", - unique->constants.keys,unique->constants.dead,slots); + (void) fprintf(unique->err, + "rehashing constants: keys %d dead %d new size %d\n", + unique->constants.keys,unique->constants.dead,slots); #endif } @@ -1676,8 +1698,8 @@ cuddShrinkSubtable( DdNode *node, *next; DdNode *sentinel = &(unique->sentinel); unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; oldnodelist = unique->subtables[i].nodelist; oldslots = unique->subtables[i].slots; @@ -1687,7 +1709,7 @@ cuddShrinkSubtable( nodelist = ABC_ALLOC(DdNodePtr, slots); MMoutOfMemory = saveHandler; if (nodelist == NULL) { - return; + return; } unique->subtables[i].nodelist = nodelist; unique->subtables[i].slots = slots; @@ -1695,43 +1717,43 @@ cuddShrinkSubtable( unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; #ifdef DD_VERBOSE (void) fprintf(unique->err, - "shrunk layer %d (%d keys) from %d to %d slots\n", - i, unique->subtables[i].keys, oldslots, slots); + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, unique->subtables[i].keys, oldslots, slots); #endif for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = sentinel; + nodelist[j] = sentinel; } shift = unique->subtables[i].shift; for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != sentinel) { - DdNode *looking, *T, *E; - DdNodePtr *previousP; - next = node->next; - posn = ddHash(cuddT(node), cuddE(node), shift); - previousP = &(nodelist[posn]); - looking = *previousP; - T = cuddT(node); - E = cuddE(node); - while (T < cuddT(looking)) { - previousP = &(looking->next); - looking = *previousP; + node = oldnodelist[j]; + while (node != sentinel) { + DdNode *looking, *T, *E; + DdNodePtr *previousP; + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + previousP = &(nodelist[posn]); + looking = *previousP; + T = cuddT(node); + E = cuddE(node); + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif + } + node->next = *previousP; + *previousP = node; + node = next; } - node->next = *previousP; - *previousP = node; - node = next; - } } ABC_FREE(oldnodelist); @@ -1739,8 +1761,8 @@ cuddShrinkSubtable( unique->slots += slots - oldslots; unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); unique->cacheSlack = (int) - ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - - 2 * (int) unique->cacheSlots; + ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) + - 2 * (int) unique->cacheSlots; } /* end of cuddShrinkSubtable */ @@ -1771,8 +1793,7 @@ cuddInsertSubtables( int oldsize,newsize; int i,j,index,reorderSave; unsigned int numSlots = unique->initSlots; - int *newperm, *newinvperm; - int *newmap = NULL; // Suppress "might be used uninitialized" + int *newperm, *newinvperm, *newmap; DdNode *one, *zero; #ifdef DD_DEBUG @@ -1782,210 +1803,210 @@ cuddInsertSubtables( oldsize = unique->size; /* Easy case: there is still room in the current table. */ if (oldsize + n <= unique->maxSize) { - /* Shift the tables at and below level. */ - for (i = oldsize - 1; i >= level; i--) { - unique->subtables[i+n].slots = unique->subtables[i].slots; - unique->subtables[i+n].shift = unique->subtables[i].shift; - unique->subtables[i+n].keys = unique->subtables[i].keys; - unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; - unique->subtables[i+n].dead = unique->subtables[i].dead; - unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; - unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; - unique->subtables[i+n].varType = unique->subtables[i].varType; - unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; - unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; - unique->subtables[i+n].varToBeGrouped = - unique->subtables[i].varToBeGrouped; - - index = unique->invperm[i]; - unique->invperm[i+n] = index; - unique->perm[index] += n; - } - /* Create new subtables. */ - for (i = 0; i < n; i++) { - unique->subtables[level+i].slots = numSlots; - unique->subtables[level+i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtables[level+i].keys = 0; - unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[level+i].dead = 0; - unique->subtables[level+i].bindVar = 0; - unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[level+i].pairIndex = 0; - unique->subtables[level+i].varHandled = 0; - unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; - - unique->perm[oldsize+i] = level + i; - unique->invperm[level+i] = oldsize + i; - newnodelist = unique->subtables[level+i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + /* Shift the tables at and below level. */ + for (i = oldsize - 1; i >= level; i--) { + unique->subtables[i+n].slots = unique->subtables[i].slots; + unique->subtables[i+n].shift = unique->subtables[i].shift; + unique->subtables[i+n].keys = unique->subtables[i].keys; + unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; + unique->subtables[i+n].dead = unique->subtables[i].dead; + unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; + unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; + unique->subtables[i+n].varType = unique->subtables[i].varType; + unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; + unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; + unique->subtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + index = unique->invperm[i]; + unique->invperm[i+n] = index; + unique->perm[index] += n; } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = sentinel; - } - } - if (unique->map != NULL) { + /* Create new subtables. */ for (i = 0; i < n; i++) { - unique->map[oldsize+i] = oldsize + i; + unique->subtables[level+i].slots = numSlots; + unique->subtables[level+i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[level+i].keys = 0; + unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[level+i].dead = 0; + unique->subtables[level+i].bindVar = 0; + unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[level+i].pairIndex = 0; + unique->subtables[level+i].varHandled = 0; + unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[oldsize+i] = level + i; + unique->invperm[level+i] = oldsize + i; + newnodelist = unique->subtables[level+i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < n; i++) { + unique->map[oldsize+i] = oldsize + i; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables. - */ - newsize = oldsize + n + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables. + */ + newsize = oldsize + n + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the table size from %d to %d\n", - unique->maxSize, newsize); + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); #endif - /* Allocate memory for new arrays (except nodelists). */ - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newvars = ABC_ALLOC(DdNodePtr,newsize); - if (newvars == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - return(0); - } - if (unique->map != NULL) { - newmap = ABC_ALLOC(int,newsize); - if (newmap == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - return(0); + /* Allocate memory for new arrays (except nodelists). */ + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->memused += (newsize - unique->maxSize) * sizeof(int); - } - unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - /* Copy levels before insertion points from old tables. */ - for (i = 0; i < level; i++) { - newsubtables[i].slots = unique->subtables[i].slots; - newsubtables[i].shift = unique->subtables[i].shift; - newsubtables[i].keys = unique->subtables[i].keys; - newsubtables[i].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i].dead = unique->subtables[i].dead; - newsubtables[i].nodelist = unique->subtables[i].nodelist; - newsubtables[i].bindVar = unique->subtables[i].bindVar; - newsubtables[i].varType = unique->subtables[i].varType; - newsubtables[i].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i].varHandled = unique->subtables[i].varHandled; - newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - newperm[i] = unique->perm[i]; - newinvperm[i] = unique->invperm[i]; - } - /* Finish initializing permutation for new table to old one. */ - for (i = level; i < oldsize; i++) { - newperm[i] = unique->perm[i]; - } - /* Initialize new levels. */ - for (i = level; i < level + n; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newsubtables[i].bindVar = 0; - newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - newsubtables[i].pairIndex = 0; - newsubtables[i].varHandled = 0; - newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - newperm[oldsize + i - level] = i; - newinvperm[i] = oldsize + i - level; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - /* We are going to leak some memory. We should clean up. */ - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newvars = ABC_ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + return(0); } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = sentinel; - } - } - /* Copy the old tables for levels past the insertion point. */ - for (i = level; i < oldsize; i++) { - newsubtables[i+n].slots = unique->subtables[i].slots; - newsubtables[i+n].shift = unique->subtables[i].shift; - newsubtables[i+n].keys = unique->subtables[i].keys; - newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i+n].dead = unique->subtables[i].dead; - newsubtables[i+n].nodelist = unique->subtables[i].nodelist; - newsubtables[i+n].bindVar = unique->subtables[i].bindVar; - newsubtables[i+n].varType = unique->subtables[i].varType; - newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i+n].varHandled = unique->subtables[i].varHandled; - newsubtables[i+n].varToBeGrouped = - unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - index = unique->invperm[i]; - newinvperm[i+n] = index; - newperm[index] += n; - } - /* Update the map. */ - if (unique->map != NULL) { - for (i = 0; i < oldsize; i++) { - newmap[i] = unique->map[i]; + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + return(0); } - for (i = oldsize; i < oldsize + n; i++) { - newmap[i] = i; + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + return(0); } - ABC_FREE(unique->map); - unique->map = newmap; - } - /* Install the new tables and free the old ones. */ - ABC_FREE(unique->subtables); - unique->subtables = newsubtables; - unique->maxSize = newsize; - ABC_FREE(unique->vars); - unique->vars = newvars; - ABC_FREE(unique->perm); - unique->perm = newperm; - ABC_FREE(unique->invperm); - unique->invperm = newinvperm; - /* Update the stack for iterative procedures. */ - if (newsize > unique->maxSizeZ) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + if (unique->map != NULL) { + newmap = ABC_ALLOC(int,newsize); + if (newmap == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + /* Copy levels before insertion points from old tables. */ + for (i = 0; i < level; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + /* Finish initializing permutation for new table to old one. */ + for (i = level; i < oldsize; i++) { + newperm[i] = unique->perm[i]; + } + /* Initialize new levels. */ + for (i = level; i < level + n; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[oldsize + i - level] = i; + newinvperm[i] = oldsize + i - level; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + /* We are going to leak some memory. We should clean up. */ + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + /* Copy the old tables for levels past the insertion point. */ + for (i = level; i < oldsize; i++) { + newsubtables[i+n].slots = unique->subtables[i].slots; + newsubtables[i+n].shift = unique->subtables[i].shift; + newsubtables[i+n].keys = unique->subtables[i].keys; + newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i+n].dead = unique->subtables[i].dead; + newsubtables[i+n].nodelist = unique->subtables[i].nodelist; + newsubtables[i+n].bindVar = unique->subtables[i].bindVar; + newsubtables[i+n].varType = unique->subtables[i].varType; + newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i+n].varHandled = unique->subtables[i].varHandled; + newsubtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + index = unique->invperm[i]; + newinvperm[i+n] = index; + newperm[index] += n; + } + /* Update the map. */ + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i < oldsize + n; i++) { + newmap[i] = i; + } + ABC_FREE(unique->map); + unique->map = newmap; + } + /* Install the new tables and free the old ones. */ + ABC_FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + ABC_FREE(unique->vars); + unique->vars = newvars; + ABC_FREE(unique->perm); + unique->perm = newperm; + ABC_FREE(unique->invperm); + unique->invperm = newinvperm; + /* Update the stack for iterative procedures. */ + if (newsize > unique->maxSizeZ) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } } /* Update manager parameters to account for the new subtables. */ unique->slots += n * numSlots; @@ -2002,53 +2023,53 @@ cuddInsertSubtables( reorderSave = unique->autoDyn; unique->autoDyn = 0; for (i = oldsize; i < oldsize + n; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) { - unique->autoDyn = reorderSave; - /* Shift everything back so table remains coherent. */ - for (j = oldsize; j < i; j++) { - Cudd_IterDerefBdd(unique,unique->vars[j]); - cuddDeallocNode(unique,unique->vars[j]); - unique->vars[j] = NULL; - } - for (j = level; j < oldsize; j++) { - unique->subtables[j].slots = unique->subtables[j+n].slots; - unique->subtables[j].slots = unique->subtables[j+n].slots; - unique->subtables[j].shift = unique->subtables[j+n].shift; - unique->subtables[j].keys = unique->subtables[j+n].keys; - unique->subtables[j].maxKeys = - unique->subtables[j+n].maxKeys; - unique->subtables[j].dead = unique->subtables[j+n].dead; - ABC_FREE(unique->subtables[j].nodelist); - unique->subtables[j].nodelist = - unique->subtables[j+n].nodelist; - unique->subtables[j+n].nodelist = NULL; - unique->subtables[j].bindVar = - unique->subtables[j+n].bindVar; - unique->subtables[j].varType = - unique->subtables[j+n].varType; - unique->subtables[j].pairIndex = - unique->subtables[j+n].pairIndex; - unique->subtables[j].varHandled = - unique->subtables[j+n].varHandled; - unique->subtables[j].varToBeGrouped = - unique->subtables[j+n].varToBeGrouped; - index = unique->invperm[j+n]; - unique->invperm[j] = index; - unique->perm[index] -= n; - } - unique->size = oldsize; - unique->slots -= n * numSlots; - ddFixLimits(unique); - (void) Cudd_DebugCheck(unique); - return(0); - } - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + /* Shift everything back so table remains coherent. */ + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = level; j < oldsize; j++) { + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].shift = unique->subtables[j+n].shift; + unique->subtables[j].keys = unique->subtables[j+n].keys; + unique->subtables[j].maxKeys = + unique->subtables[j+n].maxKeys; + unique->subtables[j].dead = unique->subtables[j+n].dead; + ABC_FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = + unique->subtables[j+n].nodelist; + unique->subtables[j+n].nodelist = NULL; + unique->subtables[j].bindVar = + unique->subtables[j+n].bindVar; + unique->subtables[j].varType = + unique->subtables[j+n].varType; + unique->subtables[j].pairIndex = + unique->subtables[j+n].pairIndex; + unique->subtables[j].varHandled = + unique->subtables[j+n].varHandled; + unique->subtables[j].varToBeGrouped = + unique->subtables[j+n].varToBeGrouped; + index = unique->invperm[j+n]; + unique->invperm[j] = index; + unique->perm[index] -= n; + } + unique->size = oldsize; + unique->slots -= n * numSlots; + ddFixLimits(unique); + (void) Cudd_DebugCheck(unique); + return(0); + } + cuddRef(unique->vars[i]); } if (unique->tree != NULL) { - unique->tree->size += n; - unique->tree->index = unique->invperm[0]; - ddPatchTree(unique,unique->tree); + unique->tree->size += n; + unique->tree->index = unique->invperm[0]; + ddPatchTree(unique,unique->tree); } unique->autoDyn = reorderSave; @@ -2103,26 +2124,26 @@ cuddDestroySubtables( */ lowestLevel = unique->size; for (index = firstIndex; index < lastIndex; index++) { - level = unique->perm[index]; - if (level < lowestLevel) lowestLevel = level; - nodelist = subtables[level].nodelist; - if (subtables[level].keys - subtables[level].dead != 1) return(0); - /* The projection function should be isolated. If the ref count - ** is 1, everything is OK. If the ref count is saturated, then - ** we need to make sure that there are no nodes pointing to it. - ** As for the external references, we assume the application is - ** responsible for them. - */ - if (vars[index]->ref != 1) { - if (vars[index]->ref != DD_MAXREF) return(0); - found = cuddFindParent(unique,vars[index]); - if (found) { - return(0); - } else { - vars[index]->ref = 1; + level = unique->perm[index]; + if (level < lowestLevel) lowestLevel = level; + nodelist = subtables[level].nodelist; + if (subtables[level].keys - subtables[level].dead != 1) return(0); + /* The projection function should be isolated. If the ref count + ** is 1, everything is OK. If the ref count is saturated, then + ** we need to make sure that there are no nodes pointing to it. + ** As for the external references, we assume the application is + ** responsible for them. + */ + if (vars[index]->ref != 1) { + if (vars[index]->ref != DD_MAXREF) return(0); + found = cuddFindParent(unique,vars[index]); + if (found) { + return(0); + } else { + vars[index]->ref = 1; + } } - } - Cudd_RecursiveDeref(unique,vars[index]); + Cudd_RecursiveDeref(unique,vars[index]); } /* Collect garbage, because we cannot afford having dead nodes pointing @@ -2132,15 +2153,15 @@ cuddDestroySubtables( /* Here we know we can destroy our subtables. */ for (index = firstIndex; index < lastIndex; index++) { - level = unique->perm[index]; - nodelist = subtables[level].nodelist; + level = unique->perm[index]; + nodelist = subtables[level].nodelist; #ifdef DD_DEBUG - assert(subtables[level].keys == 0); + assert(subtables[level].keys == 0); #endif - ABC_FREE(nodelist); - unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; - unique->slots -= subtables[level].slots; - unique->dead -= subtables[level].dead; + ABC_FREE(nodelist); + unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; + unique->slots -= subtables[level].slots; + unique->dead -= subtables[level].dead; } /* Here all subtables to be destroyed have their keys field == 0 and @@ -2152,33 +2173,33 @@ cuddDestroySubtables( */ shift = 1; for (level = lowestLevel + 1; level < unique->size; level++) { - if (subtables[level].keys == 0) { - shift++; - continue; - } - newlevel = level - shift; - subtables[newlevel].slots = subtables[level].slots; - subtables[newlevel].shift = subtables[level].shift; - subtables[newlevel].keys = subtables[level].keys; - subtables[newlevel].maxKeys = subtables[level].maxKeys; - subtables[newlevel].dead = subtables[level].dead; - subtables[newlevel].nodelist = subtables[level].nodelist; - index = unique->invperm[level]; - unique->perm[index] = newlevel; - unique->invperm[newlevel] = index; - subtables[newlevel].bindVar = subtables[level].bindVar; - subtables[newlevel].varType = subtables[level].varType; - subtables[newlevel].pairIndex = subtables[level].pairIndex; - subtables[newlevel].varHandled = subtables[level].varHandled; - subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; + if (subtables[level].keys == 0) { + shift++; + continue; + } + newlevel = level - shift; + subtables[newlevel].slots = subtables[level].slots; + subtables[newlevel].shift = subtables[level].shift; + subtables[newlevel].keys = subtables[level].keys; + subtables[newlevel].maxKeys = subtables[level].maxKeys; + subtables[newlevel].dead = subtables[level].dead; + subtables[newlevel].nodelist = subtables[level].nodelist; + index = unique->invperm[level]; + unique->perm[index] = newlevel; + unique->invperm[newlevel] = index; + subtables[newlevel].bindVar = subtables[level].bindVar; + subtables[newlevel].varType = subtables[level].varType; + subtables[newlevel].pairIndex = subtables[level].pairIndex; + subtables[newlevel].varHandled = subtables[level].varHandled; + subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; } /* Destroy the map. If a surviving variable is ** mapped to a dying variable, and the map were used again, ** an out-of-bounds access to unique->vars would result. */ if (unique->map != NULL) { - cuddCacheFlush(unique); - ABC_FREE(unique->map); - unique->map = NULL; + cuddCacheFlush(unique); + ABC_FREE(unique->map); + unique->map = NULL; } unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); @@ -2216,105 +2237,104 @@ cuddResizeTableZdd( int i,j,reorderSave; unsigned int numSlots = unique->initSlots; int *newperm, *newinvperm; - DdNode *one, *zero; oldsize = unique->sizeZ; /* Easy case: there is still room in the current table. */ if (index < unique->maxSizeZ) { - for (i = oldsize; i <= index; i++) { - unique->subtableZ[i].slots = numSlots; - unique->subtableZ[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtableZ[i].keys = 0; - unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtableZ[i].dead = 0; - unique->permZ[i] = i; - unique->invpermZ[i] = i; - newnodelist = unique->subtableZ[i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = NULL; + for (i = oldsize; i <= index; i++) { + unique->subtableZ[i].slots = numSlots; + unique->subtableZ[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtableZ[i].dead = 0; + unique->permZ[i] = i; + unique->invpermZ[i] = i; + newnodelist = unique->subtableZ[i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables up to index included. - */ - newsize = index + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the ZDD table size from %d to %d\n", - unique->maxSizeZ, newsize); + (void) fprintf(unique->err, + "Increasing the ZDD table size from %d to %d\n", + unique->maxSizeZ, newsize); #endif - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - if (newsize > unique->maxSize) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } - for (i = 0; i < oldsize; i++) { - newsubtables[i].slots = unique->subtableZ[i].slots; - newsubtables[i].shift = unique->subtableZ[i].shift; - newsubtables[i].keys = unique->subtableZ[i].keys; - newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; - newsubtables[i].dead = unique->subtableZ[i].dead; - newsubtables[i].nodelist = unique->subtableZ[i].nodelist; - newperm[i] = unique->permZ[i]; - newinvperm[i] = unique->invpermZ[i]; - } - for (i = oldsize; i <= index; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newperm[i] = i; - newinvperm[i] = i; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = NULL; + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - } - ABC_FREE(unique->subtableZ); - unique->subtableZ = newsubtables; - unique->maxSizeZ = newsize; - ABC_FREE(unique->permZ); - unique->permZ = newperm; - ABC_FREE(unique->invpermZ); - unique->invpermZ = newinvperm; + unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSize) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtableZ[i].slots; + newsubtables[i].shift = unique->subtableZ[i].shift; + newsubtables[i].keys = unique->subtableZ[i].keys; + newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; + newsubtables[i].dead = unique->subtableZ[i].dead; + newsubtables[i].nodelist = unique->subtableZ[i].nodelist; + newperm[i] = unique->permZ[i]; + newinvperm[i] = unique->invpermZ[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + ABC_FREE(unique->subtableZ); + unique->subtableZ = newsubtables; + unique->maxSizeZ = newsize; + ABC_FREE(unique->permZ); + unique->permZ = newperm; + ABC_FREE(unique->invpermZ); + unique->invpermZ = newinvperm; } unique->slots += (index + 1 - unique->sizeZ) * numSlots; ddFixLimits(unique); @@ -2324,15 +2344,13 @@ cuddResizeTableZdd( ** universe. We need to temporarily disable reordering, ** because we cannot reorder without universe in place. */ - one = unique->one; - zero = unique->zero; reorderSave = unique->autoDynZ; unique->autoDynZ = 0; cuddZddFreeUniv(unique); if (!cuddZddInitUniv(unique)) { - unique->autoDynZ = reorderSave; - return(0); + unique->autoDynZ = reorderSave; + return(0); } unique->autoDynZ = reorderSave; @@ -2359,16 +2377,16 @@ cuddSlowTableGrowth( int i; unique->maxCacheHard = unique->cacheSlots - 1; - unique->cacheSlack = -(int)(unique->cacheSlots + 1); + unique->cacheSlack = - (int) (unique->cacheSlots + 1); for (i = 0; i < unique->size; i++) { - unique->subtables[i].maxKeys <<= 2; + unique->subtables[i].maxKeys <<= 2; } unique->gcFrac = DD_GC_FRAC_MIN; unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); cuddShrinkDeathRow(unique); (void) fprintf(unique->err,"Slowing down table growth: "); (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"minDead = %u\n", unique->minDead); } /* end of cuddSlowTableGrowth */ @@ -2399,19 +2417,19 @@ ddRehashZdd( int j, pos; DdNodePtr *nodelist, *oldnodelist; DdNode *node, *next; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (unique->slots > unique->looseUpTo) { - unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); #ifdef DD_VERBOSE - if (unique->gcFrac == DD_GC_FRAC_HI) { - (void) fprintf(unique->err,"GC fraction = %.2f\t", - DD_GC_FRAC_LO); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); - } + if (unique->gcFrac == DD_GC_FRAC_HI) { + (void) fprintf(unique->err,"GC fraction = %.2f\t", + DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + } #endif - unique->gcFrac = DD_GC_FRAC_LO; + unique->gcFrac = DD_GC_FRAC_LO; } assert(i != CUDD_MAXINDEX); @@ -2425,8 +2443,8 @@ ddRehashZdd( slots = oldslots; shift = oldshift; do { - slots <<= 1; - shift--; + slots <<= 1; + shift--; } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys); saveHandler = MMoutOfMemory; @@ -2434,40 +2452,39 @@ ddRehashZdd( nodelist = ABC_ALLOC(DdNodePtr, slots); MMoutOfMemory = saveHandler; if (nodelist == NULL) { - int j; - (void) fprintf(unique->err, - "Unable to resize ZDD subtable %d for lack of memory.\n", - i); - (void) cuddGarbageCollectZdd(unique,1); - for (j = 0; j < unique->sizeZ; j++) { - unique->subtableZ[j].maxKeys <<= 1; - } - return; + (void) fprintf(unique->err, + "Unable to resize ZDD subtable %d for lack of memory.\n", + i); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->sizeZ; j++) { + unique->subtableZ[j].maxKeys <<= 1; + } + return; } unique->subtableZ[i].nodelist = nodelist; unique->subtableZ[i].slots = slots; unique->subtableZ[i].shift = shift; unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; + nodelist[j] = NULL; } for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - pos = ddHash(cuddT(node), cuddE(node), shift); - node->next = nodelist[pos]; - nodelist[pos] = node; - node = next; - } + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } } ABC_FREE(oldnodelist); #ifdef DD_VERBOSE (void) fprintf(unique->err, - "rehashing layer %d: keys %d dead %d new size %d\n", - i, unique->subtableZ[i].keys, - unique->subtableZ[i].dead, slots); + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtableZ[i].keys, + unique->subtableZ[i].dead, slots); #endif /* Update global data. */ @@ -2503,176 +2520,175 @@ ddResizeTable( int oldsize,newsize; int i,j,reorderSave; int numSlots = unique->initSlots; - int *newperm, *newinvperm; - int *newmap = NULL; // Suppress "might be used uninitialized" + int *newperm, *newinvperm, *newmap; DdNode *one, *zero; oldsize = unique->size; /* Easy case: there is still room in the current table. */ if (index < unique->maxSize) { - for (i = oldsize; i <= index; i++) { - unique->subtables[i].slots = numSlots; - unique->subtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtables[i].keys = 0; - unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[i].dead = 0; - unique->subtables[i].bindVar = 0; - unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[i].pairIndex = 0; - unique->subtables[i].varHandled = 0; - unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - unique->perm[i] = i; - unique->invperm[i] = i; - newnodelist = unique->subtables[i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - for (j = oldsize; j < i; j++) { - ABC_FREE(unique->subtables[j].nodelist); - } - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (j = 0; j < numSlots; j++) { - newnodelist[j] = sentinel; - } - } - if (unique->map != NULL) { for (i = oldsize; i <= index; i++) { - unique->map[i] = i; + unique->subtables[i].slots = numSlots; + unique->subtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[i].keys = 0; + unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].dead = 0; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[i] = i; + unique->invperm[i] = i; + newnodelist = unique->subtables[i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + for (j = oldsize; j < i; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = oldsize; i <= index; i++) { + unique->map[i] = i; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables up to index included. - */ - newsize = index + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the table size from %d to %d\n", - unique->maxSize, newsize); + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); #endif - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newvars = ABC_ALLOC(DdNodePtr,newsize); - if (newvars == NULL) { - ABC_FREE(newsubtables); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - if (unique->map != NULL) { - newmap = ABC_ALLOC(int,newsize); - if (newmap == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->memused += (newsize - unique->maxSize) * sizeof(int); - } - unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - if (newsize > unique->maxSizeZ) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - if (unique->map != NULL) { - ABC_FREE(newmap); + newvars = ABC_ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + ABC_FREE(newsubtables); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } - for (i = 0; i < oldsize; i++) { - newsubtables[i].slots = unique->subtables[i].slots; - newsubtables[i].shift = unique->subtables[i].shift; - newsubtables[i].keys = unique->subtables[i].keys; - newsubtables[i].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i].dead = unique->subtables[i].dead; - newsubtables[i].nodelist = unique->subtables[i].nodelist; - newsubtables[i].bindVar = unique->subtables[i].bindVar; - newsubtables[i].varType = unique->subtables[i].varType; - newsubtables[i].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i].varHandled = unique->subtables[i].varHandled; - newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - newperm[i] = unique->perm[i]; - newinvperm[i] = unique->invperm[i]; - } - for (i = oldsize; i <= index; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newsubtables[i].bindVar = 0; - newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - newsubtables[i].pairIndex = 0; - newsubtables[i].varHandled = 0; - newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - newperm[i] = i; - newinvperm[i] = i; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - for (j = 0; j < numSlots; j++) { - newnodelist[j] = sentinel; + if (unique->map != NULL) { + newmap = ABC_ALLOC(int,newsize); + if (newmap == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSizeZ) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + if (unique->map != NULL) { + ABC_FREE(newmap); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); } - } - if (unique->map != NULL) { for (i = 0; i < oldsize; i++) { - newmap[i] = unique->map[i]; + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; } for (i = oldsize; i <= index; i++) { - newmap[i] = i; + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } } - ABC_FREE(unique->map); - unique->map = newmap; - } - ABC_FREE(unique->subtables); - unique->subtables = newsubtables; - unique->maxSize = newsize; - ABC_FREE(unique->vars); - unique->vars = newvars; - ABC_FREE(unique->perm); - unique->perm = newperm; - ABC_FREE(unique->invperm); - unique->invperm = newinvperm; + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i <= index; i++) { + newmap[i] = i; + } + ABC_FREE(unique->map); + unique->map = newmap; + } + ABC_FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + ABC_FREE(unique->vars); + unique->vars = newvars; + ABC_FREE(unique->perm); + unique->perm = newperm; + ABC_FREE(unique->invperm); + unique->invperm = newinvperm; } /* Now that the table is in a coherent state, create the new @@ -2689,24 +2705,24 @@ ddResizeTable( reorderSave = unique->autoDyn; unique->autoDyn = 0; for (i = oldsize; i <= index; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) { - unique->autoDyn = reorderSave; - for (j = oldsize; j < i; j++) { - Cudd_IterDerefBdd(unique,unique->vars[j]); - cuddDeallocNode(unique,unique->vars[j]); - unique->vars[j] = NULL; - } - for (j = oldsize; j <= index; j++) { - ABC_FREE(unique->subtables[j].nodelist); - unique->subtables[j].nodelist = NULL; - } - unique->size = oldsize; - unique->slots -= (index + 1 - oldsize) * numSlots; - ddFixLimits(unique); - return(0); - } - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = oldsize; j <= index; j++) { + ABC_FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = NULL; + } + unique->size = oldsize; + unique->slots -= (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + return(0); + } + cuddRef(unique->vars[i]); } unique->autoDyn = reorderSave; @@ -2733,27 +2749,27 @@ cuddFindParent( DdNode * node) { int i,j; - int slots; - DdNodePtr *nodelist; - DdNode *f; + int slots; + DdNodePtr *nodelist; + DdNode *f; for (i = cuddI(table,node->index) - 1; i >= 0; i--) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (cuddT(f) > node) { - f = f->next; - } - while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { - f = f->next; - } - if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { - return(1); + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (cuddT(f) > node) { + f = f->next; + } + while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { + f = f->next; + } + if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { + return(1); + } } } - } return(0); @@ -2780,16 +2796,17 @@ ddFixLimits( { unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); unique->cacheSlack = (int) ddMin(unique->maxCacheHard, - DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - - 2 * (int) unique->cacheSlots; + DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - + 2 * (int) unique->cacheSlots; if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0) - cuddCacheResize(unique); + cuddCacheResize(unique); return; } /* end of ddFixLimits */ #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /**Function******************************************************************** Synopsis [Inserts a DdNode in a red/black search tree.] @@ -2814,13 +2831,13 @@ cuddOrderedInsert( scanP = root; while ((scan = *scanP) != NULL) { - stack[stackN++] = scanP; - if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ - DD_NEXT(node) = DD_NEXT(scan); - DD_NEXT(scan) = node; - return; - } - scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); + stack[stackN++] = scanP; + if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ + DD_NEXT(node) = DD_NEXT(scan); + DD_NEXT(scan) = node; + return; + } + scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); } DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL; DD_COLOR(node) = DD_RED; @@ -2866,42 +2883,42 @@ cuddOrderedThread( *((DdNodePtr *) current) = NULL; while (current != NULL) { - if (DD_RIGHT(current) != NULL) { - /* If possible, we follow the "right" link. Eventually we'll - ** find the node with the largest address in the current tree. - ** In this phase we use the first word of a node to implemen - ** a stack of the nodes on the path from the root to "current". - ** Also, we disconnect the "right" pointers to indicate that - ** we have already followed them. - */ - next = DD_RIGHT(current); - DD_RIGHT(current) = NULL; - *((DdNodePtr *)next) = current; - current = next; - } else { - /* We can't proceed along the "right" links any further. - ** Hence "current" is the largest element in the current tree. - ** We make this node the new head of "list". (Repeating this - ** operation until the tree is empty yields the desired linear - ** threading of all nodes.) - */ - prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ - /* Traverse the linked list of current until the end. */ - for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); - DD_NEXT(end) = list; /* attach "list" at end and make */ - list = current; /* "current" the new head of "list" */ - /* Now, if current has a "left" child, we push it on the stack. - ** Otherwise, we just continue with the parent of "current". - */ - if (DD_LEFT(current) != NULL) { - next = DD_LEFT(current); - *((DdNodePtr *) next) = prev; - current = next; + if (DD_RIGHT(current) != NULL) { + /* If possible, we follow the "right" link. Eventually we'll + ** find the node with the largest address in the current tree. + ** In this phase we use the first word of a node to implemen + ** a stack of the nodes on the path from the root to "current". + ** Also, we disconnect the "right" pointers to indicate that + ** we have already followed them. + */ + next = DD_RIGHT(current); + DD_RIGHT(current) = NULL; + *((DdNodePtr *)next) = current; + current = next; } else { - current = prev; + /* We can't proceed along the "right" links any further. + ** Hence "current" is the largest element in the current tree. + ** We make this node the new head of "list". (Repeating this + ** operation until the tree is empty yields the desired linear + ** threading of all nodes.) + */ + prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ + /* Traverse the linked list of current until the end. */ + for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); + DD_NEXT(end) = list; /* attach "list" at end and make */ + list = current; /* "current" the new head of "list" */ + /* Now, if current has a "left" child, we push it on the stack. + ** Otherwise, we just continue with the parent of "current". + */ + if (DD_LEFT(current) != NULL) { + next = DD_LEFT(current); + *((DdNodePtr *) next) = prev; + current = next; + } else { + current = prev; + } } } - } return(list); @@ -2983,55 +3000,56 @@ cuddDoRebalance( x = *xP; /* Work our way back up, re-balancing the tree. */ while (--stackN >= 0) { - parentP = stack[stackN]; - parent = *parentP; - if (DD_IS_BLACK(parent)) break; - /* Since the root is black, here a non-null grandparent exists. */ - grandpaP = stack[stackN-1]; - grandpa = *grandpaP; - if (parent == DD_LEFT(grandpa)) { - y = DD_RIGHT(grandpa); - if (y != NULL && DD_IS_RED(y)) { - DD_COLOR(parent) = DD_BLACK; - DD_COLOR(y) = DD_BLACK; - DD_COLOR(grandpa) = DD_RED; - x = grandpa; - stackN--; - } else { - if (x == DD_RIGHT(parent)) { - cuddRotateLeft(parentP); - DD_COLOR(x) = DD_BLACK; - } else { - DD_COLOR(parent) = DD_BLACK; - } - DD_COLOR(grandpa) = DD_RED; - cuddRotateRight(grandpaP); - break; - } - } else { - y = DD_LEFT(grandpa); - if (y != NULL && DD_IS_RED(y)) { - DD_COLOR(parent) = DD_BLACK; - DD_COLOR(y) = DD_BLACK; - DD_COLOR(grandpa) = DD_RED; - x = grandpa; - stackN--; - } else { - if (x == DD_LEFT(parent)) { - cuddRotateRight(parentP); - DD_COLOR(x) = DD_BLACK; + parentP = stack[stackN]; + parent = *parentP; + if (DD_IS_BLACK(parent)) break; + /* Since the root is black, here a non-null grandparent exists. */ + grandpaP = stack[stackN-1]; + grandpa = *grandpaP; + if (parent == DD_LEFT(grandpa)) { + y = DD_RIGHT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_RIGHT(parent)) { + cuddRotateLeft(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateRight(grandpaP); + break; + } } else { - DD_COLOR(parent) = DD_BLACK; - } - DD_COLOR(grandpa) = DD_RED; - cuddRotateLeft(grandpaP); + y = DD_LEFT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_LEFT(parent)) { + cuddRotateRight(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateLeft(grandpaP); + } } } - } DD_COLOR(*(stack[0])) = DD_BLACK; } /* end of cuddDoRebalance */ #endif +#endif /**Function******************************************************************** @@ -3055,11 +3073,11 @@ ddPatchTree( MtrNode *auxnode = treenode; while (auxnode != NULL) { - auxnode->low = dd->perm[auxnode->index]; - if (auxnode->child != NULL) { - ddPatchTree(dd, auxnode->child); - } - auxnode = auxnode->younger; + auxnode->low = dd->perm[auxnode->index]; + if (auxnode->child != NULL) { + ddPatchTree(dd, auxnode->child); + } + auxnode = auxnode->younger; } return; @@ -3096,14 +3114,14 @@ cuddCheckCollisionOrdering( if (node == sentinel) return(1); next = node->next; while (next != sentinel) { - if (cuddT(node) < cuddT(next) || - (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { - (void) fprintf(unique->err, - "Unordered list: index %u, position %d\n", i, j); - return(0); - } - node = next; - next = node->next; + if (cuddT(node) < cuddT(next) || + (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { + (void) fprintf(unique->err, + "Unordered list: index %u, position %d\n", i, j); + return(0); + } + node = next; + next = node->next; } return(1); @@ -3128,14 +3146,14 @@ static void ddReportRefMess( DdManager *unique /* manager */, int i /* table in which the problem occurred */, - char *caller /* procedure that detected the problem */) + const char *caller /* procedure that detected the problem */) { if (i == CUDD_CONST_INDEX) { - (void) fprintf(unique->err, - "%s: problem in constants\n", caller); + (void) fprintf(unique->err, + "%s: problem in constants\n", caller); } else if (i != -1) { - (void) fprintf(unique->err, - "%s: problem in table %d\n", caller, i); + (void) fprintf(unique->err, + "%s: problem in table %d\n", caller, i); } (void) fprintf(unique->err, " dead count != deleted\n"); (void) fprintf(unique->err, " This problem is often due to a missing \ @@ -3144,5 +3162,7 @@ See the CUDD Programmer's Guide for additional details."); abort(); } /* end of ddReportRefMess */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddUtil.c b/src/bdd/cudd/cuddUtil.c index cbaafb5a..80577366 100644 --- a/src/bdd/cudd/cuddUtil.c +++ b/src/bdd/cudd/cuddUtil.c @@ -7,72 +7,101 @@ Synopsis [Utility functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_PrintMinterm() - <li> Cudd_PrintDebug() - <li> Cudd_DagSize() - <li> Cudd_EstimateCofactor() - <li> Cudd_EstimateCofactorSimple() - <li> Cudd_SharingSize() - <li> Cudd_CountMinterm() - <li> Cudd_EpdCountMinterm() - <li> Cudd_CountPath() - <li> Cudd_CountPathsToNonZero() - <li> Cudd_Support() - <li> Cudd_SupportIndex() - <li> Cudd_SupportSize() - <li> Cudd_VectorSupport() - <li> Cudd_VectorSupportIndex() - <li> Cudd_VectorSupportSize() - <li> Cudd_ClassifySupport() - <li> Cudd_CountLeaves() - <li> Cudd_bddPickOneCube() - <li> Cudd_bddPickOneMinterm() - <li> Cudd_bddPickArbitraryMinterms() - <li> Cudd_SubsetWithMaskVars() - <li> Cudd_FirstCube() - <li> Cudd_NextCube() - <li> Cudd_bddComputeCube() - <li> Cudd_addComputeCube() - <li> Cudd_FirstNode() - <li> Cudd_NextNode() - <li> Cudd_GenFree() - <li> Cudd_IsGenEmpty() - <li> Cudd_IndicesToCube() - <li> Cudd_PrintVersion() - <li> Cudd_AverageDistance() - <li> Cudd_Random() - <li> Cudd_Srandom() - <li> Cudd_Density() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddP() - <li> cuddStCountfree() - <li> cuddCollectNodes() - </ul> - Static procedures included in this module: - <ul> - <li> dp2() - <li> ddPrintMintermAux() - <li> ddDagInt() - <li> ddCountMintermAux() - <li> ddEpdCountMintermAux() - <li> ddCountPathAux() - <li> ddSupportStep() - <li> ddClearFlag() - <li> ddLeavesInt() - <li> ddPickArbitraryMinterms() - <li> ddPickRepresentativeCube() - <li> ddEpdFree() - </ul>] + <ul> + <li> Cudd_PrintMinterm() + <li> Cudd_bddPrintCover() + <li> Cudd_PrintDebug() + <li> Cudd_DagSize() + <li> Cudd_EstimateCofactor() + <li> Cudd_EstimateCofactorSimple() + <li> Cudd_SharingSize() + <li> Cudd_CountMinterm() + <li> Cudd_EpdCountMinterm() + <li> Cudd_CountPath() + <li> Cudd_CountPathsToNonZero() + <li> Cudd_Support() + <li> Cudd_SupportIndex() + <li> Cudd_SupportSize() + <li> Cudd_VectorSupport() + <li> Cudd_VectorSupportIndex() + <li> Cudd_VectorSupportSize() + <li> Cudd_ClassifySupport() + <li> Cudd_CountLeaves() + <li> Cudd_bddPickOneCube() + <li> Cudd_bddPickOneMinterm() + <li> Cudd_bddPickArbitraryMinterms() + <li> Cudd_SubsetWithMaskVars() + <li> Cudd_FirstCube() + <li> Cudd_NextCube() + <li> Cudd_bddComputeCube() + <li> Cudd_addComputeCube() + <li> Cudd_FirstNode() + <li> Cudd_NextNode() + <li> Cudd_GenFree() + <li> Cudd_IsGenEmpty() + <li> Cudd_IndicesToCube() + <li> Cudd_PrintVersion() + <li> Cudd_AverageDistance() + <li> Cudd_Random() + <li> Cudd_Srandom() + <li> Cudd_Density() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddP() + <li> cuddStCountfree() + <li> cuddCollectNodes() + <li> cuddNodeArray() + </ul> + Static procedures included in this module: + <ul> + <li> dp2() + <li> ddPrintMintermAux() + <li> ddDagInt() + <li> ddCountMintermAux() + <li> ddEpdCountMintermAux() + <li> ddCountPathAux() + <li> ddSupportStep() + <li> ddClearFlag() + <li> ddLeavesInt() + <li> ddPickArbitraryMinterms() + <li> ddPickRepresentativeCube() + <li> ddEpdFree() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -82,6 +111,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -112,21 +142,25 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.81 2009/03/08 02:49:02 fabio Exp $"; #endif -static DdNode *background, *zero; +static DdNode *background, *zero; -static long cuddRand = 0; -static long cuddRand2; -static long shuffleSelect; -static long shuffleTable[STAB_SIZE]; +static long cuddRand = 0; +static long cuddRand2; +static long shuffleSelect; +static long shuffleTable[STAB_SIZE]; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ -#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') +#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') + +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -134,25 +168,29 @@ static long shuffleTable[STAB_SIZE]; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int dp2 ARGS((DdManager *dd, DdNode *f, st_table *t)); -static void ddPrintMintermAux ARGS((DdManager *dd, DdNode *node, int *list)); -static int ddDagInt ARGS((DdNode *n)); -static int cuddEstimateCofactor ARGS((DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr)); -static DdNode * cuddUniqueLookup ARGS((DdManager * unique, int index, DdNode * T, DdNode * E)); -static int cuddEstimateCofactorSimple ARGS((DdNode * node, int i)); -static double ddCountMintermAux ARGS((DdNode *node, double max, DdHashTable *table)); -static int ddEpdCountMintermAux ARGS((DdNode *node, EpDouble *max, EpDouble *epd, st_table *table)); -static double ddCountPathAux ARGS((DdNode *node, st_table *table)); -static double ddCountPathsToNonZero ARGS((DdNode * N, st_table * table)); -static void ddSupportStep ARGS((DdNode *f, int *support)); -static void ddClearFlag ARGS((DdNode *f)); -static int ddLeavesInt ARGS((DdNode *n)); -static int ddPickArbitraryMinterms ARGS((DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)); -static int ddPickRepresentativeCube ARGS((DdManager *dd, DdNode *node, int nvars, double *weight, char *string)); -static enum st_retval ddEpdFree ARGS((char * key, char * value, char * arg)); +static int dp2 (DdManager *dd, DdNode *f, st_table *t); +static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list); +static int ddDagInt (DdNode *n); +static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index); +static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr); +static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E); +static int cuddEstimateCofactorSimple (DdNode * node, int i); +static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table); +static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table); +static double ddCountPathAux (DdNode *node, st_table *table); +static double ddCountPathsToNonZero (DdNode * N, st_table * table); +static void ddSupportStep (DdNode *f, int *support); +static void ddClearFlag (DdNode *f); +static int ddLeavesInt (DdNode *n); +static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string); +static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string); +static enum st_retval ddEpdFree (char * key, char * value, char * arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -179,14 +217,14 @@ Cudd_PrintMinterm( DdManager * manager, DdNode * node) { - int i, *list; + int i, *list; background = manager->background; zero = Cudd_Not(manager->one); list = ABC_ALLOC(int,manager->size); if (list == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(0); + manager->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < manager->size; i++) list[i] = 2; ddPrintMintermAux(manager,node,list); @@ -233,71 +271,71 @@ Cudd_bddPrintCover( cuddRef(cover); #endif while (lb != Cudd_ReadLogicZero(dd)) { - DdNode *implicant, *prime, *tmp; - int length; - implicant = Cudd_LargestCube(dd,lb,&length); - if (implicant == NULL) { - Cudd_RecursiveDeref(dd,lb); - ABC_FREE(array); - return(0); - } - cuddRef(implicant); - prime = Cudd_bddMakePrime(dd,implicant,u); - if (prime == NULL) { - Cudd_RecursiveDeref(dd,lb); + DdNode *implicant, *prime, *tmp; + int length; + implicant = Cudd_LargestCube(dd,lb,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,lb); + ABC_FREE(array); + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,u); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,implicant); + ABC_FREE(array); + return(0); + } + cuddRef(prime); Cudd_RecursiveDeref(dd,implicant); - ABC_FREE(array); - return(0); - } - cuddRef(prime); - Cudd_RecursiveDeref(dd,implicant); - tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,lb); - lb = tmp; - result = Cudd_BddToCubeArray(dd,prime,array); - if (result == 0) { + tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - for (q = 0; q < dd->size; q++) { - switch (array[q]) { - case 0: - (void) fprintf(dd->out, "0"); - break; - case 1: - (void) fprintf(dd->out, "1"); - break; - case 2: - (void) fprintf(dd->out, "-"); - break; - default: - (void) fprintf(dd->out, "?"); + lb = tmp; + result = Cudd_BddToCubeArray(dd,prime,array); + if (result == 0) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); } - } - (void) fprintf(dd->out, " 1\n"); + for (q = 0; q < dd->size; q++) { + switch (array[q]) { + case 0: + (void) fprintf(dd->out, "0"); + break; + case 1: + (void) fprintf(dd->out, "1"); + break; + case 2: + (void) fprintf(dd->out, "-"); + break; + default: + (void) fprintf(dd->out, "?"); + } + } + (void) fprintf(dd->out, " 1\n"); #ifdef DD_DEBUG - tmp = Cudd_bddOr(dd,prime,cover); - if (tmp == NULL) { + tmp = Cudd_bddOr(dd,prime,cover); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cover); + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cover); - Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cover); - cover = tmp; + cover = tmp; #endif - Cudd_RecursiveDeref(dd,prime); + Cudd_RecursiveDeref(dd,prime); } (void) fprintf(dd->out, "\n"); Cudd_RecursiveDeref(dd,lb); @@ -348,15 +386,15 @@ Cudd_PrintDebug( int pr) { DdNode *azero, *bzero; - int nodes; - int leaves; + int nodes; + int leaves; double minterms; int retval = 1; if (f == NULL) { - (void) fprintf(dd->out,": is the NULL DD\n"); - (void) fflush(dd->out); - return(0); + (void) fprintf(dd->out,": is the NULL DD\n"); + (void) fflush(dd->out); + return(0); } azero = DD_ZERO(dd); bzero = Cudd_Not(DD_ONE(dd)); @@ -366,21 +404,21 @@ Cudd_PrintDebug( return(1); } if (pr > 0) { - nodes = Cudd_DagSize(f); - if (nodes == CUDD_OUT_OF_MEM) retval = 0; - leaves = Cudd_CountLeaves(f); - if (leaves == CUDD_OUT_OF_MEM) retval = 0; - minterms = Cudd_CountMinterm(dd, f, n); - if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; - (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", - nodes, leaves, minterms); + nodes = Cudd_DagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + leaves = Cudd_CountLeaves(f); + if (leaves == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_CountMinterm(dd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", + nodes, leaves, minterms); if (pr > 2) { - if (!cuddP(dd, f)) retval = 0; - } - if (pr == 2 || pr > 3) { - if (!Cudd_PrintMinterm(dd,f)) retval = 0; - (void) fprintf(dd->out,"\n"); - } + if (!cuddP(dd, f)) retval = 0; + } + if (pr == 2 || pr > 3) { + if (!Cudd_PrintMinterm(dd,f)) retval = 0; + (void) fprintf(dd->out,"\n"); + } (void) fflush(dd->out); } return(retval); @@ -404,7 +442,7 @@ int Cudd_DagSize( DdNode * node) { - int i; + int i; i = ddDagInt(Cudd_Regular(node)); ddClearFlag(Cudd_Regular(node)); @@ -426,7 +464,7 @@ Cudd_DagSize( (ICCAD96). The refinement allows the procedure to account for part of the recombination that may occur in the part of the cofactor above the cofactoring variable. This procedure does no create any new node. - It does keep a small table of results; therefore itmay run out of memory. + It does keep a small table of results; therefore it may run out of memory. If this is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, does not allocate any memory, but is less accurate.] @@ -439,15 +477,15 @@ int Cudd_EstimateCofactor( DdManager *dd /* manager */, DdNode * f /* function */, - int i /* index of variable */, - int phase /* 1: positive; 0: negative */ + int i /* index of variable */, + int phase /* 1: positive; 0: negative */ ) { - int val; + int val; DdNode *ptr; st_table *table; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) return(CUDD_OUT_OF_MEM); val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); ddClearFlag(Cudd_Regular(f)); @@ -480,7 +518,7 @@ Cudd_EstimateCofactorSimple( DdNode * node, int i) { - int val; + int val; val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); ddClearFlag(Cudd_Regular(node)); @@ -507,14 +545,14 @@ Cudd_SharingSize( DdNode ** nodeArray, int n) { - int i,j; + int i,j; i = 0; for (j = 0; j < n; j++) { - i += ddDagInt(Cudd_Regular(nodeArray[j])); + i += ddDagInt(Cudd_Regular(nodeArray[j])); } for (j = 0; j < n; j++) { - ddClearFlag(Cudd_Regular(nodeArray[j])); + ddClearFlag(Cudd_Regular(nodeArray[j])); } return(i); @@ -542,18 +580,18 @@ Cudd_CountMinterm( DdNode * node, int nvars) { - double max; - DdHashTable *table; - double res; + double max; + DdHashTable *table; + double res; CUDD_VALUE_TYPE epsilon; background = manager->background; zero = Cudd_Not(manager->one); - + max = pow(2.0,(double)nvars); table = cuddHashTableInit(manager,1,2); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } epsilon = Cudd_ReadEpsilon(manager); Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); @@ -587,14 +625,14 @@ Cudd_CountPath( { st_table *table; - double i; + double i; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } i = ddCountPathAux(Cudd_Regular(node),table); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); return(i); @@ -624,23 +662,23 @@ Cudd_EpdCountMinterm( { EpDouble max, tmp; st_table *table; - int status; + int status; background = manager->background; zero = Cudd_Not(manager->one); - + EpdPow2(nvars, &max); table = st_init_table(EpdCmp, st_ptrhash); if (table == NULL) { - EpdMakeZero(epd, 0); - return(CUDD_OUT_OF_MEM); + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); } status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); - st_foreach(table, (ST_PFSR)ddEpdFree, NULL); + st_foreach(table, ddEpdFree, NULL); st_free_table(table); if (status == CUDD_OUT_OF_MEM) { - EpdMakeZero(epd, 0); - return(CUDD_OUT_OF_MEM); + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); } if (Cudd_IsComplement(node)) { EpdSubtract3(&max, epd, &tmp); @@ -671,14 +709,14 @@ Cudd_CountPathsToNonZero( { st_table *table; - double i; + double i; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } i = ddCountPathsToNonZero(node,table); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); return(i); @@ -703,20 +741,20 @@ Cudd_Support( DdManager * dd /* manager */, DdNode * f /* DD whose support is sought */) { - int *support; + int *support; DdNode *res, *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -725,27 +763,30 @@ Cudd_Support( /* Transform support from array to cube. */ do { - dd->reordered = 0; - res = DD_ONE(dd); - cuddRef(res); - for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (support[i] == 1) { - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - tmp = cuddBddAndRecur(dd,res,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = NULL; - break; - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = tmp; + dd->reordered = 0; + res = DD_ONE(dd); + cuddRef(res); + for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + /* The following call to cuddUniqueInter is guaranteed + ** not to trigger reordering because the node we look up + ** already exists. */ + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = cuddBddAndRecur(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = NULL; + break; + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; + } } - } } while (dd->reordered == 1); ABC_FREE(support); @@ -759,8 +800,11 @@ Cudd_Support( Synopsis [Finds the variables on which a DD depends.] - Description [Finds the variables on which a DD depends. - Returns an index array of the variables if successful; NULL otherwise.] + Description [Finds the variables on which a DD depends. Returns an + index array of the variables if successful; NULL otherwise. The + size of the array equals the number of variables in the manager. + Each entry of the array is 1 if the corresponding variable is in the + support of the DD and 0 otherwise.] SideEffects [None] @@ -772,19 +816,19 @@ Cudd_SupportIndex( DdManager * dd /* manager */, DdNode * f /* DD whose support is sought */) { - int *support; - int i; + int *support; + int i; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -814,8 +858,8 @@ Cudd_SupportSize( DdManager * dd /* manager */, DdNode * f /* DD whose support size is sought */) { - int *support; - int i; + int *support; + int i; int size; int count; @@ -823,11 +867,11 @@ Cudd_SupportSize( size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -837,7 +881,7 @@ Cudd_SupportSize( /* Count support variables. */ count = 0; for (i = 0; i < size; i++) { - if (support[i] == 1) count++; + if (support[i] == 1) count++; } ABC_FREE(support); @@ -866,50 +910,50 @@ Cudd_VectorSupport( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; + int *support; DdNode *res, *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } /* Transform support from array to cube. */ res = DD_ONE(dd); cuddRef(res); for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (support[i] == 1) { - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - tmp = Cudd_bddAnd(dd,res,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(support); - return(NULL); + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = tmp; - } } ABC_FREE(support); @@ -938,27 +982,27 @@ Cudd_VectorSupportIndex( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; - int i; + int *support; + int i; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } return(support); @@ -986,8 +1030,8 @@ Cudd_VectorSupportSize( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; - int i; + int *support; + int i; int size; int count; @@ -995,25 +1039,25 @@ Cudd_VectorSupportSize( size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } /* Count vriables in support. */ count = 0; for (i = 0; i < size; i++) { - if (support[i] == 1) count++; + if (support[i] == 1) count++; } ABC_FREE(support); @@ -1046,27 +1090,27 @@ Cudd_ClassifySupport( DdNode ** onlyF /* cube of variables only in f */, DdNode ** onlyG /* cube of variables only in g */) { - int *supportF, *supportG; + int *supportF, *supportG; DdNode *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support arrays for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); supportF = ABC_ALLOC(int,size); if (supportF == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } supportG = ABC_ALLOC(int,size); if (supportG == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(supportF); - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(supportF); + return(0); } for (i = 0; i < size; i++) { - supportF[i] = 0; - supportG[i] = 0; + supportF[i] = 0; + supportG[i] = 0; } /* Compute supports and clean up markers. */ @@ -1079,51 +1123,51 @@ Cudd_ClassifySupport( *common = *onlyF = *onlyG = DD_ONE(dd); cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (supportF[i] == 0 && supportG[i] == 0) continue; - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - if (supportG[i] == 0) { - tmp = Cudd_bddAnd(dd,*onlyF,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*onlyF); - *onlyF = tmp; - } else if (supportF[i] == 0) { - tmp = Cudd_bddAnd(dd,*onlyG,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); + i = (j >= dd->size) ? j : dd->invperm[j]; + if (supportF[i] == 0 && supportG[i] == 0) continue; + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + if (supportG[i] == 0) { + tmp = Cudd_bddAnd(dd,*onlyF,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyF); + *onlyF = tmp; + } else if (supportF[i] == 0) { + tmp = Cudd_bddAnd(dd,*onlyG,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyG); + *onlyG = tmp; + } else { + tmp = Cudd_bddAnd(dd,*common,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*common); + *common = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*onlyG); - *onlyG = tmp; - } else { - tmp = Cudd_bddAnd(dd,*common,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*common); - *common = tmp; - } - Cudd_RecursiveDeref(dd,var); } ABC_FREE(supportF); ABC_FREE(supportG); @@ -1150,7 +1194,7 @@ int Cudd_CountLeaves( DdNode * node) { - int i; + int i; i = ddLeavesInt(Cudd_Regular(node)); ddClearFlag(Cudd_Regular(node)); @@ -1195,25 +1239,25 @@ Cudd_bddPickOneCube( for (;;) { - if (node == one) break; + if (node == one) break; - N = Cudd_Regular(node); + N = Cudd_Regular(node); - T = cuddT(N); E = cuddE(N); - if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); E = Cudd_Not(E); - } - if (T == bzero) { - string[N->index] = 0; - node = E; - } else if (E == bzero) { - string[N->index] = 1; - node = T; - } else { - dir = (char) ((Cudd_Random() & 0x2000) >> 13); - string[N->index] = dir; - node = dir ? T : E; - } + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + if (T == bzero) { + string[N->index] = 0; + node = E; + } else if (E == bzero) { + string[N->index] = 1; + node = T; + } else { + dir = (char) ((Cudd_Random() & 0x2000) >> 13); + string[N->index] = dir; + node = dir ? T : E; + } } return(1); @@ -1259,14 +1303,14 @@ Cudd_bddPickOneMinterm( size = dd->size; string = ABC_ALLOC(char, size); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } indices = ABC_ALLOC(int,n); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(string); + return(NULL); } for (i = 0; i < n; i++) { @@ -1275,15 +1319,15 @@ Cudd_bddPickOneMinterm( result = Cudd_bddPickOneCube(dd,f,string); if (result == 0) { - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } /* Randomize choice for don't cares. */ for (i = 0; i < n; i++) { - if (string[indices[i]] == 2) - string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); + if (string[indices[i]] == 2) + string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); } /* Build result BDD. */ @@ -1291,25 +1335,25 @@ Cudd_bddPickOneMinterm( cuddRef(old); for (i = n-1; i >= 0; i--) { - neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); - if (neW == NULL) { - ABC_FREE(string); - ABC_FREE(indices); + neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); + if (neW == NULL) { + ABC_FREE(string); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,old); + return(NULL); + } + cuddRef(neW); Cudd_RecursiveDeref(dd,old); - return(NULL); - } - cuddRef(neW); - Cudd_RecursiveDeref(dd,old); - old = neW; + old = neW; } #ifdef DD_DEBUG /* Test. */ if (Cudd_bddLeq(dd,old,f)) { - cuddDeref(old); + cuddDeref(old); } else { - Cudd_RecursiveDeref(dd,old); - old = NULL; + Cudd_RecursiveDeref(dd,old); + old = NULL; } #else cuddDeref(old); @@ -1360,39 +1404,38 @@ Cudd_bddPickArbitraryMinterms( DdNode **old, *neW; double minterms; char *saveString; - int saveFlag, isSame; - int savePoint = 0; // Suppress "might be used uninitialized" + int saveFlag, savePoint, isSame; minterms = Cudd_CountMinterm(dd,f,n); if ((double)k > minterms) { - return(NULL); + return(NULL); } size = dd->size; string = ABC_ALLOC(char *, k); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < k; i++) { - string[i] = ABC_ALLOC(char, size + 1); - if (string[i] == NULL) { - for (j = 0; j < i; j++) - ABC_FREE(string[i]); - ABC_FREE(string); dd->errorCode = CUDD_MEMORY_OUT; return(NULL); } - for (j = 0; j < size; j++) string[i][j] = '2'; - string[i][size] = '\0'; + for (i = 0; i < k; i++) { + string[i] = ABC_ALLOC(char, size + 1); + if (string[i] == NULL) { + for (j = 0; j < i; j++) + ABC_FREE(string[i]); + ABC_FREE(string); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (j = 0; j < size; j++) string[i][j] = '2'; + string[i][size] = '\0'; } indices = ABC_ALLOC(int,n); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + return(NULL); } for (i = 0; i < n; i++) { @@ -1401,129 +1444,130 @@ Cudd_bddPickArbitraryMinterms( result = ddPickArbitraryMinterms(dd,f,n,k,string); if (result == 0) { - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } old = ABC_ALLOC(DdNode *, k); if (old == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } saveString = ABC_ALLOC(char, size + 1); if (saveString == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - ABC_FREE(old); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + ABC_FREE(old); + return(NULL); } saveFlag = 0; /* Build result BDD array. */ for (i = 0; i < k; i++) { - isSame = 0; - if (!saveFlag) { - for (j = i + 1; j < k; j++) { - if (strcmp(string[i], string[j]) == 0) { - savePoint = i; - strcpy(saveString, string[i]); - saveFlag = 1; - break; - } - } - } else { - if (strcmp(string[i], saveString) == 0) { - isSame = 1; + isSame = 0; + if (!saveFlag) { + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } } else { - saveFlag = 0; - for (j = i + 1; j < k; j++) { - if (strcmp(string[i], string[j]) == 0) { - savePoint = i; - strcpy(saveString, string[i]); - saveFlag = 1; - break; + if (strcmp(string[i], saveString) == 0) { + isSame = 1; + } else { + saveFlag = 0; + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } } } - } - } - /* Randomize choice for don't cares. */ - for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '2') - string[i][indices[j]] = (Cudd_Random() & 0x20) ? '1' : '0'; - } - - while (isSame) { - isSame = 0; - for (j = savePoint; j < i; j++) { - if (strcmp(string[i], string[j]) == 0) { - isSame = 1; - break; - } - } - if (isSame) { - strcpy(string[i], saveString); /* Randomize choice for don't cares. */ for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '2') - string[i][indices[j]] = (Cudd_Random() & 0x20) ? - '1' : '0'; + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); } + + while (isSame) { + isSame = 0; + for (j = savePoint; j < i; j++) { + if (strcmp(string[i], string[j]) == 0) { + isSame = 1; + break; + } + } + if (isSame) { + strcpy(string[i], saveString); + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + } } - } - old[i] = Cudd_ReadOne(dd); - cuddRef(old[i]); + old[i] = Cudd_ReadOne(dd); + cuddRef(old[i]); - for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '0') { - neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); - } else { - neW = Cudd_bddAnd(dd,old[i],vars[j]); - } - if (neW == NULL) { - ABC_FREE(saveString); - for (l = 0; l < k; l++) - ABC_FREE(string[l]); - ABC_FREE(string); - ABC_FREE(indices); - for (l = 0; l <= i; l++) - Cudd_RecursiveDeref(dd,old[l]); - ABC_FREE(old); - return(NULL); + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '0') { + neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); + } else { + neW = Cudd_bddAnd(dd,old[i],vars[j]); + } + if (neW == NULL) { + ABC_FREE(saveString); + for (l = 0; l < k; l++) + ABC_FREE(string[l]); + ABC_FREE(string); + ABC_FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + ABC_FREE(old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old[i]); + old[i] = neW; } - cuddRef(neW); - Cudd_RecursiveDeref(dd,old[i]); - old[i] = neW; - } - /* Test. */ - if (!Cudd_bddLeq(dd,old[i],f)) { - ABC_FREE(saveString); - for (l = 0; l < k; l++) - ABC_FREE(string[l]); - ABC_FREE(string); - ABC_FREE(indices); - for (l = 0; l <= i; l++) - Cudd_RecursiveDeref(dd,old[l]); - ABC_FREE(old); - return(NULL); - } + /* Test. */ + if (!Cudd_bddLeq(dd,old[i],f)) { + ABC_FREE(saveString); + for (l = 0; l < k; l++) + ABC_FREE(string[l]); + ABC_FREE(string); + ABC_FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + ABC_FREE(old); + return(NULL); + } } ABC_FREE(saveString); for (i = 0; i < k; i++) { - cuddDeref(old[i]); - ABC_FREE(string[i]); + cuddDeref(old[i]); + ABC_FREE(string[i]); } ABC_FREE(string); ABC_FREE(indices); @@ -1563,114 +1607,119 @@ Cudd_SubsetWithMaskVars( DdNode ** maskVars /* array of variables */, int mvars /* size of <code>maskVars</code> */) { - double *weight; - char *string; - int i, size; - int *indices, *mask; - int result; - DdNode *zero, *cube, *newCube, *subset; - DdNode *cof; - - DdNode *support; + double *weight; + char *string; + int i, size; + int *indices, *mask; + int result; + DdNode *zero, *cube, *newCube, *subset; + DdNode *cof; + + DdNode *support; support = Cudd_Support(dd,f); cuddRef(support); Cudd_RecursiveDeref(dd,support); zero = Cudd_Not(dd->one); size = dd->size; - + weight = ABC_ALLOC(double,size); if (weight == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { weight[i] = 0.0; } for (i = 0; i < mvars; i++) { - cof = Cudd_Cofactor(dd, f, maskVars[i]); - cuddRef(cof); - weight[i] = Cudd_CountMinterm(dd, cof, nvars); - Cudd_RecursiveDeref(dd,cof); + cof = Cudd_Cofactor(dd, f, maskVars[i]); + cuddRef(cof); + weight[i] = Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); - cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); - cuddRef(cof); - weight[i] -= Cudd_CountMinterm(dd, cof, nvars); - Cudd_RecursiveDeref(dd,cof); + cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); + cuddRef(cof); + weight[i] -= Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); } string = ABC_ALLOC(char, size + 1); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + return(NULL); } mask = ABC_ALLOC(int, size); if (mask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + ABC_FREE(string); + return(NULL); } for (i = 0; i < size; i++) { - string[i] = '2'; - mask[i] = 0; + string[i] = '2'; + mask[i] = 0; } string[size] = '\0'; indices = ABC_ALLOC(int,nvars); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - ABC_FREE(mask); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + return(NULL); } for (i = 0; i < nvars; i++) { indices[i] = vars[i]->index; } - result = ddPickRepresentativeCube(dd,f,nvars,weight,string); + result = ddPickRepresentativeCube(dd,f,weight,string); if (result == 0) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); - return(NULL); + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + return(NULL); } cube = Cudd_ReadOne(dd); cuddRef(cube); zero = Cudd_Not(Cudd_ReadOne(dd)); for (i = 0; i < nvars; i++) { - if (string[indices[i]] == '0') { - newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); - } else if (string[indices[i]] == '1') { - newCube = Cudd_bddIte(dd,cube,vars[i],zero); - } else - continue; - if (newCube == NULL) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(newCube); - Cudd_RecursiveDeref(dd,cube); - cube = newCube; + cube = newCube; } Cudd_RecursiveDeref(dd,cube); for (i = 0; i < mvars; i++) { - mask[maskVars[i]->index] = 1; + mask[maskVars[i]->index] = 1; } for (i = 0; i < nvars; i++) { - if (mask[indices[i]]) { - if (string[indices[i]] == '2') { - if (weight[indices[i]] >= 0.0) - string[indices[i]] = '1'; - else - string[indices[i]] = '0'; + if (mask[indices[i]]) { + if (string[indices[i]] == '2') { + if (weight[indices[i]] >= 0.0) + string[indices[i]] = '1'; + else + string[indices[i]] = '0'; + } + } else { + string[indices[i]] = '2'; } - } else { - string[indices[i]] = '2'; - } } cube = Cudd_ReadOne(dd); @@ -1679,22 +1728,23 @@ Cudd_SubsetWithMaskVars( /* Build result BDD. */ for (i = 0; i < nvars; i++) { - if (string[indices[i]] == '0') { - newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); - } else if (string[indices[i]] == '1') { - newCube = Cudd_bddIte(dd,cube,vars[i],zero); - } else - continue; - if (newCube == NULL) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(newCube); - Cudd_RecursiveDeref(dd,cube); - cube = newCube; + cube = newCube; } subset = Cudd_bddAnd(dd,f,cube); @@ -1703,16 +1753,16 @@ Cudd_SubsetWithMaskVars( /* Test. */ if (Cudd_bddLeq(dd,subset,f)) { - cuddDeref(subset); + cuddDeref(subset); } else { - Cudd_RecursiveDeref(dd,subset); - subset = NULL; + Cudd_RecursiveDeref(dd,subset); + subset = NULL; } + ABC_FREE(weight); ABC_FREE(string); ABC_FREE(mask); ABC_FREE(indices); - ABC_FREE(weight); return(subset); } /* end of Cudd_SubsetWithMaskVars */ @@ -1762,8 +1812,8 @@ Cudd_FirstCube( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = dd; @@ -1778,9 +1828,9 @@ Cudd_FirstCube( nvars = dd->size; gen->gen.cubes.cube = ABC_ALLOC(int,nvars); if (gen->gen.cubes.cube == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); } for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; @@ -1788,12 +1838,12 @@ Cudd_FirstCube( ** because a path may have nodes at all levels, including the ** constant level. */ - gen->stack.stack = ABC_ALLOC(DdNode *, nvars+1); + gen->stack.stack = ABC_ALLOC(DdNodePtr, nvars+1); if (gen->stack.stack == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen); + return(NULL); } for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; @@ -1801,43 +1851,43 @@ Cudd_FirstCube( gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - if (!cuddIsConstant(treg)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[treg->index] = 0; - next = cuddE(treg); - if (top != treg) next = Cudd_Not(next); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { - /* Backtrack */ - while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - prev = gen->stack.stack[gen->stack.sp-2]; - preg = Cudd_Regular(prev); - nreg = cuddT(preg); - if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[preg->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[preg->index] = 2; - gen->stack.sp--; top = gen->stack.stack[gen->stack.sp-1]; treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -1874,46 +1924,14 @@ Cudd_NextCube( /* Backtrack from previously reached terminal node. */ while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - prev = gen->stack.stack[gen->stack.sp-2]; - preg = Cudd_Regular(prev); - nreg = cuddT(preg); - if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[preg->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[preg->index] = 2; - gen->stack.sp--; - } - - while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - if (!cuddIsConstant(treg)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[treg->index] = 0; - next = cuddE(treg); - if (top != treg) next = Cudd_Not(next); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { - /* Backtrack */ - while (1) { if (gen->stack.sp == 1) { /* The current node has no predecessor. */ gen->status = CUDD_GEN_EMPTY; gen->stack.sp--; goto done; } + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); prev = gen->stack.stack[gen->stack.sp-2]; preg = Cudd_Regular(prev); nreg = cuddT(preg); @@ -1926,14 +1944,46 @@ Cudd_NextCube( /* Pop the stack and try again. */ gen->gen.cubes.cube[preg->index] = 2; gen->stack.sp--; + } + + while (1) { top = gen->stack.stack[gen->stack.sp-1]; treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -1947,6 +1997,188 @@ done: /**Function******************************************************************** + Synopsis [Finds the first prime of a Boolean function.] + + Description [Defines an iterator on a pair of BDDs describing a + (possibly incompletely specified) Boolean functions and finds the + first cube of a cover of the function. Returns a generator + that contains the information necessary to continue the enumeration + if successful; NULL otherwise.<p> + + The two argument BDDs are the lower and upper bounds of an interval. + It is a mistake to call this function with a lower bound that is not + less than or equal to the upper bound.<p> + + A cube is represented as an array of literals, which are integers in + {0, 1, 2}; 0 represents a complemented literal, 1 represents an + uncomplemented literal, and 2 stands for don't care. The enumeration + produces a prime and irredundant cover of the function associated + with the two BDDs. The size of the array equals the number of + variables in the manager at the time Cudd_FirstCube is called.<p> + + This iterator can only be used on BDDs.] + + SideEffects [The first cube is returned as side effect.] + + SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_FirstCube Cudd_FirstNode] + +******************************************************************************/ +DdGen * +Cudd_FirstPrime( + DdManager *dd, + DdNode *l, + DdNode *u, + int **cube) +{ + DdGen *gen; + DdNode *implicant, *prime, *tmp; + int length, result; + + /* Sanity Check. */ + if (dd == NULL || l == NULL || u == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ABC_ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_PRIMES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.primes.cube = NULL; + gen->gen.primes.ub = u; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = l; + cuddRef(l); + + gen->gen.primes.cube = ABC_ALLOC(int,dd->size); + if (gen->gen.primes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); + } + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,implicant); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + *cube = gen->gen.primes.cube; + return(gen); + +} /* end of Cudd_FirstPrime */ + + +/**Function******************************************************************** + + Synopsis [Generates the next prime of a Boolean function.] + + Description [Generates the next cube of a Boolean function, + using generator gen. Returns 0 if the enumeration is completed; 1 + otherwise.] + + SideEffects [The cube and is returned as side effects. The + generator is modified.] + + SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty + Cudd_NextCube Cudd_NextNode] + +******************************************************************************/ +int +Cudd_NextPrime( + DdGen *gen, + int **cube) +{ + DdNode *implicant, *prime, *tmp; + DdManager *dd = gen->manager; + int length, result; + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,implicant); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.primes.cube; + return(1); + +} /* end of Cudd_NextPrime */ + + +/**Function******************************************************************** + Synopsis [Computes the cube of an array of BDD variables.] Description [Computes the cube of an array of BDD variables. If @@ -1967,26 +2199,26 @@ Cudd_bddComputeCube( int * phase, int n) { - DdNode *cube; - DdNode *fn; + DdNode *cube; + DdNode *fn; int i; cube = DD_ONE(dd); cuddRef(cube); for (i = n - 1; i >= 0; i--) { - if (phase == NULL || phase[i] != 0) { - fn = Cudd_bddAnd(dd,vars[i],cube); - } else { - fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); - } - if (fn == NULL) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_bddAnd(dd,vars[i],cube); + } else { + fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(fn); - Cudd_RecursiveDeref(dd,cube); - cube = fn; + cube = fn; } cuddDeref(cube); @@ -2017,8 +2249,8 @@ Cudd_addComputeCube( int * phase, int n) { - DdNode *cube, *zero; - DdNode *fn; + DdNode *cube, *zero; + DdNode *fn; int i; cube = DD_ONE(dd); @@ -2026,18 +2258,18 @@ Cudd_addComputeCube( zero = DD_ZERO(dd); for (i = n - 1; i >= 0; i--) { - if (phase == NULL || phase[i] != 0) { - fn = Cudd_addIte(dd,vars[i],cube,zero); - } else { - fn = Cudd_addIte(dd,vars[i],zero,cube); - } - if (fn == NULL) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_addIte(dd,vars[i],cube,zero); + } else { + fn = Cudd_addIte(dd,vars[i],zero,cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(fn); - Cudd_RecursiveDeref(dd,cube); - cube = fn; + cube = fn; } cuddDeref(cube); @@ -2074,17 +2306,17 @@ Cudd_CubeArrayToBdd( cube = DD_ONE(dd); cuddRef(cube); for (i = size - 1; i >= 0; i--) { - if ((array[i] & ~1) == 0) { - var = Cudd_bddIthVar(dd,i); - tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,cube); - return(NULL); + if ((array[i] & ~1) == 0) { + var = Cudd_bddIthVar(dd,i); + tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; - } } cuddDeref(cube); return(cube); @@ -2122,26 +2354,26 @@ Cudd_BddToCubeArray( DdNode *zero = Cudd_Not(DD_ONE(dd)); for (i = size-1; i >= 0; i--) { - array[i] = 2; + array[i] = 2; } scan = cube; while (!Cudd_IsConstant(scan)) { - int index = Cudd_Regular(scan)->index; - cuddGetBranches(scan,&t,&e); - if (t == zero) { - array[index] = 0; - scan = e; - } else if (e == zero) { - array[index] = 1; - scan = t; - } else { - return(0); /* cube is not a cube */ - } + int index = Cudd_Regular(scan)->index; + cuddGetBranches(scan,&t,&e); + if (t == zero) { + array[index] = 0; + scan = e; + } else if (e == zero) { + array[index] = 1; + scan = t; + } else { + return(0); /* cube is not a cube */ + } } if (scan == zero) { - return(0); + return(0); } else { - return(1); + return(1); } } /* end of Cudd_BddToCubeArray */ @@ -2153,8 +2385,10 @@ Cudd_BddToCubeArray( Description [Defines an iterator on the nodes of a decision diagram and finds its first node. Returns a generator that contains the - information necessary to continue the enumeration if successful; NULL - otherwise.] + information necessary to continue the enumeration if successful; + NULL otherwise. The nodes are enumerated in a reverse topological + order, so that a node is always preceded in the enumeration by its + descendants.] SideEffects [The first node is returned as a side effect.] @@ -2169,7 +2403,7 @@ Cudd_FirstNode( DdNode ** node) { DdGen *gen; - int retval; + int size; /* Sanity Check. */ if (dd == NULL || f == NULL) return(NULL); @@ -2177,46 +2411,30 @@ Cudd_FirstNode( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = dd; gen->type = CUDD_GEN_NODES; gen->status = CUDD_GEN_EMPTY; - gen->gen.nodes.visited = NULL; - gen->gen.nodes.stGen = NULL; gen->stack.sp = 0; - gen->stack.stack = NULL; gen->node = NULL; - gen->gen.nodes.visited = st_init_table(st_ptrcmp, st_ptrhash);; - if (gen->gen.nodes.visited == NULL) { - ABC_FREE(gen); - return(NULL); - } - - /* Collect all the nodes in a st table for later perusal. */ - retval = cuddCollectNodes(Cudd_Regular(f),gen->gen.nodes.visited); - if (retval == 0) { - st_free_table(gen->gen.nodes.visited); - ABC_FREE(gen); - return(NULL); - } - - /* Initialize the st table generator. */ - gen->gen.nodes.stGen = st_init_gen(gen->gen.nodes.visited); - if (gen->gen.nodes.stGen == NULL) { - st_free_table(gen->gen.nodes.visited); - ABC_FREE(gen); - return(NULL); + /* Collect all the nodes on the generator stack for later perusal. */ + gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); + if (gen->stack.stack == NULL) { + ABC_FREE(gen); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } + gen->gen.nodes.size = size; /* Find the first node. */ - retval = st_gen(gen->gen.nodes.stGen, (const char **) &(gen->node), NULL); - if (retval != 0) { - gen->status = CUDD_GEN_NONEMPTY; - *node = gen->node; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->status = CUDD_GEN_NONEMPTY; + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; } return(gen); @@ -2242,18 +2460,17 @@ Cudd_NextNode( DdGen * gen, DdNode ** node) { - int retval; - /* Find the next node. */ - retval = st_gen(gen->gen.nodes.stGen, (const char **) &(gen->node), NULL); - if (retval == 0) { - gen->status = CUDD_GEN_EMPTY; + gen->stack.sp++; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + return(1); } else { - *node = gen->node; + gen->status = CUDD_GEN_EMPTY; + return(0); } - return(retval); - } /* end of Cudd_NextNode */ @@ -2274,20 +2491,22 @@ int Cudd_GenFree( DdGen * gen) { - if (gen == NULL) return(0); switch (gen->type) { case CUDD_GEN_CUBES: case CUDD_GEN_ZDD_PATHS: - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen->stack.stack); - break; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen->stack.stack); + break; + case CUDD_GEN_PRIMES: + ABC_FREE(gen->gen.primes.cube); + Cudd_RecursiveDeref(gen->manager,gen->node); + break; case CUDD_GEN_NODES: - st_free_gen(gen->gen.nodes.stGen); - st_free_table(gen->gen.nodes.visited); - break; + ABC_FREE(gen->stack.stack); + break; default: - return(0); + return(0); } ABC_FREE(gen); return(0); @@ -2342,14 +2561,14 @@ Cudd_IndicesToCube( cube = DD_ONE(dd); cuddRef(cube); for (i = n - 1; i >= 0; i--) { - tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); - if (tmp == NULL) { + tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; + cube = tmp; } cuddDeref(cube); @@ -2416,28 +2635,28 @@ Cudd_AverageDistance( /* Scan the variable subtables. */ for (i = 0; i < nvars; i++) { - nodelist = dd->subtables[i].nodelist; - tesubtotal = 0.0; - nextsubtotal = 0.0; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != sentinel) { - diff = (long) scan - (long) cuddT(scan); - tesubtotal += (double) ddAbs(diff); - diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); - tesubtotal += (double) ddAbs(diff); - temeasured += 2.0; - if (scan->next != NULL) { - diff = (long) scan - (long) scan->next; - nextsubtotal += (double) ddAbs(diff); - nextmeasured += 1.0; - } - scan = scan->next; + nodelist = dd->subtables[i].nodelist; + tesubtotal = 0.0; + nextsubtotal = 0.0; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != sentinel) { + diff = (long) scan - (long) cuddT(scan); + tesubtotal += (double) ddAbs(diff); + diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); + tesubtotal += (double) ddAbs(diff); + temeasured += 2.0; + if (scan->next != sentinel) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } } - } - tetotal += tesubtotal; - nexttotal += nextsubtotal; + tetotal += tesubtotal; + nexttotal += nextsubtotal; } /* Scan the constant table. */ @@ -2445,15 +2664,15 @@ Cudd_AverageDistance( nextsubtotal = 0.0; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (scan->next != NULL) { - diff = (long) scan - (long) scan->next; - nextsubtotal += (double) ddAbs(diff); - nextmeasured += 1.0; + scan = nodelist[j]; + while (scan != NULL) { + if (scan->next != NULL) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; } - scan = scan->next; - } } nexttotal += nextsubtotal; @@ -2480,10 +2699,9 @@ Cudd_AverageDistance( ******************************************************************************/ long -Cudd_Random( - ) +Cudd_Random(void) { - int i; /* index in the shuffle table */ + int i; /* index in the shuffle table */ long int w; /* work variable */ /* cuddRand == 0 if the geneartor has not been initialized yet. */ @@ -2554,11 +2772,11 @@ Cudd_Srandom( cuddRand2 = cuddRand; /* Load the shuffle table (after 11 warm-ups). */ for (i = 0; i < STAB_SIZE + 11; i++) { - long int w; - w = cuddRand / LEQQ1; - cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; - cuddRand += (cuddRand < 0) * MODULUS1; - shuffleTable[i % STAB_SIZE] = cuddRand; + long int w; + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + shuffleTable[i % STAB_SIZE] = cuddRand; } shuffleSelect = shuffleTable[1 % STAB_SIZE]; @@ -2650,7 +2868,7 @@ cuddP( DdNode * f) { int retval; - st_table *table = st_init_table(st_ptrcmp, st_ptrhash);; + st_table *table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) return(0); @@ -2679,7 +2897,7 @@ cuddStCountfree( char * value, char * arg) { - double *d; + double *d; d = (double *)value; ABC_FREE(d); @@ -2693,7 +2911,7 @@ cuddStCountfree( Synopsis [Recursively collects all the nodes of a DD in a symbol table.] - Description [Traverses the BDD f and collects all its nodes in a + Description [Traverses the DD f and collects all its nodes in a symbol table. f is assumed to be a regular pointer and cuddCollectNodes guarantees this assumption in the recursive calls. Returns 1 in case of success; 0 otherwise.] @@ -2708,8 +2926,8 @@ cuddCollectNodes( DdNode * f, st_table * visited) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -2729,7 +2947,7 @@ cuddCollectNodes( /* Check terminal case. */ if (cuddIsConstant(f)) - return(1); + return(1); /* Recursive calls. */ T = cuddT(f); @@ -2742,6 +2960,45 @@ cuddCollectNodes( } /* end of cuddCollectNodes */ +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in an array.] + + Description [Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants.] + + SideEffects [The number of nodes is returned as a side effect.] + + SeeAlso [Cudd_FirstNode] + +******************************************************************************/ +DdNodePtr * +cuddNodeArray( + DdNode *f, + int *n) +{ + DdNodePtr *table; + int size, retval; + + size = ddDagInt(Cudd_Regular(f)); + table = ABC_ALLOC(DdNodePtr, size); + if (table == NULL) { + ddClearFlag(Cudd_Regular(f)); + return(NULL); + } + + retval = cuddNodeArrayRecur(f, table, 0); + assert(retval == size); + + *n = size; + return(table); + +} /* cuddNodeArray */ + + /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ @@ -2765,7 +3022,7 @@ dp2( { DdNode *g, *n, *N; int T,E; - + if (f == NULL) { return(0); } @@ -2773,68 +3030,68 @@ dp2( if (cuddIsConstant(g)) { #if SIZEOF_VOID_P == 8 (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode),cuddV(g)); + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); #else (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),cuddV(g)); + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); #endif - return(1); + return(1); } if (st_is_member(t,(char *) g) == 1) { return(1); } if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) - return(0); + return(0); #ifdef DD_STATS #if SIZEOF_VOID_P == 8 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode), g->index, g->ref); + (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); #else (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),g->index,g->ref); + (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); #endif #else #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\t", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode),g->index); + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); #else - (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\t", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),g->index); + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); #endif #endif n = cuddT(g); if (cuddIsConstant(n)) { (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); - T = 1; + T = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"T = 0x%lx\t",(unsigned long) n / (unsigned long) sizeof(DdNode)); + (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); #else - (void) fprintf(dd->out,"T = 0x%x\t",(unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); #endif - T = 0; + T = 0; } n = cuddE(g); N = Cudd_Regular(n); if (cuddIsConstant(N)) { (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); - E = 1; + E = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (unsigned long) N/(unsigned long) sizeof(DdNode)); + (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); #else - (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (unsigned) N/(unsigned) sizeof(DdNode)); + (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); #endif - E = 0; + E = 0; } if (E == 0) { if (dp2(dd,N,t) == 0) - return(0); + return(0); } if (T == 0) { if (dp2(dd,cuddT(g),t) == 0) - return(0); + return(0); } return(1); @@ -2856,38 +3113,38 @@ ddPrintMintermAux( DdNode * node /* current node */, int * list /* current recursion path */) { - DdNode *N,*Nv,*Nnv; - int i,v,index; + DdNode *N,*Nv,*Nnv; + int i,v,index; N = Cudd_Regular(node); if (cuddIsConstant(N)) { - /* Terminal case: Print one cube based on the current recursion - ** path, unless we have reached the background value (ADDs) or - ** the logical zero (BDDs). - */ - if (node != background && node != zero) { - for (i = 0; i < dd->size; i++) { - v = list[i]; - if (v == 0) (void) fprintf(dd->out,"0"); - else if (v == 1) (void) fprintf(dd->out,"1"); - else (void) fprintf(dd->out,"-"); + /* Terminal case: Print one cube based on the current recursion + ** path, unless we have reached the background value (ADDs) or + ** the logical zero (BDDs). + */ + if (node != background && node != zero) { + for (i = 0; i < dd->size; i++) { + v = list[i]; + if (v == 0) (void) fprintf(dd->out,"0"); + else if (v == 1) (void) fprintf(dd->out,"1"); + else (void) fprintf(dd->out,"-"); + } + (void) fprintf(dd->out," % g\n", cuddV(node)); } - (void) fprintf(dd->out," % g\n", cuddV(node)); - } } else { - Nv = cuddT(N); - Nnv = cuddE(N); - if (Cudd_IsComplement(node)) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); - } - index = N->index; - list[index] = 0; - ddPrintMintermAux(dd,Nnv,list); - list[index] = 1; - ddPrintMintermAux(dd,Nv,list); - list[index] = 2; + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(node)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + index = N->index; + list[index] = 0; + ddPrintMintermAux(dd,Nnv,list); + list[index] = 1; + ddPrintMintermAux(dd,Nv,list); + list[index] = 2; } return; @@ -2911,11 +3168,11 @@ ddDagInt( int tval, eval; if (Cudd_IsComplement(n->next)) { - return(0); + return(0); } n->next = Cudd_Not(n->next); if (cuddIsConstant(n)) { - return(1); + return(1); } tval = ddDagInt(cuddT(n)); eval = ddDagInt(Cudd_Regular(cuddE(n))); @@ -2926,6 +3183,46 @@ ddDagInt( /**Function******************************************************************** + Synopsis [Performs the recursive step of cuddNodeArray.] + + Description [Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddNodeArrayRecur( + DdNode *f, + DdNodePtr *table, + int index) +{ + int tindex, eindex; + + if (!Cudd_IsComplement(f->next)) { + return(index); + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + table[index] = f; + return(index + 1); + } + tindex = cuddNodeArrayRecur(cuddT(f), table, index); + eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); + table[eindex] = f; + return(eindex + 1); + +} /* end of cuddNodeArrayRecur */ + + +/**Function******************************************************************** + Synopsis [Performs the recursive step of Cudd_CofactorEstimate.] Description [Performs the recursive step of Cudd_CofactorEstimate. @@ -2952,74 +3249,76 @@ cuddEstimateCofactor( DdNode *ptrT, *ptrE; if (Cudd_IsComplement(node->next)) { - if (!st_lookup(table,(char *)node,(char **)ptr)) { - st_add_direct(table,(char *)node,(char *)node); - *ptr = node; - } - return(0); + if (!st_lookup(table,(char *)node,(char **)ptr)) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + *ptr = node; + } + return(0); } node->next = Cudd_Not(node->next); if (cuddIsConstant(node)) { - *ptr = node; - if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - return(1); + *ptr = node; + if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + return(1); } if ((int) node->index == i) { - if (phase == 1) { - *ptr = cuddT(node); - val = ddDagInt(cuddT(node)); - } else { - *ptr = cuddE(node); - val = ddDagInt(Cudd_Regular(cuddE(node))); - } - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - return(val); + if (phase == 1) { + *ptr = cuddT(node); + val = ddDagInt(cuddT(node)); + } else { + *ptr = cuddE(node); + val = ddDagInt(Cudd_Regular(cuddE(node))); + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + return(val); } if (dd->perm[node->index] > dd->perm[i]) { - *ptr = node; - tval = ddDagInt(cuddT(node)); - eval = ddDagInt(Cudd_Regular(cuddE(node))); - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)node) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - val = 1 + tval + eval; - return(val); + *ptr = node; + tval = ddDagInt(cuddT(node)); + eval = ddDagInt(Cudd_Regular(cuddE(node))); + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + val = 1 + tval + eval; + return(val); } tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, - phase,&ptrE); + phase,&ptrE); ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); - if (ptrT == ptrE) { /* recombination */ - *ptr = ptrT; - val = tval; - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } + if (ptrT == ptrE) { /* recombination */ + *ptr = ptrT; + val = tval; + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && - (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { - if (Cudd_IsComplement((*ptr)->next)) { - val = 0; + (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { + if (Cudd_IsComplement((*ptr)->next)) { + val = 0; + } else { + val = 1 + tval + eval; + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } } else { + *ptr = node; val = 1 + tval + eval; } - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - } else { - *ptr = node; - val = 1 + tval + eval; - } return(val); } /* end of cuddEstimateCofactor */ @@ -3051,7 +3350,7 @@ cuddUniqueLookup( DdSubtable *subtable; if (index >= unique->size) { - return(NULL); + return(NULL); } level = unique->perm[index]; @@ -3067,13 +3366,13 @@ cuddUniqueLookup( looking = nodelist[posn]; while (T < cuddT(looking)) { - looking = Cudd_Regular(looking->next); + looking = Cudd_Regular(looking->next); } while (T == cuddT(looking) && E < cuddE(looking)) { - looking = Cudd_Regular(looking->next); + looking = Cudd_Regular(looking->next); } if (cuddT(looking) == T && cuddE(looking) == E) { - return(looking); + return(looking); } return(NULL); @@ -3104,11 +3403,11 @@ cuddEstimateCofactorSimple( int tval, eval; if (Cudd_IsComplement(node->next)) { - return(0); + return(0); } node->next = Cudd_Not(node->next); if (cuddIsConstant(node)) { - return(1); + return(1); } tval = cuddEstimateCofactorSimple(cuddT(node),i); if ((int) node->index == i) return(tval); @@ -3142,31 +3441,31 @@ ddCountMintermAux( double max, DdHashTable * table) { - DdNode *N, *Nt, *Ne; - double min, minT, minE; - DdNode *res; + DdNode *N, *Nt, *Ne; + double min, minT, minE; + DdNode *res; N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == background || node == zero) { - return(0.0); - } else { - return(max); - } + if (node == background || node == zero) { + return(0.0); + } else { + return(max); + } } if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { - min = cuddV(res); - if (res->ref == 0) { - table->manager->dead++; - table->manager->constants.dead++; - } - return(min); + min = cuddV(res); + if (res->ref == 0) { + table->manager->dead++; + table->manager->constants.dead++; + } + return(min); } Nt = cuddT(N); Ne = cuddE(N); if (Cudd_IsComplement(node)) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); } minT = ddCountMintermAux(Nt,max,table); @@ -3178,13 +3477,13 @@ ddCountMintermAux( min = minT + minE; if (N->ref != 1) { - ptrint fanout = (ptrint) N->ref; - cuddSatDec(fanout); - res = cuddUniqueConst(table->manager,min); - if (!cuddHashTableInsert1(table,node,res,fanout)) { - cuddRef(res); Cudd_RecursiveDeref(table->manager, res); - return((double)CUDD_OUT_OF_MEM); - } + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(table->manager,min); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(table->manager, res); + return((double)CUDD_OUT_OF_MEM); + } } return(min); @@ -3215,17 +3514,17 @@ ddCountPathAux( st_table * table) { - DdNode *Nv, *Nnv; - double paths, *ppaths, paths1, paths2; - double *dummy; + DdNode *Nv, *Nnv; + double paths, *ppaths, paths1, paths2; + double *dummy; if (cuddIsConstant(node)) { - return(1.0); + return(1.0); } - if (st_lookup(table, (char *)node, (char **)&dummy)) { - paths = *dummy; - return(paths); + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + paths = *dummy; + return(paths); } Nv = cuddT(node); Nnv = cuddE(node); @@ -3235,17 +3534,17 @@ ddCountPathAux( paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); paths = paths1 + paths2; - + ppaths = ABC_ALLOC(double,1); if (ppaths == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *ppaths = paths; if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { - ABC_FREE(ppaths); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); } return(paths); @@ -3254,9 +3553,9 @@ ddCountPathAux( /**Function******************************************************************** - Synopsis [Performs the recursive step of Cudd_CountMinterm.] + Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.] - Description [Performs the recursive step of Cudd_CountMinterm. + Description [Performs the recursive step of Cudd_EpdCountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> @@ -3277,33 +3576,31 @@ ddEpdCountMintermAux( EpDouble * epd, st_table * table) { - DdNode *Nt, *Ne; + DdNode *Nt, *Ne; EpDouble *min, minT, minE; EpDouble *res; - int status; + int status; + /* node is assumed to be regular */ if (cuddIsConstant(node)) { - if (node == background || node == zero) { - EpdMakeZero(epd, 0); - } else { - EpdCopy(max, epd); - } - return(0); + if (node == background || node == zero) { + EpdMakeZero(epd, 0); + } else { + EpdCopy(max, epd); + } + return(0); } - if (node->ref != 1 && st_lookup(table, (char *)node, (char **)&res)) { - EpdCopy(res, epd); - return(0); + if (node->ref != 1 && st_lookup(table, (const char *)node, (char **)&res)) { + EpdCopy(res, epd); + return(0); } Nt = cuddT(node); Ne = cuddE(node); - if (Cudd_IsComplement(node)) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); - } status = ddEpdCountMintermAux(Nt,max,&minT,table); if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); EpdMultiply(&minT, (double)0.5); - status = ddEpdCountMintermAux(Ne,max,&minE,table); + status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); if (Cudd_IsComplement(Ne)) { EpdSubtract3(max, &minE, epd); @@ -3313,14 +3610,14 @@ ddEpdCountMintermAux( EpdAdd3(&minT, &minE, epd); if (node->ref > 1) { - min = EpdAlloc(); - if (!min) - return(CUDD_OUT_OF_MEM); - EpdCopy(epd, min); - if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { - EpdFree(min); - return(CUDD_OUT_OF_MEM); - } + min = EpdAlloc(); + if (!min) + return(CUDD_OUT_OF_MEM); + EpdCopy(epd, min); + if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { + EpdFree(min); + return(CUDD_OUT_OF_MEM); + } } return(0); @@ -3350,22 +3647,22 @@ ddCountPathsToNonZero( st_table * table) { - DdNode *node, *Nt, *Ne; - double paths, *ppaths, paths1, paths2; - double *dummy; + DdNode *node, *Nt, *Ne; + double paths, *ppaths, paths1, paths2; + double *dummy; node = Cudd_Regular(N); if (cuddIsConstant(node)) { - return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); + return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); } - if (st_lookup(table, (char *)N, (char **)&dummy)) { - paths = *dummy; - return(paths); + if (st_lookup(table, (const char *)N, (char **)&dummy)) { + paths = *dummy; + return(paths); } Nt = cuddT(node); Ne = cuddE(node); if (node != N) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); } paths1 = ddCountPathsToNonZero(Nt,table); @@ -3376,14 +3673,14 @@ ddCountPathsToNonZero( ppaths = ABC_ALLOC(double,1); if (ppaths == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *ppaths = paths; if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { - ABC_FREE(ppaths); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); } return(paths); @@ -3409,7 +3706,7 @@ ddSupportStep( int * support) { if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { - return; + return; } support[f->index] = 1; @@ -3439,12 +3736,12 @@ ddClearFlag( DdNode * f) { if (!Cudd_IsComplement(f->next)) { - return; + return; } /* Clear visited flag. */ f->next = Cudd_Regular(f->next); if (cuddIsConstant(f)) { - return; + return; } ddClearFlag(cuddT(f)); ddClearFlag(Cudd_Regular(cuddE(f))); @@ -3472,11 +3769,11 @@ ddLeavesInt( int tval, eval; if (Cudd_IsComplement(n->next)) { - return(0); + return(0); } n->next = Cudd_Not(n->next); if (cuddIsConstant(n)) { - return(1); + return(1); } tval = ddLeavesInt(cuddT(n)); eval = ddLeavesInt(Cudd_Regular(cuddE(n))); @@ -3517,13 +3814,13 @@ ddPickArbitraryMinterms( bzero = Cudd_Not(one); if (nminterms == 0 || node == bzero) return(1); if (node == one) { - return(1); + return(1); } N = Cudd_Regular(node); T = cuddT(N); E = cuddE(N); if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; @@ -3533,13 +3830,13 @@ ddPickArbitraryMinterms( t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); for (i = 0; i < t; i++) - string[i][N->index] = '1'; + string[i][N->index] = '1'; for (i = t; i < nminterms; i++) - string[i][N->index] = '0'; + string[i][N->index] = '0'; result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); if (result == 0) - return(0); + return(0); result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); return(result); @@ -3562,7 +3859,6 @@ static int ddPickRepresentativeCube( DdManager *dd, DdNode *node, - int nvars, double *weight, char *string) { @@ -3579,33 +3875,33 @@ ddPickRepresentativeCube( if (node == DD_ONE(dd)) return(1); for (;;) { - N = Cudd_Regular(node); - if (N == one) - break; - T = cuddT(N); - E = cuddE(N); - if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); - E = Cudd_Not(E); - } - if (weight[N->index] >= 0.0) { - if (T == bzero) { - node = E; - string[N->index] = '0'; - } else { - node = T; - string[N->index] = '1'; + N = Cudd_Regular(node); + if (N == one) + break; + T = cuddT(N); + E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); + E = Cudd_Not(E); } - } else { - if (E == bzero) { - node = T; - string[N->index] = '1'; + if (weight[N->index] >= 0.0) { + if (T == bzero) { + node = E; + string[N->index] = '0'; + } else { + node = T; + string[N->index] = '1'; + } } else { - node = E; - string[N->index] = '0'; + if (E == bzero) { + node = T; + string[N->index] = '1'; + } else { + node = E; + string[N->index] = '0'; + } } } - } return(1); } /* end of ddPickRepresentativeCube */ @@ -3635,5 +3931,7 @@ ddEpdFree( return(ST_CONTINUE); } /* end of ddEpdFree */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddWindow.c b/src/bdd/cudd/cuddWindow.c index 62c92ff2..0a7c6705 100644 --- a/src/bdd/cudd/cuddWindow.c +++ b/src/bdd/cudd/cuddWindow.c @@ -4,30 +4,57 @@ PackageName [cudd] - Synopsis [Functions for window permutation] + Synopsis [Functions for variable reordering by window permutation.] Description [Internal procedures included in this module: - <ul> - <li> cuddWindowReorder() - </ul> - Static procedures included in this module: - <ul> - <li> ddWindow2() - <li> ddWindowConv2() - <li> ddPermuteWindow3() - <li> ddWindow3() - <li> ddWindowConv3() - <li> ddPermuteWindow4() - <li> ddWindow4() - <li> ddWindowConv4() - </ul>] + <ul> + <li> cuddWindowReorder() + </ul> + Static procedures included in this module: + <ul> + <li> ddWindow2() + <li> ddWindowConv2() + <li> ddPermuteWindow3() + <li> ddWindow3() + <li> ddWindowConv3() + <li> ddPermuteWindow4() + <li> ddWindow4() + <li> ddWindowConv4() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -37,6 +64,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -57,7 +85,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.14 2009/02/20 02:14:58 fabio Exp $"; #endif #ifdef DD_STATS @@ -76,14 +104,14 @@ extern int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddWindow2 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv2 ARGS((DdManager *table, int low, int high)); -static int ddPermuteWindow3 ARGS((DdManager *table, int x)); -static int ddWindow3 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv3 ARGS((DdManager *table, int low, int high)); -static int ddPermuteWindow4 ARGS((DdManager *table, int w)); -static int ddWindow4 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv4 ARGS((DdManager *table, int low, int high)); +static int ddWindow2 (DdManager *table, int low, int high); +static int ddWindowConv2 (DdManager *table, int low, int high); +static int ddPermuteWindow3 (DdManager *table, int x); +static int ddWindow3 (DdManager *table, int low, int high); +static int ddWindowConv3 (DdManager *table, int low, int high); +static int ddPermuteWindow4 (DdManager *table, int w); +static int ddWindow4 (DdManager *table, int low, int high); +static int ddWindowConv4 (DdManager *table, int low, int high); /**AutomaticEnd***************************************************************/ @@ -125,39 +153,39 @@ cuddWindowReorder( switch (submethod) { case CUDD_REORDER_WINDOW2: - res = ddWindow2(table,low,high); - break; + res = ddWindow2(table,low,high); + break; case CUDD_REORDER_WINDOW3: - res = ddWindow3(table,low,high); - break; + res = ddWindow3(table,low,high); + break; case CUDD_REORDER_WINDOW4: - res = ddWindow4(table,low,high); - break; + res = ddWindow4(table,low,high); + break; case CUDD_REORDER_WINDOW2_CONV: - res = ddWindowConv2(table,low,high); - break; + res = ddWindowConv2(table,low,high); + break; case CUDD_REORDER_WINDOW3_CONV: - res = ddWindowConv3(table,low,high); + res = ddWindowConv3(table,low,high); #ifdef DD_DEBUG - supposedOpt = table->keys - table->isolated; - res = ddWindow3(table,low,high); - if (table->keys - table->isolated != (unsigned) supposedOpt) { - (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", - table->keys - table->isolated, supposedOpt); - } + supposedOpt = table->keys - table->isolated; + res = ddWindow3(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } #endif - break; + break; case CUDD_REORDER_WINDOW4_CONV: - res = ddWindowConv4(table,low,high); + res = ddWindowConv4(table,low,high); #ifdef DD_DEBUG - supposedOpt = table->keys - table->isolated; - res = ddWindow4(table,low,high); - if (table->keys - table->isolated != (unsigned) supposedOpt) { - (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", - table->keys - table->isolated, supposedOpt); - } + supposedOpt = table->keys - table->isolated; + res = ddWindow4(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } #endif - break; + break; default: return(0); } @@ -201,20 +229,20 @@ ddWindow2( res = table->keys - table->isolated; for (x = low; x < high; x++) { - size = res; - res = cuddSwapInPlace(table,x,x+1); - if (res == 0) return(0); - if (res >= size) { /* no improvement: undo permutation */ + size = res; res = cuddSwapInPlace(table,x,x+1); if (res == 0) return(0); - } + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + } #ifdef DD_STATS - if (res < size) { - (void) fprintf(table->out,"-"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -258,52 +286,52 @@ ddWindowConv2( nwin = high-low; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } res = table->keys - table->isolated; do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - size = res; - res = cuddSwapInPlace(table,x+low,x+low+1); - if (res == 0) { - ABC_FREE(events); - return(0); - } - if (res >= size) { /* no improvement: undo permutation */ - res = cuddSwapInPlace(table,x+low,x+low+1); - if (res == 0) { - ABC_FREE(events); - return(0); - } - } - if (res < size) { - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + size = res; + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + ABC_FREE(events); + return(0); + } + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + ABC_FREE(events); + return(0); + } + } + if (res < size) { + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + } + events[x] = 0; #ifdef DD_STATS - if (res < size) { - (void) fprintf(table->out,"-"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -335,8 +363,8 @@ ddPermuteWindow3( int x) { int y,z; - int size,sizeNew; - int best; + int size,sizeNew; + int best; #ifdef DD_DEBUG assert(table->dead == 0); @@ -345,7 +373,7 @@ ddPermuteWindow3( size = table->keys - table->isolated; y = x+1; z = y+1; - + /* The permutation pattern is: ** (x,y)(y,z) ** repeated three times to get all 3! = 6 permutations. @@ -353,40 +381,40 @@ ddPermuteWindow3( #define ABC 1 best = ABC; -#define BAC 2 +#define BAC 2 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BAC; + size = sizeNew; } #define BCA 3 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCA; + size = sizeNew; } #define CBA 4 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = CBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBA; + size = sizeNew; } #define CAB 5 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = CAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CAB; + size = sizeNew; } #define ACB 6 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = ACB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACB; + size = sizeNew; } /* Now take the shortest route to the best permuytation. @@ -399,7 +427,7 @@ ddPermuteWindow3( case ACB: break; case BAC: if (!cuddSwapInPlace(table,y,z)) return(0); case CAB: if (!cuddSwapInPlace(table,x,y)) return(0); - break; + break; default: return(0); } @@ -441,15 +469,15 @@ ddWindow3( if (high-low < 2) return(ddWindow2(table,low,high)); for (x = low; x+1 < high; x++) { - res = ddPermuteWindow3(table,x); - if (res == 0) return(0); + res = ddPermuteWindow3(table,x); + if (res == 0) return(0); #ifdef DD_STATS - if (res == ABC) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif } @@ -492,60 +520,60 @@ ddWindowConv3( nwin = high-low-1; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - res = ddPermuteWindow3(table,x+low); - switch (res) { - case ABC: - break; - case BAC: - if (x < nwin-1) events[x+1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case BCA: - case CBA: - case CAB: - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case ACB: - if (x < nwin-2) events[x+2] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - break; - default: - ABC_FREE(events); - return(0); - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + res = ddPermuteWindow3(table,x+low); + switch (res) { + case ABC: + break; + case BAC: + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case BCA: + case CBA: + case CAB: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case ACB: + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + default: + ABC_FREE(events); + return(0); + } + events[x] = 0; #ifdef DD_STATS - if (res == ABC) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -575,8 +603,8 @@ ddPermuteWindow4( int w) { int x,y,z; - int size,sizeNew; - int best; + int size,sizeNew; + int best; #ifdef DD_DEBUG assert(table->dead == 0); @@ -585,7 +613,7 @@ ddPermuteWindow4( size = table->keys - table->isolated; x = w+1; y = x+1; z = y+1; - + /* The permutation pattern is: * (w,x)(y,z)(w,x)(x,y) * (y,z)(w,x)(y,z)(x,y) @@ -602,166 +630,166 @@ ddPermuteWindow4( #define ABCD 1 best = ABCD; -#define BACD 7 +#define BACD 7 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BACD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BACD; + size = sizeNew; } #define BADC 13 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BADC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BADC; + size = sizeNew; } #define ABDC 8 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && ABDC < best)) { - if (sizeNew == 0) return(0); - best = ABDC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ABDC; + size = sizeNew; } #define ADBC 14 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = ADBC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ADBC; + size = sizeNew; } #define ADCB 9 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && ADCB < best)) { - if (sizeNew == 0) return(0); - best = ADCB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ADCB; + size = sizeNew; } #define DACB 15 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DACB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DACB; + size = sizeNew; } #define DABC 20 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DABC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DABC; + size = sizeNew; } #define DBAC 23 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DBAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DBAC; + size = sizeNew; } #define BDAC 19 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && BDAC < best)) { - if (sizeNew == 0) return(0); - best = BDAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BDAC; + size = sizeNew; } #define BDCA 21 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && BDCA < best)) { - if (sizeNew == 0) return(0); - best = BDCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BDCA; + size = sizeNew; } #define DBCA 24 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DBCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DBCA; + size = sizeNew; } #define DCBA 22 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && DCBA < best)) { - if (sizeNew == 0) return(0); - best = DCBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DCBA; + size = sizeNew; } #define DCAB 18 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && DCAB < best)) { - if (sizeNew == 0) return(0); - best = DCAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DCAB; + size = sizeNew; } #define CDAB 12 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && CDAB < best)) { - if (sizeNew == 0) return(0); - best = CDAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CDAB; + size = sizeNew; } #define CDBA 17 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && CDBA < best)) { - if (sizeNew == 0) return(0); - best = CDBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CDBA; + size = sizeNew; } #define CBDA 11 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && CBDA < best)) { - if (sizeNew == 0) return(0); - best = CBDA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBDA; + size = sizeNew; } #define BCDA 16 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && BCDA < best)) { - if (sizeNew == 0) return(0); - best = BCDA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCDA; + size = sizeNew; } #define BCAD 10 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && BCAD < best)) { - if (sizeNew == 0) return(0); - best = BCAD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCAD; + size = sizeNew; } #define CBAD 5 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && CBAD < best)) { - if (sizeNew == 0) return(0); - best = CBAD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBAD; + size = sizeNew; } #define CABD 3 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && CABD < best)) { - if (sizeNew == 0) return(0); - best = CABD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CABD; + size = sizeNew; } #define CADB 6 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && CADB < best)) { - if (sizeNew == 0) return(0); - best = CADB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CADB; + size = sizeNew; } #define ACDB 4 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && ACDB < best)) { - if (sizeNew == 0) return(0); - best = ACDB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACDB; + size = sizeNew; } #define ACBD 2 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && ACBD < best)) { - if (sizeNew == 0) return(0); - best = ACBD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACBD; + size = sizeNew; } /* Now take the shortest route to the best permutation. @@ -778,29 +806,29 @@ ddPermuteWindow4( case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0); case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0); case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,x,y)) return(0); - if (!cuddSwapInPlace(table,y,z)) return(0); - break; + if (!cuddSwapInPlace(table,x,y)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0); case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0); case DACB: if (!cuddSwapInPlace(table,y,z)) return(0); case BACD: if (!cuddSwapInPlace(table,x,y)) return(0); case CABD: if (!cuddSwapInPlace(table,w,x)) return(0); - break; + break; case DABC: if (!cuddSwapInPlace(table,y,z)) return(0); case BADC: if (!cuddSwapInPlace(table,x,y)) return(0); case CADB: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,y,z)) return(0); - break; + if (!cuddSwapInPlace(table,y,z)) return(0); + break; case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0); case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0); case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0); case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0); - break; + break; case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0); case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,x,y)) return(0); - break; + if (!cuddSwapInPlace(table,x,y)) return(0); + break; default: return(0); } @@ -842,15 +870,15 @@ ddWindow4( if (high-low < 3) return(ddWindow3(table,low,high)); for (w = low; w+2 < high; w++) { - res = ddPermuteWindow4(table,w); - if (res == 0) return(0); + res = ddPermuteWindow4(table,w); + if (res == 0) return(0); #ifdef DD_STATS - if (res == ABCD) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif } @@ -893,102 +921,102 @@ ddWindowConv4( nwin = high-low-2; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - res = ddPermuteWindow4(table,x+low); - switch (res) { - case ABCD: - break; - case BACD: - if (x < nwin-1) events[x+1] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case BADC: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case ABDC: - if (x < nwin-3) events[x+3] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - break; - case ADBC: - case ADCB: - case ACDB: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-2) events[x+2] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case DACB: - case DABC: - case DBAC: - case BDAC: - case BDCA: - case DBCA: - case DCBA: - case DCAB: - case CDAB: - case CDBA: - case CBDA: - case BCDA: - case CADB: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case BCAD: - case CBAD: - case CABD: - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 1) events[x-2] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case ACBD: - if (x < nwin-2) events[x+2] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - default: - ABC_FREE(events); - return(0); - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + res = ddPermuteWindow4(table,x+low); + switch (res) { + case ABCD: + break; + case BACD: + if (x < nwin-1) events[x+1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BADC: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ABDC: + if (x < nwin-3) events[x+3] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + case ADBC: + case ADCB: + case ACDB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case DACB: + case DABC: + case DBAC: + case BDAC: + case BDCA: + case DBCA: + case DCBA: + case DCAB: + case CDAB: + case CDBA: + case CBDA: + case BCDA: + case CADB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BCAD: + case CBAD: + case CABD: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ACBD: + if (x < nwin-2) events[x+2] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + default: + ABC_FREE(events); + return(0); + } + events[x] = 0; #ifdef DD_STATS - if (res == ABCD) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -998,5 +1026,6 @@ ddWindowConv4( } /* end of ddWindowConv4 */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddCount.c b/src/bdd/cudd/cuddZddCount.c index 8f974e5e..a422ad99 100644 --- a/src/bdd/cudd/cuddZddCount.c +++ b/src/bdd/cudd/cuddZddCount.c @@ -7,39 +7,67 @@ Synopsis [Procedures to count the number of minterms of a ZDD.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddCount(); - <li> Cudd_zddCountDouble(); - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddCountStep(); - <li> cuddZddCountDoubleStep(); - <li> st_zdd_count_dbl_free() - <li> st_zdd_countfree() - </ul> - ] + <ul> + <li> Cudd_zddCount(); + <li> Cudd_zddCountDouble(); + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddCountStep(); + <li> cuddZddCountDoubleStep(); + <li> st_zdd_count_dbl_free() + <li> st_zdd_countfree() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,13 +88,16 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -74,13 +105,16 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddCountStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty)); -static double cuddZddCountDoubleStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty)); -static enum st_retval st_zdd_countfree ARGS((char *key, char *value, char *arg)); -static enum st_retval st_zdd_count_dbl_free ARGS((char *key, char *value, char *arg)); +static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static enum st_retval st_zdd_countfree (char *key, char *value, char *arg); +static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -105,8 +139,8 @@ Cudd_zddCount( DdNode * P) { st_table *table; - int res; - DdNode *base, *empty; + int res; + DdNode *base, *empty; base = DD_ONE(zdd); empty = DD_ZERO(zdd); @@ -114,9 +148,9 @@ Cudd_zddCount( if (table == NULL) return(CUDD_OUT_OF_MEM); res = cuddZddCountStep(P, table, base, empty); if (res == CUDD_OUT_OF_MEM) { - zdd->errorCode = CUDD_MEMORY_OUT; + zdd->errorCode = CUDD_MEMORY_OUT; } - st_foreach(table, (ST_PFSR)st_zdd_countfree, NIL(char)); + st_foreach(table, st_zdd_countfree, NIL(char)); st_free_table(table); return(res); @@ -144,8 +178,8 @@ Cudd_zddCountDouble( DdNode * P) { st_table *table; - double res; - DdNode *base, *empty; + double res; + DdNode *base, *empty; base = DD_ONE(zdd); empty = DD_ZERO(zdd); @@ -153,9 +187,9 @@ Cudd_zddCountDouble( if (table == NULL) return((double)CUDD_OUT_OF_MEM); res = cuddZddCountDoubleStep(P, table, base, empty); if (res == (double)CUDD_OUT_OF_MEM) { - zdd->errorCode = CUDD_MEMORY_OUT; + zdd->errorCode = CUDD_MEMORY_OUT; } - st_foreach(table, (ST_PFSR)st_zdd_count_dbl_free, NIL(char)); + st_foreach(table, st_zdd_count_dbl_free, NIL(char)); st_free_table(table); return(res); @@ -191,31 +225,31 @@ cuddZddCountStep( DdNode * base, DdNode * empty) { - int res; - int *dummy; + int res; + int *dummy; if (P == empty) - return(0); + return(0); if (P == base) - return(1); + return(1); /* Check cache. */ - if (st_lookup(table, (char *)P, (char **)(&dummy))) { - res = *dummy; - return(res); + if (st_lookup(table, (const char *)P, (char **)&dummy)) { + res = *dummy; + return(res); } res = cuddZddCountStep(cuddE(P), table, base, empty) + - cuddZddCountStep(cuddT(P), table, base, empty); + cuddZddCountStep(cuddT(P), table, base, empty); dummy = ABC_ALLOC(int, 1); if (dummy == NULL) { - return(CUDD_OUT_OF_MEM); + return(CUDD_OUT_OF_MEM); } *dummy = res; if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { - ABC_FREE(dummy); - return(CUDD_OUT_OF_MEM); + ABC_FREE(dummy); + return(CUDD_OUT_OF_MEM); } return(res); @@ -241,31 +275,31 @@ cuddZddCountDoubleStep( DdNode * base, DdNode * empty) { - double res; - double *dummy; + double res; + double *dummy; if (P == empty) - return((double)0.0); + return((double)0.0); if (P == base) - return((double)1.0); + return((double)1.0); /* Check cache */ - if (st_lookup(table, (char *)P, (char **)(&dummy))) { - res = *dummy; - return(res); + if (st_lookup(table, (const char *)P, (char **)&dummy)) { + res = *dummy; + return(res); } res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) + - cuddZddCountDoubleStep(cuddT(P), table, base, empty); + cuddZddCountDoubleStep(cuddT(P), table, base, empty); dummy = ABC_ALLOC(double, 1); if (dummy == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *dummy = res; if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { - ABC_FREE(dummy); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(dummy); + return((double)CUDD_OUT_OF_MEM); } return(res); @@ -291,7 +325,7 @@ st_zdd_countfree( char * value, char * arg) { - int *d; + int *d; d = (int *)value; ABC_FREE(d); @@ -318,12 +352,14 @@ st_zdd_count_dbl_free( char * value, char * arg) { - double *d; + double *d; d = (double *)value; ABC_FREE(d); return(ST_CONTINUE); } /* end of st_zdd_count_dbl_free */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddFuncs.c b/src/bdd/cudd/cuddZddFuncs.c index 2560159c..41f7c64c 100644 --- a/src/bdd/cudd/cuddZddFuncs.c +++ b/src/bdd/cudd/cuddZddFuncs.c @@ -7,53 +7,81 @@ Synopsis [Functions to manipulate covers represented as ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddProduct(); - <li> Cudd_zddUnateProduct(); - <li> Cudd_zddWeakDiv(); - <li> Cudd_zddWeakDivF(); - <li> Cudd_zddDivide(); - <li> Cudd_zddDivideF(); - <li> Cudd_zddComplement(); - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddProduct(); - <li> cuddZddUnateProduct(); - <li> cuddZddWeakDiv(); - <li> cuddZddWeakDivF(); - <li> cuddZddDivide(); - <li> cuddZddDivideF(); - <li> cuddZddGetCofactors3() - <li> cuddZddGetCofactors2() - <li> cuddZddComplement(); - <li> cuddZddGetPosVarIndex(); - <li> cuddZddGetNegVarIndex(); - <li> cuddZddGetPosVarLevel(); - <li> cuddZddGetNegVarLevel(); - </ul> - Static procedures included in this module: - <ul> - </ul> - ] + <ul> + <li> Cudd_zddProduct(); + <li> Cudd_zddUnateProduct(); + <li> Cudd_zddWeakDiv(); + <li> Cudd_zddWeakDivF(); + <li> Cudd_zddDivide(); + <li> Cudd_zddDivideF(); + <li> Cudd_zddComplement(); + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddProduct(); + <li> cuddZddUnateProduct(); + <li> cuddZddWeakDiv(); + <li> cuddZddWeakDivF(); + <li> cuddZddDivide(); + <li> cuddZddDivideF(); + <li> cuddZddGetCofactors3() + <li> cuddZddGetCofactors2() + <li> cuddZddComplement(); + <li> cuddZddGetPosVarIndex(); + <li> cuddZddGetNegVarIndex(); + <li> cuddZddGetPosVarLevel(); + <li> cuddZddGetNegVarLevel(); + </ul> + Static procedures included in this module: + <ul> + </ul> + ] SeeAlso [] Author [In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.16 2008/04/25 07:39:33 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -113,17 +141,17 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.1.1.1 2003/02/24 22:23: SeeAlso [Cudd_zddUnateProduct] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddProduct( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddProduct(dd, f, g); + dd->reordered = 0; + res = cuddZddProduct(dd, f, g); } while (dd->reordered == 1); return(res); @@ -144,17 +172,17 @@ Cudd_zddProduct( SeeAlso [Cudd_zddProduct] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddUnateProduct( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddUnateProduct(dd, f, g); + dd->reordered = 0; + res = cuddZddUnateProduct(dd, f, g); } while (dd->reordered == 1); return(res); @@ -178,17 +206,17 @@ Cudd_zddUnateProduct( SeeAlso [Cudd_zddDivide] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddWeakDiv( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddWeakDiv(dd, f, g); + dd->reordered = 0; + res = cuddZddWeakDiv(dd, f, g); } while (dd->reordered == 1); return(res); @@ -209,17 +237,17 @@ Cudd_zddWeakDiv( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddDivide( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddDivide(dd, f, g); + dd->reordered = 0; + res = cuddZddDivide(dd, f, g); } while (dd->reordered == 1); return(res); @@ -238,17 +266,17 @@ Cudd_zddDivide( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddWeakDivF( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddWeakDivF(dd, f, g); + dd->reordered = 0; + res = cuddZddWeakDivF(dd, f, g); } while (dd->reordered == 1); return(res); @@ -267,17 +295,17 @@ Cudd_zddWeakDivF( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddDivideF( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddDivideF(dd, f, g); + dd->reordered = 0; + res = cuddZddDivideF(dd, f, g); } while (dd->reordered == 1); return(res); @@ -300,26 +328,26 @@ Cudd_zddDivideF( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddComplement( DdManager *dd, DdNode *node) { - DdNode *b, *isop, *zdd_I; + DdNode *b, *isop, *zdd_I; /* Check cache */ zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); if (zdd_I) - return(zdd_I); + return(zdd_I); b = Cudd_MakeBddFromZddCover(dd, node); if (!b) - return(NULL); + return(NULL); Cudd_Ref(b); isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); if (!isop) { - Cudd_RecursiveDeref(dd, b); - return(NULL); + Cudd_RecursiveDeref(dd, b); + return(NULL); } Cudd_Ref(isop); Cudd_Ref(zdd_I); @@ -348,21 +376,21 @@ Cudd_zddComplement( SeeAlso [Cudd_zddProduct] ******************************************************************************/ -DdNode * +DdNode * cuddZddProduct( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g; - DdNode *tmp, *term1, *term2, *term3; - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *R0, *R1, *Rd, *N0, *N1; - DdNode *r; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - int flag; - int pv, nv; + int v, top_f, top_g; + DdNode *tmp, *term1, *term2, *term3; + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *R0, *R1, *Rd, *N0, *N1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + int pv, nv; statLine(dd); if (f == zero || g == zero) @@ -376,26 +404,26 @@ cuddZddProduct( top_g = dd->permZ[g->index]; if (top_f > top_g) - return(cuddZddProduct(dd, g, f)); + return(cuddZddProduct(dd, g, f)); /* Check cache */ r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g); if (r) - return(r); + return(r); - v = f->index; /* either yi or zi */ + v = f->index; /* either yi or zi */ flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -405,95 +433,95 @@ cuddZddProduct( Rd = cuddZddProduct(dd, fd, gd); if (Rd == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); } Cudd_Ref(Rd); term1 = cuddZddProduct(dd, f0, g0); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddProduct(dd, f0, gd); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddProduct(dd, fd, g0); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); tmp = cuddZddUnion(dd, term1, term2); if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); R0 = cuddZddUnion(dd, tmp, term3); if (R0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); } Cudd_Ref(R0); Cudd_RecursiveDerefZdd(dd, tmp); Cudd_RecursiveDerefZdd(dd, term3); N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */ if (N0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, R0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, R0); + return(NULL); } Cudd_Ref(N0); Cudd_RecursiveDerefZdd(dd, R0); @@ -501,35 +529,35 @@ cuddZddProduct( term1 = cuddZddProduct(dd, f1, g1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddProduct(dd, f1, gd); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddProduct(dd, fd, g1); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); Cudd_RecursiveDerefZdd(dd, f1); @@ -538,30 +566,30 @@ cuddZddProduct( Cudd_RecursiveDerefZdd(dd, gd); tmp = cuddZddUnion(dd, term1, term2); if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); R1 = cuddZddUnion(dd, tmp, term3); if (R1 == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); } Cudd_Ref(R1); Cudd_RecursiveDerefZdd(dd, tmp); Cudd_RecursiveDerefZdd(dd, term3); N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */ if (N1 == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, R1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, R1); + return(NULL); } Cudd_Ref(N1); Cudd_RecursiveDerefZdd(dd, R1); @@ -585,20 +613,20 @@ cuddZddProduct( SeeAlso [Cudd_zddUnateProduct] ******************************************************************************/ -DdNode * +DdNode * cuddZddUnateProduct( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g; - DdNode *term1, *term2, *term3, *term4; - DdNode *sum1, *sum2; - DdNode *f0, *f1, *g0, *g1; - DdNode *r; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - int flag; + int v, top_f, top_g; + DdNode *term1, *term2, *term3, *term4; + DdNode *sum1, *sum2; + DdNode *f0, *f1, *g0, *g1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; statLine(dd); if (f == zero || g == zero) @@ -612,68 +640,68 @@ cuddZddUnateProduct( top_g = dd->permZ[g->index]; if (top_f > top_g) - return(cuddZddUnateProduct(dd, g, f)); + return(cuddZddUnateProduct(dd, g, f)); /* Check cache */ r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g); if (r) - return(r); + return(r); - v = f->index; /* either yi or zi */ + v = f->index; /* either yi or zi */ flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); term1 = cuddZddUnateProduct(dd, f1, g1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddUnateProduct(dd, f1, g0); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddUnateProduct(dd, f0, g1); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); term4 = cuddZddUnateProduct(dd, f0, g0); if (term4 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(term4); Cudd_RecursiveDerefZdd(dd, f1); @@ -682,30 +710,30 @@ cuddZddUnateProduct( Cudd_RecursiveDerefZdd(dd, g0); sum1 = cuddZddUnion(dd, term1, term2); if (sum1 == NULL) { - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, term4); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + return(NULL); } Cudd_Ref(sum1); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); sum2 = cuddZddUnion(dd, sum1, term3); if (sum2 == NULL) { - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, term4); - Cudd_RecursiveDerefZdd(dd, sum1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum1); + return(NULL); } Cudd_Ref(sum2); Cudd_RecursiveDerefZdd(dd, sum1); Cudd_RecursiveDerefZdd(dd, term3); r = cuddZddGetNode(dd, v, sum2, term4); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, term4); - Cudd_RecursiveDerefZdd(dd, sum2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum2); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDerefZdd(dd, sum2); @@ -729,47 +757,47 @@ cuddZddUnateProduct( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * cuddZddWeakDiv( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *q, *tmp; - DdNode *r; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -778,98 +806,98 @@ cuddZddWeakDiv( q = g; if (g0 != zero) { - q = cuddZddWeakDiv(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(q); + q = cuddZddWeakDiv(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); } else - Cudd_Ref(q); + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); if (q == zero) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); - Cudd_Deref(q); - return(zero); - } - - if (g1 != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDiv(dd, f1, g1); - if (tmp == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); } if (q == zero) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); - Cudd_Deref(q); - return(zero); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); } if (gd != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDiv(dd, fd, gd); - if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); } cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q); @@ -890,34 +918,34 @@ cuddZddWeakDiv( SeeAlso [Cudd_zddWeakDivF] ******************************************************************************/ -DdNode * +DdNode * cuddZddWeakDivF( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g, vf, vg; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *q, *tmp; - DdNode *r; - DdNode *term1, *term0, *termd; - int flag; - int pv, nv; + int v, top_f, top_g, vf, vg; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + DdNode *term1, *term0, *termd; + int flag; + int pv, nv; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g); if (r) - return(r); + return(r); top_f = dd->permZ[f->index]; top_g = dd->permZ[g->index]; @@ -926,87 +954,87 @@ cuddZddWeakDivF( v = ddMin(top_f, top_g); if (v == top_f && vf < vg) { - v = f->index; - flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); - if (flag == 1) - return(NULL); - Cudd_Ref(f1); - Cudd_Ref(f0); - Cudd_Ref(fd); - - pv = cuddZddGetPosVarIndex(dd, v); - nv = cuddZddGetNegVarIndex(dd, v); - - term1 = cuddZddWeakDivF(dd, f1, g); - if (term1 == NULL) { + v = f->index; + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + term1 = cuddZddWeakDivF(dd, f1, g); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(term1); Cudd_RecursiveDerefZdd(dd, f1); + term0 = cuddZddWeakDivF(dd, f0, g); + if (term0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term0); Cudd_RecursiveDerefZdd(dd, f0); + termd = cuddZddWeakDivF(dd, fd, g); + if (termd == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + return(NULL); + } + Cudd_Ref(termd); Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); - } - Cudd_Ref(term1); - Cudd_RecursiveDerefZdd(dd, f1); - term0 = cuddZddWeakDivF(dd, f0, g); - if (term0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); - } - Cudd_Ref(term0); - Cudd_RecursiveDerefZdd(dd, f0); - termd = cuddZddWeakDivF(dd, fd, g); - if (termd == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term0); - return(NULL); - } - Cudd_Ref(termd); - Cudd_RecursiveDerefZdd(dd, fd); - tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ - if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, term1); + tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term0); Cudd_RecursiveDerefZdd(dd, termd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, term0); - Cudd_RecursiveDerefZdd(dd, termd); - q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ - if (q == NULL) { + q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); - } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, tmp); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); - Cudd_Deref(q); - return(q); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); } if (v == top_f) - v = f->index; + v = f->index; else - v = g->index; + v = g->index; flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -1015,98 +1043,98 @@ cuddZddWeakDivF( q = g; if (g0 != zero) { - q = cuddZddWeakDivF(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(q); + q = cuddZddWeakDivF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); } else - Cudd_Ref(q); + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); if (q == zero) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); - Cudd_Deref(q); - return(zero); - } - - if (g1 != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDivF(dd, f1, g1); - if (tmp == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); } if (q == zero) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); - Cudd_Deref(q); - return(zero); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); } if (gd != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDivF(dd, fd, gd); - if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); } cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); @@ -1127,81 +1155,81 @@ cuddZddWeakDivF( SeeAlso [Cudd_zddDivide] ******************************************************************************/ -DdNode * +DdNode * cuddZddDivide( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *g0, *g1; - DdNode *q, *r, *tmp; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); r = cuddZddDivide(dd, f1, g1); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(r); - - if (r != zero && g0 != zero) { - tmp = r; - q = cuddZddDivide(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(q); - r = cuddZddIntersect(dd, r, q); - if (r == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, q); return(NULL); } Cudd_Ref(r); - Cudd_RecursiveDerefZdd(dd, q); - Cudd_RecursiveDerefZdd(dd, tmp); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivide(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); } Cudd_RecursiveDerefZdd(dd, f1); @@ -1227,81 +1255,81 @@ cuddZddDivide( SeeAlso [Cudd_zddDivideF] ******************************************************************************/ -DdNode * +DdNode * cuddZddDivideF( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *g0, *g1; - DdNode *q, *r, *tmp; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); r = cuddZddDivideF(dd, f1, g1); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(r); - - if (r != zero && g0 != zero) { - tmp = r; - q = cuddZddDivideF(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(q); - r = cuddZddIntersect(dd, r, q); - if (r == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, q); return(NULL); } Cudd_Ref(r); - Cudd_RecursiveDerefZdd(dd, q); - Cudd_RecursiveDerefZdd(dd, tmp); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivideF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); } Cudd_RecursiveDerefZdd(dd, f1); @@ -1321,7 +1349,7 @@ cuddZddDivideF( Synopsis [Computes the three-way decomposition of f w.r.t. v.] Description [Computes the three-way decomposition of function f (represented - by a ZDD) wit respect to variable v.] + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.] SideEffects [The results are returned in f1, f0, and fd.] @@ -1337,10 +1365,10 @@ cuddZddGetCofactors3( DdNode ** f0, DdNode ** fd) { - DdNode *pc, *nc; - DdNode *zero = DD_ZERO(dd); - int top, hv, ht, pv, nv; - int level; + DdNode *pc, *nc; + DdNode *zero = DD_ZERO(dd); + int top, hv, ht, pv, nv; + int level; top = dd->permZ[f->index]; level = dd->permZ[v]; @@ -1348,96 +1376,96 @@ cuddZddGetCofactors3( ht = top >> 1; if (hv < ht) { - *f1 = zero; - *f0 = zero; - *fd = f; + *f1 = zero; + *f0 = zero; + *fd = f; } else { - pv = cuddZddGetPosVarIndex(dd, v); - nv = cuddZddGetNegVarIndex(dd, v); - - /* not to create intermediate ZDD node */ - if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { - pc = cuddZddSubset1(dd, f, pv); - if (pc == NULL) - return(1); - Cudd_Ref(pc); - nc = cuddZddSubset0(dd, f, pv); - if (nc == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - return(1); - } - Cudd_Ref(nc); - - *f1 = cuddZddSubset0(dd, pc, nv); - if (*f1 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - return(1); - } - Cudd_Ref(*f1); - *f0 = cuddZddSubset1(dd, nc, nv); - if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + /* not to create intermediate ZDD node */ + if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { + pc = cuddZddSubset1(dd, f, pv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, pv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f1 = cuddZddSubset0(dd, pc, nv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f1); + *f0 = cuddZddSubset1(dd, nc, nv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + Cudd_Ref(*f0); + + *fd = cuddZddSubset0(dd, nc, nv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } else { + pc = cuddZddSubset1(dd, f, nv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, nv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f0 = cuddZddSubset0(dd, pc, pv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f0); + *f1 = cuddZddSubset1(dd, nc, pv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*f1); + + *fd = cuddZddSubset0(dd, nc, pv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); } - Cudd_Ref(*f0); - *fd = cuddZddSubset0(dd, nc, nv); - if (*fd == NULL) { Cudd_RecursiveDerefZdd(dd, pc); Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - Cudd_RecursiveDerefZdd(dd, *f0); - return(1); - } - Cudd_Ref(*fd); - } else { - pc = cuddZddSubset1(dd, f, nv); - if (pc == NULL) - return(1); - Cudd_Ref(pc); - nc = cuddZddSubset0(dd, f, nv); - if (nc == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - return(1); - } - Cudd_Ref(nc); - - *f0 = cuddZddSubset0(dd, pc, pv); - if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - return(1); - } - Cudd_Ref(*f0); - *f1 = cuddZddSubset1(dd, nc, pv); - if (*f1 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); - } - Cudd_Ref(*f1); - - *fd = cuddZddSubset0(dd, nc, pv); - if (*fd == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - Cudd_RecursiveDerefZdd(dd, *f0); - return(1); - } - Cudd_Ref(*fd); - } - - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_Deref(*f1); - Cudd_Deref(*f0); - Cudd_Deref(*fd); + Cudd_Deref(*f1); + Cudd_Deref(*f0); + Cudd_Deref(*fd); } return(0); @@ -1465,11 +1493,11 @@ cuddZddGetCofactors2( { *f1 = cuddZddSubset1(dd, f, v); if (*f1 == NULL) - return(1); + return(1); *f0 = cuddZddSubset0(dd, f, v); if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); } return(0); @@ -1490,26 +1518,26 @@ cuddZddGetCofactors2( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * cuddZddComplement( DdManager * dd, DdNode *node) { - DdNode *b, *isop, *zdd_I; + DdNode *b, *isop, *zdd_I; /* Check cache */ zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); if (zdd_I) - return(zdd_I); + return(zdd_I); b = cuddMakeBddFromZddCover(dd, node); if (!b) - return(NULL); + return(NULL); cuddRef(b); isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); if (!isop) { - Cudd_RecursiveDeref(dd, b); - return(NULL); + Cudd_RecursiveDeref(dd, b); + return(NULL); } cuddRef(isop); cuddRef(zdd_I); @@ -1538,7 +1566,7 @@ cuddZddGetPosVarIndex( DdManager * dd, int index) { - int pv = (index >> 1) << 1; + int pv = (index >> 1) << 1; return(pv); } /* end of cuddZddGetPosVarIndex */ @@ -1559,7 +1587,7 @@ cuddZddGetNegVarIndex( DdManager * dd, int index) { - int nv = index | 0x1; + int nv = index | 0x1; return(nv); } /* end of cuddZddGetPosVarIndex */ @@ -1580,7 +1608,7 @@ cuddZddGetPosVarLevel( DdManager * dd, int index) { - int pv = cuddZddGetPosVarIndex(dd, index); + int pv = cuddZddGetPosVarIndex(dd, index); return(dd->permZ[pv]); } /* end of cuddZddGetPosVarLevel */ @@ -1601,8 +1629,10 @@ cuddZddGetNegVarLevel( DdManager * dd, int index) { - int nv = cuddZddGetNegVarIndex(dd, index); + int nv = cuddZddGetNegVarIndex(dd, index); return(dd->permZ[nv]); } /* end of cuddZddGetNegVarLevel */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddGroup.c b/src/bdd/cudd/cuddZddGroup.c index 0bf611e5..5d0409de 100644 --- a/src/bdd/cudd/cuddZddGroup.c +++ b/src/bdd/cudd/cuddZddGroup.c @@ -7,36 +7,63 @@ Synopsis [Functions for ZDD group sifting.] Description [External procedures included in this file: - <ul> - <li> Cudd_MakeZddTreeNode() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddZddTreeSifting() - </ul> - Static procedures included in this module: - <ul> - <li> zddTreeSiftingAux() - <li> zddCountInternalMtrNodes() - <li> zddReorderChildren() - <li> zddFindNodeHiLo() - <li> zddUniqueCompareGroup() - <li> zddGroupSifting() - <li> zddGroupSiftingAux() - <li> zddGroupSiftingUp() - <li> zddGroupSiftingDown() - <li> zddGroupMove() - <li> zddGroupMoveBackward() - <li> zddGroupSiftingBackward() - <li> zddMergeGroups() - </ul>] + <ul> + <li> Cudd_MakeZddTreeNode() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddZddTreeSifting() + </ul> + Static procedures included in this module: + <ul> + <li> zddTreeSiftingAux() + <li> zddCountInternalMtrNodes() + <li> zddReorderChildren() + <li> zddFindNodeHiLo() + <li> zddUniqueCompareGroup() + <li> zddGroupSifting() + <li> zddGroupSiftingAux() + <li> zddGroupSiftingUp() + <li> zddGroupSiftingDown() + <li> zddGroupMove() + <li> zddGroupMoveBackward() + <li> zddGroupSiftingBackward() + <li> zddMergeGroups() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -46,6 +73,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -63,11 +91,11 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.20 2009/02/19 16:25:36 fabio Exp $"; #endif -static int *entry; -extern int zddTotalNumberSwapping; +static int *entry; +extern int zddTotalNumberSwapping; #ifdef DD_STATS static int extsymmcalls; static int extsymm; @@ -76,8 +104,8 @@ static int secdiff; static int secdiffmisfire; #endif #ifdef DD_DEBUG -static int pr = 0; /* flag to enable printing while debugging */ - /* by depositing a 1 into it */ +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ #endif /*---------------------------------------------------------------------------*/ @@ -90,21 +118,21 @@ static int pr = 0; /* flag to enable printing while debugging */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int zddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)); +static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); #ifdef DD_STATS -static int zddCountInternalMtrNodes ARGS((DdManager *table, MtrNode *treenode)); +static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); #endif -static int zddReorderChildren ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)); -static void zddFindNodeHiLo ARGS((DdManager *table, MtrNode *treenode, int *lower, int *upper)); -static int zddUniqueCompareGroup ARGS((int *ptrX, int *ptrY)); -static int zddGroupSifting ARGS((DdManager *table, int lower, int upper)); -static int zddGroupSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static int zddGroupSiftingUp ARGS((DdManager *table, int y, int xLow, Move **moves)); -static int zddGroupSiftingDown ARGS((DdManager *table, int x, int xHigh, Move **moves)); -static int zddGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int zddGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int zddGroupSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void zddMergeGroups ARGS((DdManager *table, MtrNode *treenode, int low, int high)); +static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int zddUniqueCompareGroup (int *ptrX, int *ptrY); +static int zddGroupSifting (DdManager *table, int lower, int upper); +static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves); +static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves); +static int zddGroupMove (DdManager *table, int x, int y, Move **moves); +static int zddGroupMoveBackward (DdManager *table, int x, int y); +static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size); +static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); /**AutomaticEnd***************************************************************/ @@ -150,15 +178,15 @@ Cudd_MakeZddTreeNode( level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; if (level + size - 1> (int) MTR_MAXHIGH) - return(NULL); + return(NULL); /* If the tree does not exist yet, create it. */ tree = dd->treeZ; if (tree == NULL) { - dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); - if (tree == NULL) - return(NULL); - tree->index = dd->invpermZ[0]; + dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); + if (tree == NULL) + return(NULL); + tree->index = dd->invpermZ[0]; } /* Extend the upper bound of the tree if necessary. This allows the @@ -169,7 +197,7 @@ Cudd_MakeZddTreeNode( /* Create the group. */ group = Mtr_MakeGroup(tree, level, size, type); if (group == NULL) - return(NULL); + return(NULL); /* Initialize the index field to the index of the variable currently ** in position low. This field will be updated by the reordering @@ -216,44 +244,44 @@ cuddZddTreeSifting( */ tempTree = table->treeZ == NULL; if (tempTree) { - table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); - table->treeZ->index = table->invpermZ[0]; + table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); + table->treeZ->index = table->invpermZ[0]; } nvars = table->sizeZ; #ifdef DD_DEBUG if (pr > 0 && !tempTree) - (void) fprintf(table->out,"cuddZddTreeSifting:"); + (void) fprintf(table->out,"cuddZddTreeSifting:"); Mtr_PrintGroups(table->treeZ,pr <= 0); #endif #if 0 /* Debugging code. */ if (table->tree && table->treeZ) { - (void) fprintf(table->out,"\n"); - Mtr_PrintGroups(table->tree, 0); - cuddPrintVarGroups(table,table->tree,0,0); - for (i = 0; i < table->size; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->invperm[i]); - } - (void) fprintf(table->out,"\n"); - for (i = 0; i < table->size; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->perm[i]); - } - (void) fprintf(table->out,"\n\n"); - Mtr_PrintGroups(table->treeZ,0); - cuddPrintVarGroups(table,table->treeZ,1,0); - for (i = 0; i < table->sizeZ; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->invpermZ[i]); - } - (void) fprintf(table->out,"\n"); - for (i = 0; i < table->sizeZ; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->permZ[i]); - } - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); + Mtr_PrintGroups(table->tree, 0); + cuddPrintVarGroups(table,table->tree,0,0); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invperm[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->perm[i]); + } + (void) fprintf(table->out,"\n\n"); + Mtr_PrintGroups(table->treeZ,0); + cuddPrintVarGroups(table,table->treeZ,1,0); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invpermZ[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->permZ[i]); + } + (void) fprintf(table->out,"\n"); } /* End of debugging code. */ #endif @@ -266,8 +294,8 @@ cuddZddTreeSifting( (void) fprintf(table->out,"\n"); if (!tempTree) - (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", - zddCountInternalMtrNodes(table,table->treeZ)); + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + zddCountInternalMtrNodes(table,table->treeZ)); #endif /* Initialize the group of each subtable to itself. Initially @@ -280,23 +308,23 @@ cuddZddTreeSifting( /* Reorder. */ result = zddTreeSiftingAux(table, table->treeZ, method); -#ifdef DD_STATS /* print stats */ +#ifdef DD_STATS /* print stats */ if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - (table->groupcheck == CUDD_GROUP_CHECK7 || - table->groupcheck == CUDD_GROUP_CHECK5)) { - (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); - (void) fprintf(table->out,"extsymm = %d",extsymm); + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); } if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - table->groupcheck == CUDD_GROUP_CHECK7) { - (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); - (void) fprintf(table->out,"secdiff = %d\n",secdiff); - (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); } #endif if (tempTree) - Cudd_FreeZddTree(table); + Cudd_FreeZddTree(table); return(result); } /* end of cuddZddTreeSifting */ @@ -332,17 +360,17 @@ zddTreeSiftingAux( auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - if (!zddTreeSiftingAux(table, auxnode->child, method)) - return(0); - res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); - if (res == 0) - return(0); - } else if (auxnode->size > 1) { - if (!zddReorderChildren(table, auxnode, method)) - return(0); - } - auxnode = auxnode->younger; + if (auxnode->child != NULL) { + if (!zddTreeSiftingAux(table, auxnode->child, method)) + return(0); + res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!zddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; } return(1); @@ -373,12 +401,12 @@ zddCountInternalMtrNodes( nodeCount = 0; auxnode = treenode; while (auxnode != NULL) { - if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { - nodeCount++; - count = zddCountInternalMtrNodes(table,auxnode->child); - nodeCount += count; - } - auxnode = auxnode->younger; + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = zddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; } return(nodeCount); @@ -415,61 +443,61 @@ zddReorderChildren( zddFindNodeHiLo(table,treenode,&lower,&upper); /* If upper == -1 these variables do not exist yet. */ if (upper == -1) - return(1); + return(1); if (treenode->flags == MTR_FIXED) { - result = 1; + result = 1; } else { #ifdef DD_STATS - (void) fprintf(table->out," "); + (void) fprintf(table->out," "); #endif - switch (method) { - case CUDD_REORDER_RANDOM: - case CUDD_REORDER_RANDOM_PIVOT: - result = cuddZddSwapping(table,lower,upper,method); - break; - case CUDD_REORDER_SIFT: - result = cuddZddSifting(table,lower,upper); - break; - case CUDD_REORDER_SIFT_CONVERGE: - do { - initialSize = table->keysZ; - result = cuddZddSifting(table,lower,upper); - if (initialSize <= table->keysZ) + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddZddSwapping(table,lower,upper,method); break; + case CUDD_REORDER_SIFT: + result = cuddZddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_SYMM_SIFT: - result = cuddZddSymmSifting(table,lower,upper); - break; - case CUDD_REORDER_SYMM_SIFT_CONV: - result = cuddZddSymmSiftingConv(table,lower,upper); - break; - case CUDD_REORDER_GROUP_SIFT: - result = zddGroupSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR: - result = cuddZddLinearSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR_CONVERGE: - do { - initialSize = table->keysZ; - result = cuddZddLinearSifting(table,lower,upper); - if (initialSize <= table->keysZ) + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddZddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddZddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + result = zddGroupSifting(table,lower,upper); break; + case CUDD_REORDER_LINEAR: + result = cuddZddLinearSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddLinearSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - default: - return(0); - } + } while (result != 0); + break; + default: + return(0); + } } /* Create a single group for all the variables that were sifted, @@ -517,42 +545,42 @@ zddFindNodeHiLo( ** the values of upper that no reordering is needed. */ if ((int) treenode->low >= table->sizeZ) { - *lower = table->sizeZ; - *upper = -1; - return; + *lower = table->sizeZ; + *upper = -1; + return; } *lower = low = (unsigned int) table->permZ[treenode->index]; high = (int) (low + treenode->size - 1); if (high >= table->sizeZ) { - /* This is the case of a partially existing group. The aim is to - ** reorder as many variables as safely possible. If the tree - ** node is terminal, we just reorder the subset of the group - ** that is currently in existence. If the group has - ** subgroups, then we only reorder those subgroups that are - ** fully instantiated. This way we avoid breaking up a group. - */ - MtrNode *auxnode = treenode->child; - if (auxnode == NULL) { - *upper = (unsigned int) table->sizeZ - 1; - } else { - /* Search the subgroup that strands the table->sizeZ line. - ** If the first group starts at 0 and goes past table->sizeZ - ** upper will get -1, thus correctly signaling that no reordering - ** should take place. + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. */ - while (auxnode != NULL) { - int thisLower = table->permZ[auxnode->low]; - int thisUpper = thisLower + auxnode->size - 1; - if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) - *upper = (unsigned int) thisLower - 1; - auxnode = auxnode->younger; + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->sizeZ - 1; + } else { + /* Search the subgroup that strands the table->sizeZ line. + ** If the first group starts at 0 and goes past table->sizeZ + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->permZ[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } } - } } else { - /* Normal case: All the variables of the group exist. */ - *upper = (unsigned int) high; + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; } #ifdef DD_DEBUG @@ -584,7 +612,7 @@ zddUniqueCompareGroup( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -611,16 +639,16 @@ zddGroupSifting( int lower, int upper) { - int *var; - int i,j,x,xInit; - int nvars; - int classes; - int result; - int *sifted; + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; #ifdef DD_STATS unsigned previousSize; #endif - int xindex; + int xindex; nvars = table->sizeZ; @@ -629,77 +657,77 @@ zddGroupSifting( sifted = NULL; var = ABC_ALLOC(int,nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } entry = ABC_ALLOC(int,nvars); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } sifted = ABC_ALLOC(int,nvars); if (sifted == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } /* Here we consider only one representative for each group. */ for (i = 0, classes = 0; i < nvars; i++) { - sifted[i] = 0; - x = table->permZ[i]; - if ((unsigned) x >= table->subtableZ[x].next) { - entry[i] = table->subtableZ[x].keys; - var[classes] = i; - classes++; - } + sifted[i] = 0; + x = table->permZ[i]; + if ((unsigned) x >= table->subtableZ[x].next) { + entry[i] = table->subtableZ[x].keys; + var[classes] = i; + classes++; + } } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))zddUniqueCompareGroup); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - xindex = var[i]; - if (sifted[xindex] == 1) /* variable already sifted as part of group */ - continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; x = table->permZ[xindex]; /* find current level of this variable */ - if (x < lower || x > upper) - continue; + if (x < lower || x > upper) + continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtableZ[x].next); #endif - result = zddGroupSiftingAux(table,x,lower,upper); - if (!result) goto zddGroupSiftingOutOfMem; + result = zddGroupSiftingAux(table,x,lower,upper); + if (!result) goto zddGroupSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > previousSize) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > previousSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - /* Mark variables in the group just sifted. */ - x = table->permZ[xindex]; - if ((unsigned) x != table->subtableZ[x].next) { - xInit = x; - do { - j = table->invpermZ[x]; - sifted[j] = 1; - x = table->subtableZ[x].next; - } while (x != xInit); - } + /* Mark variables in the group just sifted. */ + x = table->permZ[xindex]; + if ((unsigned) x != table->subtableZ[x].next) { + xInit = x; + do { + j = table->invpermZ[x]; + sifted[j] = 1; + x = table->subtableZ[x].next; + } while (x != xInit); + } #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); + if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); #endif } /* for */ @@ -710,9 +738,9 @@ zddGroupSifting( return(1); zddGroupSiftingOutOfMem: - if (entry != NULL) ABC_FREE(entry); + if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - if (sifted != NULL) ABC_FREE(sifted); + if (sifted != NULL) ABC_FREE(sifted); return(0); @@ -742,7 +770,7 @@ zddGroupSiftingAux( int xHigh) { Move *move; - Move *moves; /* list of moves */ + Move *moves; /* list of moves */ int initialSize; int result; @@ -757,25 +785,25 @@ zddGroupSiftingAux( if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtableZ[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtableZ[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */ #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtableZ[x].next); #endif /* Find top of x's group */ @@ -783,27 +811,27 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xLow, unless early term */ + /* at this point x == xLow, unless early term */ - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ /* Find top of group */ - if (moves) { - x = moves->y; - } - while ((unsigned) x < table->subtableZ[x].next) + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; #ifdef DD_DEBUG /* x should be the top of a group */ assert((unsigned) x <= table->subtableZ[x].next); @@ -812,10 +840,10 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; @@ -825,13 +853,13 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ if (moves) { - x = moves->x; - } - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; + x = moves->x; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; #ifdef DD_DEBUG /* x is bottom of a group */ assert((unsigned) x >= table->subtableZ[x].next); @@ -840,17 +868,17 @@ zddGroupSiftingAux( if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -859,7 +887,7 @@ zddGroupSiftingAux( zddGroupSiftingAuxOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -895,9 +923,6 @@ zddGroupSiftingUp( int size; int gxtop; int limitSize; - int xindex, yindex; - - yindex = table->invpermZ[y]; limitSize = table->keysZ; @@ -905,9 +930,8 @@ zddGroupSiftingUp( while (x >= xLow) { gxtop = table->subtableZ[x].next; if (table->subtableZ[x].next == (unsigned) x && - table->subtableZ[y].next == (unsigned) y) { + table->subtableZ[y].next == (unsigned) y) { /* x and y are self groups */ - xindex = table->invpermZ[x]; size = cuddZddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtableZ[x].next == (unsigned) x); @@ -918,22 +942,22 @@ zddGroupSiftingUp( if (move == NULL) goto zddGroupSiftingUpOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } else { /* group move */ size = zddGroupMove(table,x,y,moves); - if (size == 0) goto zddGroupSiftingUpOutOfMem; + if (size == 0) goto zddGroupSiftingUpOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } y = gxtop; @@ -945,7 +969,7 @@ zddGroupSiftingUp( zddGroupSiftingUpOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -975,23 +999,20 @@ zddGroupSiftingDown( int y; int size; int limitSize; - int gxtop,gybot; - int xindex; + int gybot; /* Initialize R */ - xindex = table->invpermZ[x]; - gxtop = table->subtableZ[x].next; limitSize = size = table->keysZ; y = cuddZddNextHigh(table,x); while (y <= xHigh) { - /* Find bottom of y group. */ + /* Find bottom of y group. */ gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) gybot = table->subtableZ[gybot].next; if (table->subtableZ[x].next == (unsigned) x && - table->subtableZ[y].next == (unsigned) y) { + table->subtableZ[y].next == (unsigned) y) { /* x and y are self groups */ size = cuddZddSwapInPlace(table,x,y); #ifdef DD_DEBUG @@ -1000,12 +1021,12 @@ zddGroupSiftingDown( #endif if (size == 0) goto zddGroupSiftingDownOutOfMem; - /* Record move. */ + /* Record move. */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) goto zddGroupSiftingDownOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; @@ -1022,7 +1043,7 @@ zddGroupSiftingDown( size = zddGroupMove(table,x,y,moves); if (size == 0) goto zddGroupSiftingDownOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } x = gybot; @@ -1034,7 +1055,7 @@ zddGroupSiftingDown( zddGroupSiftingDownOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } @@ -1063,12 +1084,12 @@ zddGroupMove( Move *move; int size; int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx = 0,swapy = 0; // Suppress "might be used uninitialized" + int swapx,swapy; #if defined(DD_DEBUG) && defined(DD_VERBOSE) int initialSize,bestSize; #endif -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1091,8 +1112,8 @@ zddGroupMove( size = cuddZddSwapInPlace(table,x,y); if (size == 0) goto zddGroupMoveOutOfMem; #if defined(DD_DEBUG) && defined(DD_VERBOSE) - if (size < bestSize) - bestSize = size; + if (size < bestSize) + bestSize = size; #endif swapx = x; swapy = y; y = x; @@ -1103,7 +1124,7 @@ zddGroupMove( } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if ((bestSize < initialSize) && (bestSize < size)) - (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); #endif /* fix groups */ @@ -1141,7 +1162,7 @@ zddGroupMove( zddGroupMoveOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1169,7 +1190,7 @@ zddGroupMoveBackward( int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1252,7 +1273,7 @@ zddGroupSiftingBackward( for (move = moves; move != NULL; move = move->next) { if (move->size == size) return(1); if ((table->subtableZ[move->x].next == move->x) && - (table->subtableZ[move->y].next == move->y)) { + (table->subtableZ[move->y].next == move->y)) { res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); #ifdef DD_DEBUG @@ -1261,8 +1282,8 @@ zddGroupSiftingBackward( assert(table->subtableZ[move->y].next == move->y); #endif } else { /* Group move necessary */ - res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); - if (!res) return(0); + res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); } } @@ -1297,9 +1318,9 @@ zddMergeGroups( ** this is the topmost group. In such a case we do not merge lest ** we lose the symmetry information. */ if (treenode != table->treeZ) { - for (i = low; i < high; i++) - table->subtableZ[i].next = i+1; - table->subtableZ[high].next = low; + for (i = low; i < high; i++) + table->subtableZ[i].next = i+1; + table->subtableZ[high].next = low; } /* Adjust the index fields of the tree nodes. If a node is the @@ -1308,15 +1329,16 @@ zddMergeGroups( newindex = table->invpermZ[low]; auxnode = treenode; do { - auxnode->index = newindex; - if (auxnode->parent == NULL || - (int) auxnode->parent->index != saveindex) - break; - auxnode = auxnode->parent; + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; } while (1); return; } /* end of zddMergeGroups */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddIsop.c b/src/bdd/cudd/cuddZddIsop.c index cd7c16bf..1de9110a 100644 --- a/src/bdd/cudd/cuddZddIsop.c +++ b/src/bdd/cudd/cuddZddIsop.c @@ -7,39 +7,67 @@ Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddIsop() - <li> Cudd_zddIsop() - <li> Cudd_MakeBddFromZddCover() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddIsop() - <li> cuddZddIsop() - <li> cuddMakeBddFromZddCover() - </ul> - Static procedures included in this module: - <ul> - </ul> - ] + <ul> + <li> Cudd_bddIsop() + <li> Cudd_zddIsop() + <li> Cudd_MakeBddFromZddCover() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddIsop() + <li> cuddZddIsop() + <li> cuddMakeBddFromZddCover() + </ul> + Static procedures included in this module: + <ul> + </ul> + ] SeeAlso [] Author [In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,7 +88,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.20 2009/02/19 16:26:12 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -104,22 +132,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.1.1.1 2003/02/24 22:23:5 SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I) { - DdNode *res; - int autoDynZ; + DdNode *res; + int autoDynZ; autoDynZ = dd->autoDynZ; dd->autoDynZ = 0; do { - dd->reordered = 0; - res = cuddZddIsop(dd, L, U, zdd_I); + dd->reordered = 0; + res = cuddZddIsop(dd, L, U, zdd_I); } while (dd->reordered == 1); dd->autoDynZ = autoDynZ; return(res); @@ -142,17 +170,17 @@ Cudd_zddIsop( SeeAlso [Cudd_zddIsop] ******************************************************************************/ -DdNode * +DdNode * Cudd_bddIsop( DdManager * dd, DdNode * L, DdNode * U) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddBddIsop(dd, L, U); + dd->reordered = 0; + res = cuddBddIsop(dd, L, U); } while (dd->reordered == 1); return(res); @@ -171,16 +199,16 @@ Cudd_bddIsop( SeeAlso [cuddMakeBddFromZddCover] ******************************************************************************/ -DdNode * +DdNode * Cudd_MakeBddFromZddCover( DdManager * dd, DdNode * node) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddMakeBddFromZddCover(dd, node); + dd->reordered = 0; + res = cuddMakeBddFromZddCover(dd, node); } while (dd->reordered == 1); return(res); } /* end of Cudd_MakeBddFromZddCover */ @@ -202,42 +230,42 @@ Cudd_MakeBddFromZddCover( SeeAlso [Cudd_zddIsop] ******************************************************************************/ -DdNode * +DdNode * cuddZddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I) { - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - DdNode *zdd_one = DD_ONE(dd); - DdNode *zdd_zero = DD_ZERO(dd); - int v, top_l, top_u; - DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; - DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; - DdNode *Isub0, *Isub1, *Id; - DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; - DdNode *x; - DdNode *term0, *term1, *sum; - DdNode *Lv, *Uv, *Lnv, *Unv; - DdNode *r, *y, *z; - int index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r, *y, *z; + int index; + DD_CTFP cacheOp; statLine(dd); if (L == zero) { - *zdd_I = zdd_zero; + *zdd_I = zdd_zero; return(zero); } if (U == one) { - *zdd_I = zdd_one; + *zdd_I = zdd_one; return(one); } if (U == zero || L == one) { - printf("*** ERROR : illegal condition for ISOP (U < L).\n"); - exit(1); + printf("*** ERROR : illegal condition for ISOP (U < L).\n"); + exit(1); } /* Check the cache. We store two results for each recursive call. @@ -245,19 +273,19 @@ cuddZddIsop( ** Hence we need a double hit in the cache to terminate the ** recursion. Clearly, collisions may evict only one of the two ** results. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) cuddZddIsop; + cacheOp = (DD_CTFP) cuddZddIsop; r = cuddCacheLookup2(dd, cuddBddIsop, L, U); if (r) { - *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); - if (*zdd_I) - return(r); - else { - /* The BDD result may have been dead. In that case - ** cuddCacheLookup2 would have called cuddReclaim, - ** whose effects we now have to undo. */ - cuddRef(r); - Cudd_RecursiveDeref(dd, r); - } + *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); + if (*zdd_I) + return(r); + else { + /* The BDD result may have been dead. In that case + ** cuddCacheLookup2 would have called cuddReclaim, + ** whose effects we now have to undo. */ + cuddRef(r); + Cudd_RecursiveDeref(dd, r); + } } top_l = dd->perm[Cudd_Regular(L)->index]; @@ -266,7 +294,7 @@ cuddZddIsop( /* Compute cofactors. */ if (top_l == v) { - index = Cudd_Regular(L)->index; + index = Cudd_Regular(L)->index; Lv = Cudd_T(L); Lnv = Cudd_E(L); if (Cudd_IsComplement(L)) { @@ -275,7 +303,7 @@ cuddZddIsop( } } else { - index = Cudd_Regular(U)->index; + index = Cudd_Regular(U)->index; Lv = Lnv = L; } @@ -293,45 +321,45 @@ cuddZddIsop( Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); if (Lsub0 == NULL) - return(NULL); + return(NULL); Cudd_Ref(Lsub0); Usub0 = Unv; Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); if (Lsub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); } Cudd_Ref(Lsub1); Usub1 = Uv; Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0); if (Isub0 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Isub0))) && - (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Isub0); Cudd_Ref(zdd_Isub0); Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1); if (Isub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Isub1))) && - (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Isub1); @@ -341,21 +369,21 @@ cuddZddIsop( Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); if (Lsuper0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + return(NULL); } Cudd_Ref(Lsuper0); Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); if (Lsuper1 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); } Cudd_Ref(Lsuper1); Usuper0 = Unv; @@ -364,27 +392,27 @@ cuddZddIsop( /* Ld = Lsuper0 + Lsuper1 */ Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); if (Ld == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); } Ld = Cudd_Not(Ld); Cudd_Ref(Ld); /* Ud = Usuper0 * Usuper1 */ Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); if (Ud == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - Cudd_RecursiveDeref(dd, Ld); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); } Cudd_Ref(Ud); Cudd_RecursiveDeref(dd, Lsuper0); @@ -392,19 +420,19 @@ cuddZddIsop( Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id); if (Id == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Ld); - Cudd_RecursiveDeref(dd, Ud); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Id))) && - (Cudd_Regular(Id)->index != zdd_Id->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Id)->index != zdd_Id->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Id); @@ -414,40 +442,40 @@ cuddZddIsop( x = cuddUniqueInter(dd, index, one, zero); if (x == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + return(NULL); } Cudd_Ref(x); /* term0 = x * Isub0 */ term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); if (term0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, x); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); } Cudd_Ref(term0); Cudd_RecursiveDeref(dd, Isub0); /* term1 = x * Isub1 */ term1 = cuddBddAndRecur(dd, x, Isub1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, x); - Cudd_RecursiveDeref(dd, term0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); } Cudd_Ref(term1); Cudd_RecursiveDeref(dd, x); @@ -455,13 +483,13 @@ cuddZddIsop( /* sum = term0 + term1 */ sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); if (sum == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, term0); - Cudd_RecursiveDeref(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); } sum = Cudd_Not(sum); Cudd_Ref(sum); @@ -471,44 +499,44 @@ cuddZddIsop( r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); r = Cudd_NotCond(r, r != NULL); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, sum); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDeref(dd, sum); Cudd_RecursiveDeref(dd, Id); if (zdd_Isub0 != zdd_zero) { - z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); - if (z == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, r); - return(NULL); - } + z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); + if (z == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + return(NULL); + } } else { - z = zdd_Id; + z = zdd_Id; } Cudd_Ref(z); if (zdd_Isub1 != zdd_zero) { - y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); - if (y == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, r); - Cudd_RecursiveDerefZdd(dd, z); - return(NULL); - } + y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); + if (y == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + Cudd_RecursiveDerefZdd(dd, z); + return(NULL); + } } else - y = z; + y = z; Cudd_Ref(y); Cudd_RecursiveDerefZdd(dd, zdd_Isub0); @@ -524,7 +552,7 @@ cuddZddIsop( *zdd_I = y; /* if (Cudd_Regular(r)->index != y->index / 2) { - printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); + printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); } */ return(r); @@ -543,23 +571,23 @@ cuddZddIsop( SeeAlso [Cudd_bddIsop] ******************************************************************************/ -DdNode * +DdNode * cuddBddIsop( DdManager * dd, DdNode * L, DdNode * U) { - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - int v, top_l, top_u; - DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; - DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; - DdNode *Isub0, *Isub1, *Id; - DdNode *x; - DdNode *term0, *term1, *sum; - DdNode *Lv, *Uv, *Lnv, *Unv; - DdNode *r; - int index; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r; + int index; statLine(dd); if (L == zero) @@ -578,7 +606,7 @@ cuddBddIsop( /* Compute cofactors */ if (top_l == v) { - index = Cudd_Regular(L)->index; + index = Cudd_Regular(L)->index; Lv = Cudd_T(L); Lnv = Cudd_E(L); if (Cudd_IsComplement(L)) { @@ -587,7 +615,7 @@ cuddBddIsop( } } else { - index = Cudd_Regular(U)->index; + index = Cudd_Regular(U)->index; Lv = Lnv = L; } @@ -605,30 +633,30 @@ cuddBddIsop( Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); if (Lsub0 == NULL) - return(NULL); + return(NULL); Cudd_Ref(Lsub0); Usub0 = Unv; Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); if (Lsub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); } Cudd_Ref(Lsub1); Usub1 = Uv; Isub0 = cuddBddIsop(dd, Lsub0, Usub0); if (Isub0 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); } Cudd_Ref(Isub0); Isub1 = cuddBddIsop(dd, Lsub1, Usub1); if (Isub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - Cudd_RecursiveDeref(dd, Isub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + return(NULL); } Cudd_Ref(Isub1); Cudd_RecursiveDeref(dd, Lsub0); @@ -636,17 +664,17 @@ cuddBddIsop( Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); if (Lsuper0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + return(NULL); } Cudd_Ref(Lsuper0); Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); if (Lsuper1 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); } Cudd_Ref(Lsuper1); Usuper0 = Unv; @@ -656,21 +684,21 @@ cuddBddIsop( Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); Ld = Cudd_NotCond(Ld, Ld != NULL); if (Ld == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); } Cudd_Ref(Ld); Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); if (Ud == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - Cudd_RecursiveDeref(dd, Ld); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); } Cudd_Ref(Ud); Cudd_RecursiveDeref(dd, Lsuper0); @@ -678,11 +706,11 @@ cuddBddIsop( Id = cuddBddIsop(dd, Ld, Ud); if (Id == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Ld); - Cudd_RecursiveDeref(dd, Ud); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); } Cudd_Ref(Id); Cudd_RecursiveDeref(dd, Ld); @@ -690,29 +718,29 @@ cuddBddIsop( x = cuddUniqueInter(dd, index, one, zero); if (x == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + return(NULL); } Cudd_Ref(x); term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); if (term0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, x); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); } Cudd_Ref(term0); Cudd_RecursiveDeref(dd, Isub0); term1 = cuddBddAndRecur(dd, x, Isub1); if (term1 == NULL) { - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, x); - Cudd_RecursiveDeref(dd, term0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); } Cudd_Ref(term1); Cudd_RecursiveDeref(dd, x); @@ -721,10 +749,10 @@ cuddBddIsop( sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); sum = Cudd_NotCond(sum, sum != NULL); if (sum == NULL) { - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, term0); - Cudd_RecursiveDeref(dd, term1); - return(NULL); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); } Cudd_Ref(sum); Cudd_RecursiveDeref(dd, term0); @@ -733,9 +761,9 @@ cuddBddIsop( r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); r = Cudd_NotCond(r, r != NULL); if (r == NULL) { - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, sum); - return(NULL); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDeref(dd, sum); @@ -768,108 +796,108 @@ cuddBddIsop( SeeAlso [Cudd_MakeBddFromZddCover] ******************************************************************************/ -DdNode * +DdNode * cuddMakeBddFromZddCover( DdManager * dd, DdNode * node) { - DdNode *neW; - int v; - DdNode *f1, *f0, *fd; - DdNode *b1, *b0, *bd; - DdNode *T, *E; + DdNode *neW; + int v; + DdNode *f1, *f0, *fd; + DdNode *b1, *b0, *bd; + DdNode *T, *E; statLine(dd); if (node == dd->one) - return(dd->one); + return(dd->one); if (node == dd->zero) - return(Cudd_Not(dd->one)); + return(Cudd_Not(dd->one)); /* Check cache */ neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); if (neW) - return(neW); + return(neW); - v = Cudd_Regular(node)->index; /* either yi or zi */ - cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd); + v = Cudd_Regular(node)->index; /* either yi or zi */ + if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); b1 = cuddMakeBddFromZddCover(dd, f1); if (!b1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(b1); b0 = cuddMakeBddFromZddCover(dd, f0); - if (!b1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDeref(dd, b1); - return(NULL); + if (!b0) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + return(NULL); } Cudd_Ref(b0); Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); if (fd != dd->zero) { - bd = cuddMakeBddFromZddCover(dd, fd); - if (!bd) { + bd = cuddMakeBddFromZddCover(dd, fd); + if (!bd) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + return(NULL); + } + Cudd_Ref(bd); Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDeref(dd, b1); - Cudd_RecursiveDeref(dd, b0); - return(NULL); - } - Cudd_Ref(bd); - Cudd_RecursiveDerefZdd(dd, fd); - T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); - if (!T) { + T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); + if (!T) { + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + return(NULL); + } + T = Cudd_NotCond(T, T != NULL); + Cudd_Ref(T); Cudd_RecursiveDeref(dd, b1); + E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); + if (!E) { + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + E = Cudd_NotCond(E, E != NULL); + Cudd_Ref(E); Cudd_RecursiveDeref(dd, b0); Cudd_RecursiveDeref(dd, bd); - return(NULL); - } - T = Cudd_NotCond(T, T != NULL); - Cudd_Ref(T); - Cudd_RecursiveDeref(dd, b1); - E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); - if (!E) { - Cudd_RecursiveDeref(dd, b0); - Cudd_RecursiveDeref(dd, bd); - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - E = Cudd_NotCond(E, E != NULL); - Cudd_Ref(E); - Cudd_RecursiveDeref(dd, b0); - Cudd_RecursiveDeref(dd, bd); } else { - Cudd_RecursiveDerefZdd(dd, fd); - T = b1; - E = b0; + Cudd_RecursiveDerefZdd(dd, fd); + T = b1; + E = b0; } if (Cudd_IsComplement(T)) { - neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); - if (!neW) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } - neW = Cudd_Not(neW); + neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + neW = Cudd_Not(neW); } else { - neW = cuddUniqueInterIVO(dd, v / 2, T, E); - if (!neW) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + neW = cuddUniqueInterIVO(dd, v / 2, T, E); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } Cudd_Ref(neW); Cudd_RecursiveDeref(dd, T); @@ -886,5 +914,6 @@ cuddMakeBddFromZddCover( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddLin.c b/src/bdd/cudd/cuddZddLin.c index 14cad0b1..0c364413 100644 --- a/src/bdd/cudd/cuddZddLin.c +++ b/src/bdd/cudd/cuddZddLin.c @@ -7,37 +7,65 @@ Synopsis [Procedures for dynamic variable ordering of ZDDs.] Description [Internal procedures included in this module: - <ul> - <li> cuddZddLinearSifting() - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddLinearInPlace() - <li> cuddZddLinerAux() - <li> cuddZddLinearUp() - <li> cuddZddLinearDown() - <li> cuddZddLinearBackward() - <li> cuddZddUndoMoves() - </ul> - ] + <ul> + <li> cuddZddLinearSifting() + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddLinearInPlace() + <li> cuddZddLinerAux() + <li> cuddZddLinearUp() + <li> cuddZddLinearDown() + <li> cuddZddLinearBackward() + <li> cuddZddUndoMoves() + </ul> + ] SeeAlso [cuddLinear.c cuddZddReord.c] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -61,13 +89,13 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"; #endif -extern int *zdd_entry; -extern int zddTotalNumberSwapping; -static int zddTotalNumberLinearTr; -static DdNode *empty; +extern int *zdd_entry; +extern int zddTotalNumberSwapping; +static int zddTotalNumberLinearTr; +static DdNode *empty; /*---------------------------------------------------------------------------*/ @@ -81,11 +109,12 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddLinearAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * cuddZddLinearUp ARGS((DdManager *table, int y, int xLow, Move *prevMoves)); -static Move * cuddZddLinearDown ARGS((DdManager *table, int x, int xHigh, Move *prevMoves)); -static int cuddZddLinearBackward ARGS((DdManager *table, int size, Move *moves)); -static Move* cuddZddUndoMoves ARGS((DdManager *table, Move *moves)); +static int cuddZddLinearInPlace (DdManager * table, int x, int y); +static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh); +static Move * cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int cuddZddLinearBackward (DdManager *table, int size, Move *moves); +static Move* cuddZddUndoMoves (DdManager *table, Move *moves); /**AutomaticEnd***************************************************************/ @@ -129,13 +158,13 @@ cuddZddLinearSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->sizeZ; @@ -145,45 +174,45 @@ cuddZddLinearSifting( var = NULL; zdd_entry = ABC_ALLOC(int, size); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } var = ABC_ALLOC(int, size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddLinearAux(table, x, lower, upper); - if (!result) - goto cuddZddSiftingOutOfMem; + result = cuddZddLinearAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -222,23 +251,23 @@ cuddZddSiftingOutOfMem: SeeAlso [cuddZddSwapInPlace cuddLinearInPlace] ******************************************************************************/ -int +static int cuddZddLinearInPlace( DdManager * table, int x, int y) { DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; int oldxkeys, oldykeys; int newxkeys, newykeys; - int i; - int posn; - DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; - DdNode *newf1, *newf0, *g, *next, *previous; - DdNode *special; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *g, *next, *previous; + DdNode *special; #ifdef DD_DEBUG assert(x < y); @@ -274,61 +303,61 @@ cuddZddLinearInPlace( */ g = special = NULL; for (i = 0; i < xslots; i++) { - f = xlist[i]; - if (f == NULL) continue; - xlist[i] = NULL; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); - /* if (f1->index == yindex) */ cuddSatDec(f1->ref); - f0 = cuddE(f); - /* if (f0->index == yindex) */ cuddSatDec(f0->ref); - if ((int) f1->index == yindex && cuddE(f1) == empty && - (int) f0->index != yindex) { - f->next = special; - special = f; - } else { - f->next = g; - g = f; - } - f = next; - } /* while there are elements in the collision chain */ + f = xlist[i]; + if (f == NULL) continue; + xlist[i] = NULL; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + /* if (f1->index == yindex) */ cuddSatDec(f1->ref); + f0 = cuddE(f); + /* if (f0->index == yindex) */ cuddSatDec(f0->ref); + if ((int) f1->index == yindex && cuddE(f1) == empty && + (int) f0->index != yindex) { + f->next = special; + special = f; + } else { + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ } /* for each slot of the x subtable */ /* Mark y nodes with pointers from above x. We mark them by ** changing their index to x. */ for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != NULL) { - if (f->ref != 0) { - f->index = xindex; - } - f = f->next; - } /* while there are elements in the collision chain */ + f = ylist[i]; + while (f != NULL) { + if (f->ref != 0) { + f->index = xindex; + } + f = f->next; + } /* while there are elements in the collision chain */ } /* for each slot of the y subtable */ /* Move special nodes to the y list. */ f = special; while (f != NULL) { - next = f->next; - f1 = cuddT(f); - f11 = cuddT(f1); - cuddT(f) = f11; - cuddSatInc(f11->ref); - f0 = cuddE(f); - cuddSatInc(f0->ref); - f->index = yindex; - /* Insert at the beginning of the list so that it will be - ** found first if there is a duplicate. The duplicate will - ** eventually be moved or garbage collected. No node - ** re-expression will add a pointer to it. - */ - posn = ddHash(f11, f0, yshift); - f->next = ylist[posn]; - ylist[posn] = f; - newykeys++; - f = next; + next = f->next; + f1 = cuddT(f); + f11 = cuddT(f1); + cuddT(f) = f11; + cuddSatInc(f11->ref); + f0 = cuddE(f); + cuddSatInc(f0->ref); + f->index = yindex; + /* Insert at the beginning of the list so that it will be + ** found first if there is a duplicate. The duplicate will + ** eventually be moved or garbage collected. No node + ** re-expression will add a pointer to it. + */ + posn = ddHash(f11, f0, yshift); + f->next = ylist[posn]; + ylist[posn] = f; + newykeys++; + f = next; } /* Take care of the remaining x nodes that must be re-expressed. @@ -337,172 +366,172 @@ cuddZddLinearInPlace( f = g; while (f != NULL) { #ifdef DD_COUNT - table->swapSteps++; + table->swapSteps++; #endif - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - if ((int) f1->index == yindex || (int) f1->index == xindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = empty; f10 = f1; - } - f0 = cuddE(f); - if ((int) f0->index == yindex || (int) f0->index == xindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = empty; f00 = f0; - } - /* Create the new T child. */ - if (f01 == empty) { - newf1 = f10; - cuddSatInc(newf1->ref); - } else { - /* Check ylist for triple (yindex, f01, f10). */ - posn = ddHash(f01, f10, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - newf1 = ylist[posn]; - /* Search the collision chain skipping the marked nodes. */ - while (newf1 != NULL) { - if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && - (int) newf1->index == yindex) { - cuddSatInc(newf1->ref); - break; /* match */ + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex || (int) f1->index == xindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f01; - cuddE(newf1) = f10; - /* Insert newf1 in the collision list ylist[pos]; - ** increase the ref counts of f01 and f10 - */ - newykeys++; - newf1->next = ylist[posn]; - ylist[posn] = newf1; - cuddSatInc(f01->ref); - cuddSatInc(f10->ref); + f0 = cuddE(f); + if ((int) f0->index == yindex || (int) f0->index == xindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; } - } - cuddT(f) = newf1; + /* Create the new T child. */ + if (f01 == empty) { + newf1 = f10; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex, f01, f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + /* Search the collision chain skipping the marked nodes. */ + while (newf1 != NULL) { + if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f01; + cuddE(newf1) = f10; + /* Insert newf1 in the collision list ylist[pos]; + ** increase the ref counts of f01 and f10 + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + cuddSatInc(f01->ref); + cuddSatInc(f10->ref); + } + } + cuddT(f) = newf1; - /* Do the same for f0. */ - /* Create the new E child. */ - if (f11 == empty) { - newf0 = f00; - cuddSatInc(newf0->ref); - } else { - /* Check ylist for triple (yindex, f11, f00). */ - posn = ddHash(f11, f00, yshift); - /* For each element newf0 in collision list ylist[posn]. */ - newf0 = ylist[posn]; - while (newf0 != NULL) { - if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && - (int) newf0->index == yindex) { + /* Do the same for f0. */ + /* Create the new E child. */ + if (f11 == empty) { + newf0 = f00; cuddSatInc(newf0->ref); - break; /* match */ - } - newf0 = newf0->next; - } /* while newf0 */ - if (newf0 == NULL) { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto zddSwapOutOfMem; - newf0->index = yindex; newf0->ref = 1; - cuddT(newf0) = f11; cuddE(newf0) = f00; - /* Insert newf0 in the collision list ylist[posn]; - ** increase the ref counts of f11 and f00. - */ - newykeys++; - newf0->next = ylist[posn]; - ylist[posn] = newf0; - cuddSatInc(f11->ref); - cuddSatInc(f00->ref); + } else { + /* Check ylist for triple (yindex, f11, f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + newf0 = ylist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && + (int) newf0->index == yindex) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f11; cuddE(newf0) = f00; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf0->next = ylist[posn]; + ylist[posn] = newf0; + cuddSatInc(f11->ref); + cuddSatInc(f00->ref); + } } - } - cuddE(f) = newf0; + cuddE(f) = newf0; - /* Re-insert the modified f in xlist. - ** The modified f does not already exists in xlist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, xshift); - newxkeys++; - f->next = xlist[posn]; - xlist[posn] = f; - f = next; + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + f->next = xlist[posn]; + xlist[posn] = f; + f = next; } /* while f != NULL */ /* GC the y layer and move the marked nodes to the x list. */ /* For each node f in ylist. */ for (i = 0; i < yslots; i++) { - previous = NULL; - f = ylist[i]; - while (f != NULL) { - next = f->next; - if (f->ref == 0) { - cuddSatDec(cuddT(f)->ref); - cuddSatDec(cuddE(f)->ref); - cuddDeallocNode(table, f); - newykeys--; - if (previous == NULL) - ylist[i] = next; - else - previous->next = next; - } else if ((int) f->index == xindex) { /* move marked node */ - if (previous == NULL) - ylist[i] = next; - else - previous->next = next; - f1 = cuddT(f); - cuddSatDec(f1->ref); - /* Check ylist for triple (yindex, f1, empty). */ - posn = ddHash(f1, empty, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - newf1 = ylist[posn]; - while (newf1 != NULL) { - if (cuddT(newf1) == f1 && cuddE(newf1) == empty && - (int) newf1->index == yindex) { - cuddSatInc(newf1->ref); - break; /* match */ + previous = NULL; + f = ylist[i]; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + } else if ((int) f->index == xindex) { /* move marked node */ + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + f1 = cuddT(f); + cuddSatDec(f1->ref); + /* Check ylist for triple (yindex, f1, empty). */ + posn = ddHash(f1, empty, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f1 && cuddE(newf1) == empty && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f1; cuddE(newf1) = empty; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f1 and empty. + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + if (posn == i && previous == NULL) + previous = newf1; + cuddSatInc(f1->ref); + cuddSatInc(empty->ref); + } + cuddT(f) = newf1; + f0 = cuddE(f); + /* Insert f in x list. */ + posn = ddHash(newf1, f0, xshift); + newxkeys++; + newykeys--; + f->next = xlist[posn]; + xlist[posn] = f; + } else { + previous = f; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f1; cuddE(newf1) = empty; - /* Insert newf1 in the collision list ylist[posn]; - ** increase the ref counts of f1 and empty. - */ - newykeys++; - newf1->next = ylist[posn]; - ylist[posn] = newf1; - if (posn == i && previous == NULL) - previous = newf1; - cuddSatInc(f1->ref); - cuddSatInc(empty->ref); - } - cuddT(f) = newf1; - f0 = cuddE(f); - /* Insert f in x list. */ - posn = ddHash(newf1, f0, xshift); - newxkeys++; - newykeys--; - f->next = xlist[posn]; - xlist[posn] = f; - } else { - previous = f; - } - f = next; - } /* while f */ + f = next; + } /* while f */ } /* for i */ /* Set the appropriate fields in table. */ @@ -551,12 +580,12 @@ cuddZddLinearAux( int xLow, int xHigh) { - Move *move; - Move *moveUp; /* list of up move */ - Move *moveDown; /* list of down move */ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ - int initial_size; - int result; + int initial_size; + int result; initial_size = table->keysZ; @@ -568,88 +597,88 @@ cuddZddLinearAux( moveUp = NULL; if (x == xLow) { - moveDown = cuddZddLinearDown(table, x, xHigh, NULL); - /* At this point x --> xHigh. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveDown); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else if (x == xHigh) { - moveUp = cuddZddLinearUp(table, x, xLow, NULL); - /* At this point x --> xLow. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveUp); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xLow. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = cuddZddLinearDown(table, x, xHigh, NULL); - /* At this point x --> xHigh. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - moveUp = cuddZddUndoMoves(table,moveDown); + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddUndoMoves(table,moveDown); #ifdef DD_DEBUG - assert(moveUp == NULL || moveUp->x == x); + assert(moveUp == NULL || moveUp->x == x); #endif - moveUp = cuddZddLinearUp(table, x, xLow, moveUp); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveUp); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddLinearUp(table, x, xLow, moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else { - moveUp = cuddZddLinearUp(table, x, xLow, NULL); - /* At this point x --> xHigh. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Then move up. */ - moveDown = cuddZddUndoMoves(table,moveUp); + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xHigh. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Then move up. */ + moveDown = cuddZddUndoMoves(table,moveUp); #ifdef DD_DEBUG - assert(moveDown == NULL || moveDown->y == x); + assert(moveDown == NULL || moveDown->y == x); #endif - moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveDown); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); cuddZddLinearAuxOutOfMem: if (moveDown != (Move *) CUDD_OUT_OF_MEM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != (Move *) CUDD_OUT_OF_MEM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -678,64 +707,64 @@ cuddZddLinearUp( int xLow, Move * prevMoves) { - Move *moves; - Move *move; - int x; - int size, newsize; - int limitSize; + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; moves = prevMoves; limitSize = table->keysZ; x = cuddZddNextLow(table, y); while (x >= xLow) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddLinearUpOutOfMem; - newsize = cuddZddLinearInPlace(table, x, y); - if (newsize == 0) - goto cuddZddLinearUpOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddLinearUpOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize > size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ - newsize = cuddZddLinearInPlace(table,x,y); - if (newsize == 0) goto cuddZddLinearUpOutOfMem; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearUpOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearUpOutOfMem; #ifdef DD_DEBUG - if (newsize != size) { - (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); - } + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } #endif - } else { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - } - move->size = size; + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; - if ((double)size > (double)limitSize * table->maxGrowth) - break; + if ((double)size > (double)limitSize * table->maxGrowth) + break; if (size < limitSize) - limitSize = size; + limitSize = size; - y = x; - x = cuddZddNextLow(table, y); + y = x; + x = cuddZddNextLow(table, y); } return(moves); cuddZddLinearUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -763,62 +792,62 @@ cuddZddLinearDown( int xHigh, Move * prevMoves) { - Move *moves; - Move *move; - int y; - int size, newsize; - int limitSize; + Move *moves; + Move *move; + int y; + int size, newsize; + int limitSize; moves = prevMoves; limitSize = table->keysZ; y = cuddZddNextHigh(table, x); while (y <= xHigh) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddLinearDownOutOfMem; - newsize = cuddZddLinearInPlace(table, x, y); - if (newsize == 0) - goto cuddZddLinearDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddLinearDownOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize > size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ - newsize = cuddZddLinearInPlace(table,x,y); - if (newsize == 0) goto cuddZddLinearDownOutOfMem; - if (newsize != size) { - (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearDownOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; } - } else { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - } - move->size = size; + move->size = size; - if ((double)size > (double)limitSize * table->maxGrowth) - break; + if ((double)size > (double)limitSize * table->maxGrowth) + break; if (size < limitSize) - limitSize = size; + limitSize = size; - x = y; - y = cuddZddNextHigh(table, x); + x = y; + y = cuddZddNextHigh(table, x); } return(moves); cuddZddLinearDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -846,29 +875,29 @@ cuddZddLinearBackward( int size, Move * moves) { - Move *move; - int res; + Move *move; + int res; /* Find the minimum size among moves. */ for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) - return(0); - if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { - res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } return(1); @@ -896,49 +925,51 @@ cuddZddUndoMoves( Move *invmoves = NULL; Move *move; Move *invmove; - int size; + int size; for (move = moves; move != NULL; move = move->next) { - invmove = (Move *) cuddDynamicAllocNode(table); - if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; - invmove->x = move->x; - invmove->y = move->y; - invmove->next = invmoves; - invmoves = invmove; - if (move->flags == CUDD_SWAP_MOVE) { - invmove->flags = CUDD_SWAP_MOVE; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; - size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ #ifdef DD_DEBUG - (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); #endif - invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } - invmove->size = size; + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } + invmove->size = size; } return(invmoves); cuddZddUndoMovesOutOfMem: while (invmoves != NULL) { - move = invmoves->next; - cuddDeallocNode(table, (DdNode *) invmoves); - invmoves = move; + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of cuddZddUndoMoves */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddMisc.c b/src/bdd/cudd/cuddZddMisc.c index b78faea1..4d28f6a7 100644 --- a/src/bdd/cudd/cuddZddMisc.c +++ b/src/bdd/cudd/cuddZddMisc.c @@ -4,41 +4,69 @@ PackageName [cudd] - Synopsis [.] + Synopsis [Miscellaneous utility functions for ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddDagSize() - <li> Cudd_zddCountMinterm() - <li> Cudd_zddPrintSubtable() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddDagInt() - </ul> - ] + <ul> + <li> Cudd_zddDagSize() + <li> Cudd_zddCountMinterm() + <li> Cudd_zddPrintSubtable() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddDagInt() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include <math.h> -#include "util_hack.h" -#include "cuddInt.h" +#include <math.h> +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.16 2009/02/20 02:14:58 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -73,7 +101,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddDagInt ARGS((DdNode *n, st_table *tab)); +static int cuddZddDagInt (DdNode *n, st_table *tab); /**AutomaticEnd***************************************************************/ @@ -100,7 +128,7 @@ Cudd_zddDagSize( DdNode * p_node) { - int i; + int i; st_table *table; table = st_init_table(st_ptrcmp, st_ptrhash); @@ -132,7 +160,7 @@ Cudd_zddCountMinterm( DdNode * node, int path) { - double dc_var, minterms; + double dc_var, minterms; dc_var = (double)((double)(zdd->sizeZ) - (double)path); minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); @@ -156,61 +184,61 @@ void Cudd_zddPrintSubtable( DdManager * table) { - int i, j; - DdNode *z1, *z1_next, *base; - DdSubtable *ZSubTable; + int i, j; + DdNode *z1, *z1_next, *base; + DdSubtable *ZSubTable; base = table->one; for (i = table->sizeZ - 1; i >= 0; i--) { - ZSubTable = &(table->subtableZ[i]); - printf("subtable[%d]:\n", i); - for (j = ZSubTable->slots - 1; j >= 0; j--) { - z1 = ZSubTable->nodelist[j]; - while (z1 != NIL(DdNode)) { - (void) fprintf(table->out, + ZSubTable = &(table->subtableZ[i]); + printf("subtable[%d]:\n", i); + for (j = ZSubTable->slots - 1; j >= 0; j--) { + z1 = ZSubTable->nodelist[j]; + while (z1 != NIL(DdNode)) { + (void) fprintf(table->out, #if SIZEOF_VOID_P == 8 - "ID = 0x%lx\tindex = %d\tr = %d\t", - (unsigned long) z1 / (unsigned long) sizeof(DdNode), - z1->index, z1->ref); + "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); #else - "ID = 0x%x\tindex = %d\tr = %d\t", - (unsigned) z1 / (unsigned) sizeof(DdNode), - z1->index, z1->ref); + "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); #endif - z1_next = cuddT(z1); - if (Cudd_IsConstant(z1_next)) { - (void) fprintf(table->out, "T = %d\t\t", - (z1_next == base)); - } - else { + z1_next = cuddT(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "T = %d\t\t", + (z1_next == base)); + } + else { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out, "T = 0x%lx\t", - (unsigned long) z1_next / (unsigned long) sizeof(DdNode)); + (void) fprintf(table->out, "T = 0x%lx\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #else - (void) fprintf(table->out, "T = 0x%x\t", - (unsigned) z1_next / (unsigned) sizeof(DdNode)); + (void) fprintf(table->out, "T = 0x%x\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #endif - } - z1_next = cuddE(z1); - if (Cudd_IsConstant(z1_next)) { - (void) fprintf(table->out, "E = %d\n", - (z1_next == base)); - } - else { + } + z1_next = cuddE(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "E = %d\n", + (z1_next == base)); + } + else { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out, "E = 0x%lx\n", - (unsigned long) z1_next / (unsigned long) sizeof(DdNode)); + (void) fprintf(table->out, "E = 0x%lx\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #else - (void) fprintf(table->out, "E = 0x%x\n", - (unsigned) z1_next / (unsigned) sizeof(DdNode)); + (void) fprintf(table->out, "E = 0x%x\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #endif - } + } - z1_next = z1->next; - z1 = z1_next; + z1_next = z1->next; + z1 = z1_next; + } } } - } putchar('\n'); } /* Cudd_zddPrintSubtable */ @@ -239,19 +267,20 @@ cuddZddDagInt( st_table * tab) { if (n == NIL(DdNode)) - return(0); + return(0); if (st_is_member(tab, (char *)n) == 1) - return(0); + return(0); if (Cudd_IsConstant(n)) - return(0); + return(0); (void)st_insert(tab, (char *)n, NIL(char)); return(1 + cuddZddDagInt(cuddT(n), tab) + - cuddZddDagInt(cuddE(n), tab)); + cuddZddDagInt(cuddE(n), tab)); } /* cuddZddDagInt */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddPort.c b/src/bdd/cudd/cuddZddPort.c index dfefece1..76b46ca5 100644 --- a/src/bdd/cudd/cuddZddPort.c +++ b/src/bdd/cudd/cuddZddPort.c @@ -7,37 +7,65 @@ Synopsis [Functions that translate BDDs to ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddPortFromBdd() - <li> Cudd_zddPortToBdd() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> zddPortFromBddStep() - <li> zddPortToBddStep() - </ul> - ] + <ul> + <li> Cudd_zddPortFromBdd() + <li> Cudd_zddPortToBdd() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> zddPortFromBddStep() + <li> zddPortToBddStep() + </ul> + ] SeeAlso [] Author [Hyong-kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,7 +86,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.13 2004/08/13 18:04:53 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -72,8 +100,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * zddPortFromBddStep ARGS((DdManager *dd, DdNode *B, int expected)); -static DdNode * zddPortToBddStep ARGS((DdManager *dd, DdNode *f, int depth)); +static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected); +static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth); /**AutomaticEnd***************************************************************/ @@ -107,8 +135,8 @@ Cudd_zddPortFromBdd( DdNode *res; do { - dd->reordered = 0; - res = zddPortFromBddStep(dd,B,0); + dd->reordered = 0; + res = zddPortFromBddStep(dd,B,0); } while (dd->reordered == 1); return(res); @@ -136,8 +164,8 @@ Cudd_zddPortToBdd( DdNode *res; do { - dd->reordered = 0; - res = zddPortToBddStep(dd,f,0); + dd->reordered = 0; + res = zddPortToBddStep(dd,f,0); } while (dd->reordered == 1); return(res); @@ -171,20 +199,20 @@ zddPortFromBddStep( DdNode * B, int expected) { - DdNode *res, *prevZdd, *t, *e; - DdNode *Breg, *Bt, *Be; - int id, level; + DdNode *res, *prevZdd, *t, *e; + DdNode *Breg, *Bt, *Be; + int id, level; statLine(dd); /* Terminal cases. */ if (B == Cudd_Not(DD_ONE(dd))) - return(DD_ZERO(dd)); + return(DD_ZERO(dd)); if (B == DD_ONE(dd)) { - if (expected >= dd->sizeZ) { - return(DD_ONE(dd)); - } else { - return(dd->univ[expected]); - } + if (expected >= dd->sizeZ) { + return(DD_ONE(dd)); + } else { + return(dd->univ[expected]); + } } Breg = Cudd_Regular(B); @@ -192,33 +220,33 @@ zddPortFromBddStep( /* Computed table look-up. */ res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B); if (res != NULL) { - level = cuddI(dd,Breg->index); - /* Adding DC vars. */ - if (expected < level) { - /* Add suppressed variables. */ - cuddRef(res); - for (level--; level >= expected; level--) { - prevZdd = res; - id = dd->invperm[level]; - res = cuddZddGetNode(dd, id, prevZdd, prevZdd); - if (res == NULL) { - Cudd_RecursiveDerefZdd(dd, prevZdd); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd, prevZdd); + level = cuddI(dd,Breg->index); + /* Adding DC vars. */ + if (expected < level) { + /* Add suppressed variables. */ + cuddRef(res); + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + cuddDeref(res); } - cuddDeref(res); - } - return(res); - } /* end of cache look-up */ + return(res); + } /* end of cache look-up */ if (Cudd_IsComplement(B)) { - Bt = Cudd_Not(cuddT(Breg)); - Be = Cudd_Not(cuddE(Breg)); + Bt = Cudd_Not(cuddT(Breg)); + Be = Cudd_Not(cuddE(Breg)); } else { - Bt = cuddT(Breg); - Be = cuddE(Breg); + Bt = cuddT(Breg); + Be = cuddE(Breg); } id = Breg->index; @@ -228,15 +256,15 @@ zddPortFromBddStep( cuddRef(t); e = zddPortFromBddStep(dd, Be, level+1); if (e == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); } cuddRef(e); res = cuddZddGetNode(dd, id, t, e); if (res == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - Cudd_RecursiveDerefZdd(dd, e); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + return(NULL); } cuddRef(res); Cudd_RecursiveDerefZdd(dd, t); @@ -245,15 +273,15 @@ zddPortFromBddStep( cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res); for (level--; level >= expected; level--) { - prevZdd = res; - id = dd->invperm[level]; - res = cuddZddGetNode(dd, id, prevZdd, prevZdd); - if (res == NULL) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDerefZdd(dd, prevZdd); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd, prevZdd); } cuddDeref(res); @@ -297,51 +325,51 @@ zddPortToBddStep( cuddRef(var); if (level > (unsigned) depth) { - E = zddPortToBddStep(dd,f,depth+1); - if (E == NULL) { - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(E); - res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); - if (res == NULL) { + E = zddPortToBddStep(dd,f,depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,E); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,E); - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); if (res != NULL) { - Cudd_RecursiveDeref(dd,var); - return(res); + Cudd_RecursiveDeref(dd,var); + return(res); } T = zddPortToBddStep(dd,cuddT(f),depth+1); if (T == NULL) { - Cudd_RecursiveDeref(dd,var); - return(NULL); + Cudd_RecursiveDeref(dd,var); + return(NULL); } cuddRef(T); E = zddPortToBddStep(dd,cuddE(f),depth+1); if (E == NULL) { - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd,var,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,var); @@ -355,5 +383,7 @@ zddPortToBddStep( } /* end of zddPortToBddStep */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddReord.c b/src/bdd/cudd/cuddZddReord.c index 1d73721c..80e3601c 100644 --- a/src/bdd/cudd/cuddZddReord.c +++ b/src/bdd/cudd/cuddZddReord.c @@ -7,51 +7,79 @@ Synopsis [Procedures for dynamic variable ordering of ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddReduceHeap() - <li> Cudd_zddShuffleHeap() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddAlignToBdd() - <li> cuddZddNextHigh() - <li> cuddZddNextLow() - <li> cuddZddUniqueCompare() - <li> cuddZddSwapInPlace() - <li> cuddZddSwapping() - <li> cuddZddSifting() - </ul> - Static procedures included in this module: - <ul> - <li> zddSwapAny() - <li> cuddZddSiftingAux() - <li> cuddZddSiftingUp() - <li> cuddZddSiftingDown() - <li> cuddZddSiftingBackward() - <li> zddReorderPreprocess() - <li> zddReorderPostprocess() - <li> zddShuffle() - <li> zddSiftUp() - </ul> - ] + <ul> + <li> Cudd_zddReduceHeap() + <li> Cudd_zddShuffleHeap() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddAlignToBdd() + <li> cuddZddNextHigh() + <li> cuddZddNextLow() + <li> cuddZddUniqueCompare() + <li> cuddZddSwapInPlace() + <li> cuddZddSwapping() + <li> cuddZddSifting() + </ul> + Static procedures included in this module: + <ul> + <li> zddSwapAny() + <li> cuddZddSiftingAux() + <li> cuddZddSiftingUp() + <li> cuddZddSiftingDown() + <li> cuddZddSiftingBackward() + <li> zddReorderPreprocess() + <li> zddReorderPostprocess() + <li> zddShuffle() + <li> zddSiftUp() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,14 +102,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.47 2004/08/13 18:04:53 fabio Exp $"; #endif -int *zdd_entry; +int *zdd_entry; -int zddTotalNumberSwapping; +int zddTotalNumberSwapping; -static DdNode *empty; +static DdNode *empty; /*---------------------------------------------------------------------------*/ @@ -95,16 +123,16 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static Move * zddSwapAny ARGS((DdManager *table, int x, int y)); -static int cuddZddSiftingAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static Move * cuddZddSiftingUp ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * cuddZddSiftingDown ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int cuddZddSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void zddReorderPreprocess ARGS((DdManager *table)); -static int zddReorderPostprocess ARGS((DdManager *table)); -static int zddShuffle ARGS((DdManager *table, int *permutation)); -static int zddSiftUp ARGS((DdManager *table, int x, int xLow)); -static void zddFixTree ARGS((DdManager *table, MtrNode *treenode)); +static Move * zddSwapAny (DdManager *table, int x, int y); +static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size); +static void zddReorderPreprocess (DdManager *table); +static int zddReorderPostprocess (DdManager *table); +static int zddShuffle (DdManager *table, int *permutation); +static int zddSiftUp (DdManager *table, int x, int xLow); +static void zddFixTree (DdManager *table, MtrNode *treenode); /**AutomaticEnd***************************************************************/ @@ -145,24 +173,24 @@ Cudd_zddReduceHeap( Cudd_ReorderingType heuristic /* method used for reordering */, int minsize /* bound below which no reordering occurs */) { - DdHook *hook; - int result; + DdHook *hook; + int result; unsigned int nextDyn; #ifdef DD_STATS unsigned int initialSize; unsigned int finalSize; #endif - long localTime; + long localTime; /* Don't reorder if there are too many dead nodes. */ if (table->keysZ - table->deadZ < (unsigned) minsize) - return(1); + return(1); if (heuristic == CUDD_REORDER_SAME) { - heuristic = table->autoMethodZ; + heuristic = table->autoMethodZ; } if (heuristic == CUDD_REORDER_NONE) { - return(1); + return(1); } /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore @@ -176,9 +204,9 @@ Cudd_zddReduceHeap( /* Run the hook functions. */ hook = table->preReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "ZDD", (void *)heuristic); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "ZDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; } /* Clear the cache and collect garbage. */ @@ -191,21 +219,21 @@ Cudd_zddReduceHeap( switch(heuristic) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - (void) fprintf(table->out,"#:I_RANDOM "); - break; + (void) fprintf(table->out,"#:I_RANDOM "); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: - (void) fprintf(table->out,"#:I_SIFTING "); - break; + (void) fprintf(table->out,"#:I_SIFTING "); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - (void) fprintf(table->out,"#:I_LINSIFT "); - break; + (void) fprintf(table->out,"#:I_LINSIFT "); + break; default: - (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); - return(0); + (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); + return(0); } (void) fprintf(table->out,"%8d: initial size",initialSize); #endif @@ -217,36 +245,36 @@ Cudd_zddReduceHeap( finalSize = table->keysZ; (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", - zddTotalNumberSwapping); + zddTotalNumberSwapping); #endif if (result == 0) - return(0); + return(0); if (!zddReorderPostprocess(table)) - return(0); + return(0); if (table->realignZ) { - if (!cuddBddAlignToZdd(table)) - return(0); + if (!cuddBddAlignToZdd(table)) + return(0); } nextDyn = table->keysZ * DD_DYN_RATIO; if (table->reorderings < 20 || nextDyn > table->nextDyn) - table->nextDyn = nextDyn; + table->nextDyn = nextDyn; else - table->nextDyn += 20; + table->nextDyn += 20; table->reordered = 1; /* Run hook functions. */ hook = table->postReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "ZDD", (void *)localTime); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "ZDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; } /* Update cumulative reordering time. */ table->reordTime += util_cpu_time() - localTime; @@ -278,7 +306,7 @@ Cudd_zddShuffleHeap( int * permutation /* required variable permutation */) { - int result; + int result; empty = table->zero; zddReorderPreprocess(table); @@ -324,14 +352,14 @@ int cuddZddAlignToBdd( DdManager * table /* DD manager */) { - int *invpermZ; /* permutation array */ - int M; /* ratio of ZDD variables to BDD variables */ - int i,j; /* loop indices */ - int result; /* return value */ + int *invpermZ; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i,j; /* loop indices */ + int result; /* return value */ /* We assume that a ratio of 0 is OK. */ if (table->sizeZ == 0) - return(1); + return(1); empty = table->zero; M = table->sizeZ / table->size; @@ -339,26 +367,26 @@ cuddZddAlignToBdd( ** number of BDD variables. */ if (M * table->size != table->sizeZ) - return(0); + return(0); /* Create and initialize the inverse permutation array. */ invpermZ = ABC_ALLOC(int,table->sizeZ); if (invpermZ == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < table->size; i++) { - int index = table->invperm[i]; - int indexZ = index * M; - int levelZ = table->permZ[indexZ]; - levelZ = (levelZ / M) * M; - for (j = 0; j < M; j++) { - invpermZ[M * i + j] = table->invpermZ[levelZ + j]; - } + int index = table->invperm[i]; + int indexZ = index * M; + int levelZ = table->permZ[indexZ]; + levelZ = (levelZ / M) * M; + for (j = 0; j < M; j++) { + invpermZ[M * i + j] = table->invpermZ[levelZ + j]; + } } /* Eliminate dead nodes. Do not scan the cache again, because we ** assume that Cudd_ReduceHeap has already cleared it. */ - cuddGarbageCollectZdd(table,0); + cuddGarbageCollect(table,0); result = zddShuffle(table, invpermZ); ABC_FREE(invpermZ); @@ -458,18 +486,17 @@ cuddZddSwapInPlace( int x, int y) { - DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; int oldxkeys, oldykeys; int newxkeys, newykeys; - int i; - int posn; - DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; - DdNode *newf1 = NULL; // Suppress "might be used uninitialized" - DdNode *newf0, *next; - DdNodePtr g, *lastP, *previousP; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *next; + DdNodePtr g, *lastP, *previousP; #ifdef DD_DEBUG assert(x < y); @@ -506,24 +533,24 @@ cuddZddSwapInPlace( g = NULL; lastP = &g; for (i = 0; i < xslots; i++) { - previousP = &(xlist[i]); - f = *previousP; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if ((f1->index != (DdHalfWord) yindex) && - (f0->index != (DdHalfWord) yindex)) { /* stays */ - newxkeys++; - *previousP = f; - previousP = &(f->next); - } else { - f->index = yindex; - *lastP = f; - lastP = &(f->next); - } - f = next; - } /* while there are elements in the collision chain */ - *previousP = NULL; + previousP = &(xlist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if ((f1->index != (DdHalfWord) yindex) && + (f0->index != (DdHalfWord) yindex)) { /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + *lastP = f; + lastP = &(f->next); + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = NULL; } /* for each slot of the x subtable */ *lastP = NULL; @@ -537,131 +564,131 @@ cuddZddSwapInPlace( */ f = g; while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = empty; f10 = f1; - } - f0 = cuddE(f); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = empty; f00 = f0; - } - - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == empty) { - if (f01 != empty) { - newf1 = f01; - cuddSatInc(newf1->ref); + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; } - /* else case was already handled when finding nodes - ** with both children below level y - */ - } else { - /* Check xlist for triple (xindex, f11, f01). */ - posn = ddHash(f11, f01, xshift); - /* For each element newf1 in collision list xlist[posn]. */ - newf1 = xlist[posn]; - while (newf1 != NULL) { - if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { - cuddSatInc(newf1->ref); - break; /* match */ + f0 = cuddE(f); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = xindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f01; - /* Insert newf1 in the collision list xlist[pos]; - ** increase the ref counts of f11 and f01 - */ - newxkeys++; - newf1->next = xlist[posn]; - xlist[posn] = newf1; - cuddSatInc(f11->ref); - cuddSatInc(f01->ref); + + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == empty) { + if (f01 != empty) { + newf1 = f01; + cuddSatInc(newf1->ref); + } + /* else case was already handled when finding nodes + ** with both children below level y + */ + } else { + /* Check xlist for triple (xindex, f11, f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + newf1 = xlist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[pos]; + ** increase the ref counts of f11 and f01 + */ + newxkeys++; + newf1->next = xlist[posn]; + xlist[posn] = newf1; + cuddSatInc(f11->ref); + cuddSatInc(f01->ref); + } } - } - cuddT(f) = newf1; - - /* Do the same for f0. */ - /* Decrease ref count of f0. */ - cuddSatDec(f0->ref); - /* Create the new E child. */ - if (f10 == empty) { - newf0 = f00; - cuddSatInc(newf0->ref); - } else { - /* Check xlist for triple (xindex, f10, f00). */ - posn = ddHash(f10, f00, xshift); - /* For each element newf0 in collision list xlist[posn]. */ - newf0 = xlist[posn]; - while (newf0 != NULL) { - if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Decrease ref count of f0. */ + cuddSatDec(f0->ref); + /* Create the new E child. */ + if (f10 == empty) { + newf0 = f00; cuddSatInc(newf0->ref); - break; /* match */ - } - newf0 = newf0->next; - } /* while newf0 */ - if (newf0 == NULL) { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto zddSwapOutOfMem; - newf0->index = xindex; newf0->ref = 1; - cuddT(newf0) = f10; cuddE(newf0) = f00; - /* Insert newf0 in the collision list xlist[posn]; - ** increase the ref counts of f10 and f00. - */ - newxkeys++; - newf0->next = xlist[posn]; - xlist[posn] = newf0; - cuddSatInc(f10->ref); - cuddSatInc(f00->ref); + } else { + /* Check xlist for triple (xindex, f10, f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + newf0 = xlist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = xlist[posn]; + xlist[posn] = newf0; + cuddSatInc(f10->ref); + cuddSatInc(f00->ref); + } } - } - cuddE(f) = newf0; + cuddE(f) = newf0; - /* Insert the modified f in ylist. - ** The modified f does not already exists in ylist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, yshift); - newykeys++; - f->next = ylist[posn]; - ylist[posn] = f; - f = next; + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + f->next = ylist[posn]; + ylist[posn] = f; + f = next; } /* while f != NULL */ /* GC the y layer. */ /* For each node f in ylist. */ for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != NULL) { - next = f->next; - if (f->ref == 0) { - cuddSatDec(cuddT(f)->ref); - cuddSatDec(cuddE(f)->ref); - cuddDeallocNode(table, f); - newykeys--; - } else { - *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = NULL; + previousP = &(ylist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = NULL; } /* for i */ /* Set the appropriate fields in table. */ @@ -722,14 +749,14 @@ cuddZddSwapping( int upper, Cudd_ReorderingType heuristic) { - int i, j; + int i, j; int max, keys; int nvars; - int x, y; + int x, y; int iterate; int previousSize; Move *moves, *move; - int pivot = -1; // Suppress "might be used uninitialized" + int pivot; int modulo; int result; @@ -742,63 +769,63 @@ cuddZddSwapping( iterate = nvars; for (i = 0; i < iterate; i++) { - if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { - /* Find pivot <= id with maximum keys. */ - for (max = -1, j = lower; j <= upper; j++) { - if ((keys = table->subtableZ[j].keys) > max) { - max = keys; - pivot = j; - } - } - - modulo = upper - pivot; - if (modulo == 0) { - y = pivot; /* y = nvars-1 */ - } else { - /* y = random # from {pivot+1 .. nvars-1} */ - y = pivot + 1 + (int) (Cudd_Random() % modulo); - } - - modulo = pivot - lower - 1; - if (modulo < 1) { /* if pivot = 1 or 0 */ - x = lower; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + /* Find pivot <= id with maximum keys. */ + for (max = -1, j = lower; j <= upper; j++) { + if ((keys = table->subtableZ[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; /* y = nvars-1 */ + } else { + /* y = random # from {pivot+1 .. nvars-1} */ + y = pivot + 1 + (int) (Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { /* if pivot = 1 or 0 */ + x = lower; + } else { + do { /* x = random # from {0 .. pivot-2} */ + x = (int) Cudd_Random() % modulo; + } while (x == y); + /* Is this condition really needed, since x and y + are in regions separated by pivot? */ + } } else { - do { /* x = random # from {0 .. pivot-2} */ - x = (int) Cudd_Random() % modulo; - } while (x == y); - /* Is this condition really needed, since x and y - are in regions separated by pivot? */ + x = (int) (Cudd_Random() % nvars) + lower; + do { + y = (int) (Cudd_Random() % nvars) + lower; + } while (x == y); } - } else { - x = (int) (Cudd_Random() % nvars) + lower; - do { - y = (int) (Cudd_Random() % nvars) + lower; - } while (x == y); - } - previousSize = table->keysZ; - moves = zddSwapAny(table, x, y); - if (moves == NULL) - goto cuddZddSwappingOutOfMem; + previousSize = table->keysZ; + moves = zddSwapAny(table, x, y); + if (moves == NULL) + goto cuddZddSwappingOutOfMem; - result = cuddZddSiftingBackward(table, moves, previousSize); - if (!result) - goto cuddZddSwappingOutOfMem; + result = cuddZddSiftingBackward(table, moves, previousSize); + if (!result) + goto cuddZddSwappingOutOfMem; - while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; - } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -806,9 +833,9 @@ cuddZddSwapping( cuddZddSwappingOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -842,13 +869,13 @@ cuddZddSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->sizeZ; @@ -857,45 +884,45 @@ cuddZddSifting( var = NULL; zdd_entry = ABC_ALLOC(int, size); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } var = ABC_ALLOC(int, size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSiftingOutOfMem; + result = cuddZddSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -936,14 +963,14 @@ zddSwapAny( int x, int y) { - Move *move, *moves; - int tmp, size; - int x_ref, y_ref; - int x_next, y_next; - int limit_size; - - if (x > y) { /* make x precede y */ - tmp = x; x = y; y = tmp; + Move *move, *moves; + int tmp, size; + int x_ref, y_ref; + int x_next, y_next; + int limit_size; + + if (x > y) { /* make x precede y */ + tmp = x; x = y; y = tmp; } x_ref = x; y_ref = y; @@ -954,118 +981,118 @@ zddSwapAny( limit_size = table->keysZ; for (;;) { - if (x_next == y_next) { /* x < x_next = y_next < y */ - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - size = cuddZddSwapInPlace(table, y_next, y); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; x = y; y = tmp; - - } else if (x == y_next) { /* x = y_next < y = x_next */ - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; + if (x_next == y_next) { /* x < x_next = y_next < y */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == y_next) { /* x = y_next < y = x_next */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + } else { + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = x_next; y = y_next; + } - tmp = x; x = y; y = tmp; - } else { - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + if (x_next > y_ref) + break; /* if x == y_ref */ + if ((double) size > table->maxGrowth * (double) limit_size) + break; + if (size < limit_size) + limit_size = size; + } + if (y_next >= x_ref) { size = cuddZddSwapInPlace(table, y_next, y); if (size == 0) - goto zddSwapAnyOutOfMem; + goto zddSwapAnyOutOfMem; move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) - goto zddSwapAnyOutOfMem; + goto zddSwapAnyOutOfMem; move->x = y_next; move->y = y; move->size = size; move->next = moves; moves = move; - - x = x_next; y = y_next; - } - - x_next = cuddZddNextHigh(table, x); - y_next = cuddZddNextLow(table, y); - if (x_next > y_ref) - break; /* if x == y_ref */ - - if ((double) size > table->maxGrowth * (double) limit_size) - break; - if (size < limit_size) - limit_size = size; - } - if (y_next >= x_ref) { - size = cuddZddSwapInPlace(table, y_next, y); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; } return(moves); zddSwapAnyOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1093,12 +1120,12 @@ cuddZddSiftingAux( int x_low, int x_high) { - Move *move; - Move *moveUp; /* list of up move */ - Move *moveDown; /* list of down move */ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ - int initial_size; - int result; + int initial_size; + int result; initial_size = table->keysZ; @@ -1110,82 +1137,82 @@ cuddZddSiftingAux( moveUp = NULL; if (x == x_low) { - moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); - /* after that point x --> x_high */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveDown, - initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else if (x == x_high) { - moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); - /* after that point x --> x_low */ - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveUp, initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_low */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { - /* must go down first:shorter */ - moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); - /* after that point x --> x_high */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, - initial_size); - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveUp, initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + /* must go down first:shorter */ + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, + initial_size); + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else { - moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); - /* after that point x --> x_high */ - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, - initial_size); - /* then move up */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveDown, - initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_high */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, + initial_size); + /* then move up */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); cuddZddSiftingAuxOutOfMem: while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(0); @@ -1213,42 +1240,42 @@ cuddZddSiftingUp( int x_low, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; moves = NULL; y = cuddZddNextLow(table, x); while (y >= x_low) { - size = cuddZddSwapInPlace(table, y, x); - if (size == 0) - goto cuddZddSiftingUpOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSiftingUpOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - - if ((double)size > (double)limit_size * table->maxGrowth) - break; + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; if (size < limit_size) - limit_size = size; + limit_size = size; - x = y; - y = cuddZddNextLow(table, x); + x = y; + y = cuddZddNextLow(table, x); } return(moves); cuddZddSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1276,42 +1303,42 @@ cuddZddSiftingDown( int x_high, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; moves = NULL; y = cuddZddNextHigh(table, x); while (y <= x_high) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddSiftingDownOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - if ((double)size > (double)limit_size * table->maxGrowth) - break; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSiftingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; if (size < limit_size) - limit_size = size; + limit_size = size; - x = y; - y = cuddZddNextHigh(table, x); + x = y; + y = cuddZddNextHigh(table, x); } return(moves); cuddZddSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1339,28 +1366,28 @@ cuddZddSiftingBackward( Move * moves, int size) { - int i; - int i_best; - Move *move; - int res; + int i; + int i_best; + Move *move; + int res; /* Find the minimum size among moves. */ i_best = -1; for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (move->size < size) { - i_best = i; - size = move->size; - } + if (move->size < size) { + i_best = i; + size = move->size; + } } for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (i == i_best) - break; - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) - return(0); - if (i_best == -1 && res == size) - break; + if (i == i_best) + break; + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (i_best == -1 && res == size) + break; } return(1); @@ -1388,7 +1415,7 @@ zddReorderPreprocess( cuddCacheFlush(table); /* Eliminate dead nodes. Do not scan the cache again. */ - cuddGarbageCollectZdd(table,0); + cuddGarbageCollect(table,0); return; @@ -1416,8 +1443,8 @@ zddReorderPostprocess( DdNodePtr *nodelist, *oldnodelist; DdNode *node, *next; unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifdef DD_VERBOSE (void) fflush(table->out); @@ -1433,51 +1460,51 @@ zddReorderPostprocess( /* Resize subtables. */ for (i = 0; i < table->sizeZ; i++) { - int shift; - oldslots = table->subtableZ[i].slots; - if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || - oldslots <= table->initSlots) continue; - oldnodelist = table->subtableZ[i].nodelist; - slots = oldslots >> 1; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - return(1); - } - table->subtableZ[i].nodelist = nodelist; - table->subtableZ[i].slots = slots; - table->subtableZ[i].shift++; - table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + int shift; + oldslots = table->subtableZ[i].slots; + if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || + oldslots <= table->initSlots) continue; + oldnodelist = table->subtableZ[i].nodelist; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return(1); + } + table->subtableZ[i].nodelist = nodelist; + table->subtableZ[i].slots = slots; + table->subtableZ[i].shift++; + table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; #ifdef DD_VERBOSE - (void) fprintf(table->err, - "shrunk layer %d (%d keys) from %d to %d slots\n", - i, table->subtableZ[i].keys, oldslots, slots); + (void) fprintf(table->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, table->subtableZ[i].keys, oldslots, slots); #endif - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - shift = table->subtableZ[i].shift; - for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - posn = ddHash(cuddT(node), cuddE(node), shift); - node->next = nodelist[posn]; - nodelist[posn] = node; - node = next; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; } - } - ABC_FREE(oldnodelist); - - table->memused += (slots - oldslots) * sizeof(DdNode *); - table->slots += slots - oldslots; - table->minDead = (unsigned) (table->gcFrac * (double) table->slots); - table->cacheSlack = (int) ddMin(table->maxCacheHard, - DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - - 2 * (int) table->cacheSlots; + shift = table->subtableZ[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[posn]; + nodelist[posn] = node; + node = next; + } + } + ABC_FREE(oldnodelist); + + table->memused += (slots - oldslots) * sizeof(DdNode *); + table->slots += slots - oldslots; + table->minDead = (unsigned) (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) ddMin(table->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - + 2 * (int) table->cacheSlots; } /* We don't look at the constant subtable, because it is not ** affected by reordering. @@ -1508,16 +1535,16 @@ zddShuffle( DdManager * table, int * permutation) { - int index; - int level; - int position; - int numvars; - int result; + int index; + int level; + int position; + int numvars; + int result; #ifdef DD_STATS - long localTime; - int initialSize; - int finalSize; - int previousSize; + long localTime; + int initialSize; + int finalSize; + int previousSize; #endif zddTotalNumberSwapping = 0; @@ -1525,28 +1552,28 @@ zddShuffle( localTime = util_cpu_time(); initialSize = table->keysZ; (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", - initialSize); + initialSize); #endif numvars = table->sizeZ; for (level = 0; level < numvars; level++) { - index = permutation[level]; - position = table->permZ[index]; + index = permutation[level]; + position = table->permZ[index]; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = zddSiftUp(table,position,level); - if (!result) return(0); + result = zddSiftUp(table,position,level); + if (!result) return(0); #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -1555,9 +1582,9 @@ zddShuffle( finalSize = table->keysZ; (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", - zddTotalNumberSwapping); + zddTotalNumberSwapping); #endif return(1); @@ -1589,12 +1616,12 @@ zddSiftUp( y = cuddZddNextLow(table,x); while (y >= xLow) { - size = cuddZddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddZddNextLow(table,x); + size = cuddZddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddZddNextLow(table,x); } return(1); @@ -1621,19 +1648,21 @@ zddFixTree( { if (treenode == NULL) return; treenode->low = ((int) treenode->index < table->sizeZ) ? - table->permZ[treenode->index] : treenode->index; + table->permZ[treenode->index] : treenode->index; if (treenode->child != NULL) { - zddFixTree(table, treenode->child); + zddFixTree(table, treenode->child); } if (treenode->younger != NULL) - zddFixTree(table, treenode->younger); + zddFixTree(table, treenode->younger); if (treenode->parent != NULL && treenode->low < treenode->parent->low) { - treenode->parent->low = treenode->low; - treenode->parent->index = treenode->index; + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; } return; } /* end of zddFixTree */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddSetop.c b/src/bdd/cudd/cuddZddSetop.c index 566c610b..b4726b63 100644 --- a/src/bdd/cudd/cuddZddSetop.c +++ b/src/bdd/cudd/cuddZddSetop.c @@ -7,51 +7,79 @@ Synopsis [Set operations on ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddIte() - <li> Cudd_zddUnion() - <li> Cudd_zddIntersect() - <li> Cudd_zddDiff() - <li> Cudd_zddDiffConst() - <li> Cudd_zddSubset1() - <li> Cudd_zddSubset0() - <li> Cudd_zddChange() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddIte() - <li> cuddZddUnion() - <li> cuddZddIntersect() - <li> cuddZddDiff() - <li> cuddZddChangeAux() - <li> cuddZddSubset1() - <li> cuddZddSubset0() - </ul> - Static procedures included in this module: - <ul> - <li> zdd_subset1_aux() - <li> zdd_subset0_aux() - <li> zddVarToConst() - </ul> - ] + <ul> + <li> Cudd_zddIte() + <li> Cudd_zddUnion() + <li> Cudd_zddIntersect() + <li> Cudd_zddDiff() + <li> Cudd_zddDiffConst() + <li> Cudd_zddSubset1() + <li> Cudd_zddSubset0() + <li> Cudd_zddChange() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddIte() + <li> cuddZddUnion() + <li> cuddZddIntersect() + <li> cuddZddDiff() + <li> cuddZddChangeAux() + <li> cuddZddSubset1() + <li> cuddZddSubset0() + </ul> + Static procedures included in this module: + <ul> + <li> zdd_subset1_aux() + <li> zdd_subset0_aux() + <li> zddVarToConst() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -72,13 +100,16 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.25 2004/08/13 18:04:54 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -86,12 +117,15 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * zdd_subset1_aux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -static DdNode * zdd_subset0_aux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -static void zddVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)); +static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -120,8 +154,8 @@ Cudd_zddIte( DdNode *res; do { - dd->reordered = 0; - res = cuddZddIte(dd, f, g, h); + dd->reordered = 0; + res = cuddZddIte(dd, f, g, h); } while (dd->reordered == 1); return(res); @@ -149,8 +183,8 @@ Cudd_zddUnion( DdNode *res; do { - dd->reordered = 0; - res = cuddZddUnion(dd, P, Q); + dd->reordered = 0; + res = cuddZddUnion(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -178,8 +212,8 @@ Cudd_zddIntersect( DdNode *res; do { - dd->reordered = 0; - res = cuddZddIntersect(dd, P, Q); + dd->reordered = 0; + res = cuddZddIntersect(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -207,8 +241,8 @@ Cudd_zddDiff( DdNode *res; do { - dd->reordered = 0; - res = cuddZddDiff(dd, P, Q); + dd->reordered = 0; + res = cuddZddDiff(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -234,41 +268,41 @@ Cudd_zddDiffConst( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(P); + return(P); if (P == Q) - return(empty); + return(empty); /* Check cache. The cache is shared by cuddZddDiff(). */ res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - res = DD_NON_CONSTANT; + res = DD_NON_CONSTANT; } else if (p_top > q_top) { - res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); + res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); } else { - t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); - if (t != empty) - res = DD_NON_CONSTANT; - else - res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); + t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); + if (t != empty) + res = DD_NON_CONSTANT; + else + res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); } cuddCacheInsert2(table, cuddZddDiff, P, Q, res); @@ -298,11 +332,11 @@ Cudd_zddSubset1( DdNode * P, int var) { - DdNode *r; + DdNode *r; do { - dd->reordered = 0; - r = cuddZddSubset1(dd, P, var); + dd->reordered = 0; + r = cuddZddSubset1(dd, P, var); } while (dd->reordered == 1); return(r); @@ -330,11 +364,11 @@ Cudd_zddSubset0( DdNode * P, int var) { - DdNode *r; + DdNode *r; do { - dd->reordered = 0; - r = cuddZddSubset0(dd, P, var); + dd->reordered = 0; + r = cuddZddSubset0(dd, P, var); } while (dd->reordered == 1); return(r); @@ -360,13 +394,13 @@ Cudd_zddChange( DdNode * P, int var) { - DdNode *res; + DdNode *res; if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddZddChange(dd, P, var); + dd->reordered = 0; + res = cuddZddChange(dd, P, var); } while (dd->reordered == 1); return(res); @@ -404,8 +438,8 @@ cuddZddIte( statLine(dd); /* Trivial cases. */ /* One variable cases. */ - if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ - return(h); + if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); } topf = cuddIZ(dd,f->index); topg = cuddIZ(dd,g->index); @@ -414,7 +448,7 @@ cuddZddIte( top = ddMin(topf,v); tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top]; - if (f == tautology) { /* ITE(1,G,H) = G */ + if (f == tautology) { /* ITE(1,G,H) = G */ return(g); } @@ -422,18 +456,18 @@ cuddZddIte( zddVarToConst(f,&g,&h,tautology,empty); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ - return(g); + if (g == h) { /* ITE(F,G,G) = G */ + return(g); } - if (g == tautology) { /* ITE(F,1,0) = F */ - if (h == empty) return(f); + if (g == tautology) { /* ITE(F,1,0) = F */ + if (h == empty) return(f); } /* Check cache. */ r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h); if (r != NULL) { - return(r); + return(r); } /* Recompute these because they may have changed in zddVarToConst. */ @@ -442,59 +476,59 @@ cuddZddIte( v = ddMin(topg,toph); if (topf < v) { - r = cuddZddIte(dd,cuddE(f),g,h); - if (r == NULL) return(NULL); + r = cuddZddIte(dd,cuddE(f),g,h); + if (r == NULL) return(NULL); } else if (topf > v) { - if (topg > v) { - Gvn = g; - index = h->index; - } else { - Gvn = cuddE(g); - index = g->index; - } - if (toph > v) { - Hv = empty; Hvn = h; - } else { - Hv = cuddT(h); Hvn = cuddE(h); - } - e = cuddZddIte(dd,f,Gvn,Hvn); - if (e == NULL) return(NULL); - cuddRef(e); - r = cuddZddGetNode(dd,index,Hv,e); - if (r == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - return(NULL); - } - cuddDeref(e); - } else { - index = f->index; - if (topg > v) { - Gv = empty; Gvn = g; + if (topg > v) { + Gvn = g; + index = h->index; + } else { + Gvn = cuddE(g); + index = g->index; + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,f,Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + r = cuddZddGetNode(dd,index,Hv,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddDeref(e); } else { - Gv = cuddT(g); Gvn = cuddE(g); - } - if (toph > v) { - Hv = empty; Hvn = h; - } else { - Hv = cuddT(h); Hvn = cuddE(h); - } - e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); - if (e == NULL) return(NULL); - cuddRef(e); - t = cuddZddIte(dd,cuddT(f),Gv,Hv); - if (t == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - return(NULL); - } - cuddRef(t); - r = cuddZddGetNode(dd,index,t,e); - if (r == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - Cudd_RecursiveDerefZdd(dd,t); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + index = f->index; + if (topg > v) { + Gv = empty; Gvn = g; + } else { + Gv = cuddT(g); Gvn = cuddE(g); + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + t = cuddZddIte(dd,cuddT(f),Gv,Hv); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddRef(t); + r = cuddZddGetNode(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + Cudd_RecursiveDerefZdd(dd,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r); @@ -521,69 +555,69 @@ cuddZddUnion( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(Q); + return(Q); if (Q == empty) - return(P); + return(P); if (P == Q) - return(P); + return(P); /* Check cache */ res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - e = cuddZddUnion(zdd, cuddE(P), Q); - if (e == NULL) return (NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, cuddT(P), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddUnion(zdd, cuddE(P), Q); + if (e == NULL) return (NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else if (p_top > q_top) { - e = cuddZddUnion(zdd, P, cuddE(Q)); - if (e == NULL) return(NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddUnion(zdd, P, cuddE(Q)); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else { - t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddUnion, P, Q, res); @@ -610,55 +644,55 @@ cuddZddIntersect( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(empty); + return(empty); if (P == Q) - return(P); + return(P); /* Check cache. */ res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - res = cuddZddIntersect(zdd, cuddE(P), Q); - if (res == NULL) return(NULL); + res = cuddZddIntersect(zdd, cuddE(P), Q); + if (res == NULL) return(NULL); } else if (p_top > q_top) { - res = cuddZddIntersect(zdd, P, cuddE(Q)); - if (res == NULL) return(NULL); + res = cuddZddIntersect(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); } else { - t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddIntersect, P, Q, res); @@ -685,62 +719,62 @@ cuddZddDiff( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(P); + return(P); if (P == Q) - return(empty); + return(empty); /* Check cache. The cache is shared by Cudd_zddDiffConst(). */ res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); if (res != NULL && res != DD_NON_CONSTANT) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - e = cuddZddDiff(zdd, cuddE(P), Q); - if (e == NULL) return(NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, cuddT(P), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddDiff(zdd, cuddE(P), Q); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else if (p_top > q_top) { - res = cuddZddDiff(zdd, P, cuddE(Q)); - if (res == NULL) return(NULL); + res = cuddZddDiff(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); } else { - t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddDiff, P, Q, res); @@ -767,49 +801,49 @@ cuddZddChangeAux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base = DD_ONE(zdd); - DdNode *empty = DD_ZERO(zdd); + int top_var, level; + DdNode *res, *t, *e; + DdNode *base = DD_ONE(zdd); + DdNode *empty = DD_ZERO(zdd); statLine(zdd); if (P == empty) - return(empty); + return(empty); if (P == base) - return(zvar); + return(zvar); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar); if (res != NULL) - return(res); + return(res); top_var = zdd->permZ[P->index]; level = zdd->permZ[zvar->index]; if (top_var > level) { - res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); - if (res == NULL) return(NULL); + res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); + if (res == NULL) return(NULL); } else if (top_var == level) { - res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); - if (res == NULL) return(NULL); + res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); + if (res == NULL) return(NULL); } else { - t = cuddZddChangeAux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddChangeAux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddChangeAux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddChangeAux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res); @@ -842,24 +876,24 @@ cuddZddSubset1( DdNode * P, int var) { - DdNode *zvar, *r; - DdNode *base, *empty; + DdNode *zvar, *r; + DdNode *base, *empty; base = DD_ONE(dd); empty = DD_ZERO(dd); zvar = cuddUniqueInterZdd(dd, var, base, empty); if (zvar == NULL) { - return(NULL); + return(NULL); } else { - cuddRef(zvar); - r = zdd_subset1_aux(dd, P, zvar); - if (r == NULL) { + cuddRef(zvar); + r = zdd_subset1_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDerefZdd(dd, zvar); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDerefZdd(dd, zvar); } cuddDeref(r); @@ -891,24 +925,24 @@ cuddZddSubset0( DdNode * P, int var) { - DdNode *zvar, *r; - DdNode *base, *empty; + DdNode *zvar, *r; + DdNode *base, *empty; base = DD_ONE(dd); empty = DD_ZERO(dd); zvar = cuddUniqueInterZdd(dd, var, base, empty); if (zvar == NULL) { - return(NULL); + return(NULL); } else { - cuddRef(zvar); - r = zdd_subset0_aux(dd, P, zvar); - if (r == NULL) { + cuddRef(zvar); + r = zdd_subset0_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDerefZdd(dd, zvar); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDerefZdd(dd, zvar); } cuddDeref(r); @@ -939,7 +973,7 @@ cuddZddChange( DdNode * P, int var) { - DdNode *zvar, *res; + DdNode *zvar, *res; zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd)); if (zvar == NULL) return(NULL); @@ -947,8 +981,8 @@ cuddZddChange( res = cuddZddChangeAux(dd, P, zvar); if (res == NULL) { - Cudd_RecursiveDerefZdd(dd,zvar); - return(NULL); + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); } cuddRef(res); Cudd_RecursiveDerefZdd(dd,zvar); @@ -980,23 +1014,22 @@ zdd_subset1_aux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base, *empty; + int top_var, level; + DdNode *res, *t, *e; + DdNode *empty; statLine(zdd); - base = DD_ONE(zdd); empty = DD_ZERO(zdd); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) { - res = empty; - cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); - return(res); + res = empty; + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + return(res); } top_var = zdd->permZ[P->index]; @@ -1005,25 +1038,25 @@ zdd_subset1_aux( if (top_var > level) { res = empty; } else if (top_var == level) { - res = cuddT(P); + res = cuddT(P); } else { t = zdd_subset1_aux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); + if (t == NULL) return(NULL); + cuddRef(t); e = zdd_subset1_aux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); @@ -1050,23 +1083,20 @@ zdd_subset0_aux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base, *empty; + int top_var, level; + DdNode *res, *t, *e; statLine(zdd); - base = DD_ONE(zdd); - empty = DD_ZERO(zdd); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) { - res = P; - cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); - return(res); + res = P; + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + return(res); } top_var = zdd->permZ[P->index]; @@ -1080,22 +1110,22 @@ zdd_subset0_aux( } else { t = zdd_subset0_aux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); + if (t == NULL) return(NULL); + cuddRef(t); e = zdd_subset0_aux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); @@ -1129,14 +1159,16 @@ zddVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = base; + *gp = base; } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = empty; + *hp = empty; } } /* end of zddVarToConst */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddSymm.c b/src/bdd/cudd/cuddZddSymm.c index 644673cd..52e26d88 100644 --- a/src/bdd/cudd/cuddZddSymm.c +++ b/src/bdd/cudd/cuddZddSymm.c @@ -7,45 +7,73 @@ Synopsis [Functions for symmetry-based ZDD variable reordering.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddSymmProfile() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddSymmCheck() - <li> cuddZddSymmSifting() - <li> cuddZddSymmSiftingConv() - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddUniqueCompare() - <li> cuddZddSymmSiftingAux() - <li> cuddZddSymmSiftingConvAux() - <li> cuddZddSymmSifting_up() - <li> cuddZddSymmSifting_down() - <li> zdd_group_move() - <li> cuddZddSymmSiftingBackward() - <li> zdd_group_move_backward() - </ul> - ] + <ul> + <li> Cudd_zddSymmProfile() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddSymmCheck() + <li> cuddZddSymmSifting() + <li> cuddZddSymmSiftingConv() + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddUniqueCompare() + <li> cuddZddSymmSiftingAux() + <li> cuddZddSymmSiftingConvAux() + <li> cuddZddSymmSifting_up() + <li> cuddZddSymmSifting_down() + <li> zdd_group_move() + <li> cuddZddSymmSiftingBackward() + <li> zdd_group_move_backward() + </ul> + ] SeeAlso [cuddSymmetry.c] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -65,14 +93,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.29 2004/08/13 18:04:54 fabio Exp $"; #endif -extern int *zdd_entry; +extern int *zdd_entry; -extern int zddTotalNumberSwapping; +extern int zddTotalNumberSwapping; -static DdNode *empty; +static DdNode *empty; /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -85,14 +113,14 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddSymmSiftingAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static int cuddZddSymmSiftingConvAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static Move * cuddZddSymmSifting_up ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * cuddZddSymmSifting_down ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int cuddZddSymmSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static int zdd_group_move ARGS((DdManager *table, int x, int y, Move **moves)); -static int zdd_group_move_backward ARGS((DdManager *table, int x, int y)); -static void cuddZddSymmSummary ARGS((DdManager *table, int lower, int upper, int *symvars, int *symgroups)); +static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high); +static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static int zdd_group_move (DdManager *table, int x, int y, Move **moves); +static int zdd_group_move_backward (DdManager *table, int x, int y); +static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); /**AutomaticEnd***************************************************************/ @@ -119,30 +147,27 @@ Cudd_zddSymmProfile( int lower, int upper) { - int i, x, gbot; - int TotalSymm = 0; - int TotalSymmGroups = 0; - int nvars; - - nvars = table->sizeZ; + int i, x, gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; for (i = lower; i < upper; i++) { - if (table->subtableZ[i].next != (unsigned) i) { - x = i; - (void) fprintf(table->out,"Group:"); - do { - (void) fprintf(table->out," %d", table->invpermZ[x]); - TotalSymm++; - gbot = x; - x = table->subtableZ[x].next; - } while (x != i); - TotalSymmGroups++; + if (table->subtableZ[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d", table->invpermZ[x]); + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); + TotalSymmGroups++; #ifdef DD_DEBUG - assert(table->subtableZ[gbot].next == (unsigned) i); + assert(table->subtableZ[gbot].next == (unsigned) i); #endif - i = gbot; - (void) fprintf(table->out,"\n"); - } + i = gbot; + (void) fprintf(table->out,"\n"); + } } (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); @@ -174,75 +199,75 @@ cuddZddSymmCheck( int x, int y) { - int i; - DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; - int yindex; - int xsymmy = 1; - int xsymmyp = 1; - int arccount = 0; - int TotalRefCount = 0; - int symm_found; + int i; + DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; + int yindex; + int xsymmy = 1; + int xsymmyp = 1; + int arccount = 0; + int TotalRefCount = 0; + int symm_found; empty = table->zero; yindex = table->invpermZ[y]; for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { - f = table->subtableZ[x].nodelist[i]; - while (f != NULL) { - /* Find f1, f0, f11, f10, f01, f00 */ - f1 = cuddT(f); - f0 = cuddE(f); - if ((int) f1->index == yindex) { - f11 = cuddT(f1); - f10 = cuddE(f1); - if (f10 != empty) - arccount++; - } else { - if ((int) f0->index != yindex) { - return(0); /* f bypasses layer y */ - } - f11 = empty; - f10 = f1; - } - if ((int) f0->index == yindex) { - f01 = cuddT(f0); - f00 = cuddE(f0); - if (f00 != empty) - arccount++; - } else { - f01 = empty; - f00 = f0; - } - if (f01 != f10) - xsymmy = 0; - if (f11 != f00) - xsymmyp = 0; - if ((xsymmy == 0) && (xsymmyp == 0)) - return(0); - - f = f->next; - } /* for each element of the collision list */ + f = table->subtableZ[x].nodelist[i]; + while (f != NULL) { + /* Find f1, f0, f11, f10, f01, f00 */ + f1 = cuddT(f); + f0 = cuddE(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); + f10 = cuddE(f1); + if (f10 != empty) + arccount++; + } else { + if ((int) f0->index != yindex) { + return(0); /* f bypasses layer y */ + } + f11 = empty; + f10 = f1; + } + if ((int) f0->index == yindex) { + f01 = cuddT(f0); + f00 = cuddE(f0); + if (f00 != empty) + arccount++; + } else { + f01 = empty; + f00 = f0; + } + if (f01 != f10) + xsymmy = 0; + if (f11 != f00) + xsymmyp = 0; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + + f = f->next; + } /* for each element of the collision list */ } /* for each slot of the subtable */ /* Calculate the total reference counts of y ** whose else arc is not empty. */ for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { - f = table->subtableZ[y].nodelist[i]; - while (f != NIL(DdNode)) { - if (cuddE(f) != empty) - TotalRefCount += f->ref; - f = f->next; - } + f = table->subtableZ[y].nodelist[i]; + while (f != NIL(DdNode)) { + if (cuddE(f) != empty) + TotalRefCount += f->ref; + f = f->next; + } } symm_found = (arccount == TotalRefCount); #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (symm_found) { - int xindex = table->invpermZ[x]; - (void) fprintf(table->out, - "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + int xindex = table->invpermZ[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif @@ -279,16 +304,16 @@ cuddZddSymmSifting( int lower, int upper) { - int i; - int *var; - int nvars; - int x; - int result; - int symvars; - int symgroups; - int iteration; + int i; + int *var; + int nvars; + int x; + int result; + int symvars; + int symgroups; + int iteration; #ifdef DD_STATS - int previousSize; + int previousSize; #endif nvars = table->sizeZ; @@ -297,54 +322,54 @@ cuddZddSymmSifting( var = NULL; zdd_entry = ABC_ALLOC(int, nvars); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; } var = ABC_ALLOC(int, nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; } for (i = 0; i < nvars; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Initialize the symmetry of each subtable to itself. */ for (i = lower; i <= upper; i++) - table->subtableZ[i].next = i; + table->subtableZ[i].next = i; iteration = ddMin(table->siftMaxVar, nvars); for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - if (x < lower || x > upper) continue; - if (table->subtableZ[x].next == (unsigned) x) { - result = cuddZddSymmSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingOutOfMem; + if (x < lower || x > upper) continue; + if (table->subtableZ[x].next == (unsigned) x) { + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } ABC_FREE(var); @@ -362,9 +387,9 @@ cuddZddSymmSifting( cuddZddSymmSiftingOutOfMem: if (zdd_entry != NULL) - ABC_FREE(zdd_entry); + ABC_FREE(zdd_entry); if (var != NULL) - ABC_FREE(var); + ABC_FREE(var); return(0); @@ -400,16 +425,16 @@ cuddZddSymmSiftingConv( int lower, int upper) { - int i; - int *var; - int nvars; - int initialSize; - int x; - int result; - int symvars; - int symgroups; - int classes; - int iteration; + int i; + int *var; + int nvars; + int initialSize; + int x; + int result; + int symvars; + int symgroups; + int classes; + int iteration; #ifdef DD_STATS int previousSize; #endif @@ -422,117 +447,117 @@ cuddZddSymmSiftingConv( var = NULL; zdd_entry = ABC_ALLOC(int, nvars); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; } var = ABC_ALLOC(int, nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; } for (i = 0; i < nvars; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Initialize the symmetry of each subtable to itself ** for first pass of converging symmetric sifting. */ for (i = lower; i <= upper; i++) - table->subtableZ[i].next = i; + table->subtableZ[i].next = i; iteration = ddMin(table->siftMaxVar, table->sizeZ); for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; - /* Only sift if not in symmetry group already. */ - if (table->subtableZ[x].next == (unsigned) x) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtableZ[x].next == (unsigned) x) { #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSymmSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingConvOutOfMem; + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } /* Sifting now until convergence. */ while ((unsigned) initialSize > table->keysZ) { - initialSize = table->keysZ; + initialSize = table->keysZ; #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif - /* Here we consider only one representative for each symmetry class. */ - for (x = lower, classes = 0; x <= upper; x++, classes++) { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - /* Here x is the largest index in a group. - ** Groups consists of adjacent variables. - ** Hence, the next increment of x will move it to a new group. - */ - i = table->invpermZ[x]; - zdd_entry[i] = table->subtableZ[x].keys; - var[classes] = i; - } + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + /* Here x is the largest index in a group. + ** Groups consists of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invpermZ[x]; + zdd_entry[i] = table->subtableZ[x].keys; + var[classes] = i; + } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare); - /* Now sift. */ - iteration = ddMin(table->siftMaxVar, nvars); - for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if ((unsigned) x >= table->subtableZ[x].next) { + /* Now sift. */ + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if ((unsigned) x >= table->subtableZ[x].next) { #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSymmSiftingConvAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingConvOutOfMem; + result = cuddZddSymmSiftingConvAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } - } /* for */ + } + } /* for */ } cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); #ifdef DD_STATS (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", - symgroups); + symgroups); #endif ABC_FREE(var); @@ -543,9 +568,9 @@ cuddZddSymmSiftingConv( cuddZddSymmSiftingConvOutOfMem: if (zdd_entry != NULL) - ABC_FREE(zdd_entry); + ABC_FREE(zdd_entry); if (var != NULL) - ABC_FREE(var); + ABC_FREE(var); return(0); @@ -580,13 +605,13 @@ cuddZddSymmSiftingAux( int x_high) { Move *move; - Move *move_up; /* list of up move */ + Move *move_up; /* list of up move */ Move *move_down; /* list of down move */ - int initial_size; - int result; - int i; - int topbot; /* index to either top or bottom of symmetry group */ - int init_group_size, final_group_size; + int initial_size; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int init_group_size, final_group_size; initial_size = table->keysZ; @@ -595,300 +620,300 @@ cuddZddSymmSiftingAux( /* Look for consecutive symmetries above x. */ for (i = x; i > x_low; i--) { - if (!cuddZddSymmCheck(table, i - 1, i)) + if (!cuddZddSymmCheck(table, i - 1, i)) break; - /* find top of i-1's symmetry */ - topbot = table->subtableZ[i - 1].next; - table->subtableZ[i - 1].next = i; - table->subtableZ[x].next = topbot; - /* x is bottom of group so its symmetry is top of i-1's - group */ - i = topbot + 1; /* add 1 for i--, new i is top of symm group */ + /* find top of i-1's symmetry */ + topbot = table->subtableZ[i - 1].next; + table->subtableZ[i - 1].next = i; + table->subtableZ[x].next = topbot; + /* x is bottom of group so its symmetry is top of i-1's + group */ + i = topbot + 1; /* add 1 for i--, new i is top of symm group */ } /* Look for consecutive symmetries below x. */ for (i = x; i < x_high; i++) { - if (!cuddZddSymmCheck(table, i, i + 1)) + if (!cuddZddSymmCheck(table, i, i + 1)) break; - /* find bottom of i+1's symm group */ - topbot = i + 1; - while ((unsigned) topbot < table->subtableZ[topbot].next) - topbot = table->subtableZ[topbot].next; - - table->subtableZ[topbot].next = table->subtableZ[i].next; - table->subtableZ[i].next = i + 1; - i = topbot - 1; /* add 1 for i++, - new i is bottom of symm group */ + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtableZ[topbot].next) + topbot = table->subtableZ[topbot].next; + + table->subtableZ[topbot].next = table->subtableZ[i].next; + table->subtableZ[i].next = i + 1; + i = topbot - 1; /* add 1 for i++, + new i is bottom of symm group */ } /* Now x maybe in the middle of a symmetry group. */ if (x == x_low) { /* Sift down */ - /* Find bottom of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - - i = table->subtableZ[x].next; - init_group_size = x - i + 1; + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + i = table->subtableZ[x].next; + init_group_size = x - i + 1; - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ if (move_down != NULL) - x = move_down->y; - else - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + x = move_down->y; + else + x = table->subtableZ[x].next; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, - move_down, initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, + move_down, initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else if (x == x_high) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_low, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ if (move_up != NULL) - x = move_up->x; - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { /* must go down first: - shorter */ - /* Find bottom of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; - - if (move_down != NULL) { - x = move_down->y; - } - else { - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + shorter */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ - if (move_up != NULL) { - x = move_up->x; + if (move_down != NULL) { + x = move_down->y; } else { - while ((unsigned) x < table->subtableZ[x].next) x = table->subtableZ[x].next; } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else { /* moving up first:shorter */ /* Find top of x's symmetry group */ - while ((unsigned) x < table->subtableZ[x].next) + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_high, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up != NULL) { - x = move_up->x; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - init_group_size = x - i + 1; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; - - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ - if (move_down != NULL) { - x = move_down->y; + if (move_up != NULL) { + x = move_up->x; } else { - x = table->subtableZ[x].next; + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + i = table->subtableZ[x].next; + init_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ - result = cuddZddSymmSiftingBackward(table, move_down, + move_down = cuddZddSymmSifting_down(table, x, x_high, initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; } while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; } return(1); cuddZddSymmSiftingAuxOutOfMem: if (move_down != ZDD_MV_OOM) { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; - } + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } } if (move_up != ZDD_MV_OOM) { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } } return(0); @@ -919,13 +944,13 @@ cuddZddSymmSiftingConvAux( int x_low, int x_high) { - Move *move; - Move *move_up; /* list of up move */ - Move *move_down; /* list of down move */ - int initial_size; - int result; - int i; - int init_group_size, final_group_size; + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int init_group_size, final_group_size; initial_size = table->keysZ; @@ -934,269 +959,269 @@ cuddZddSymmSiftingConvAux( if (x == x_low) { /* Sift down */ i = table->subtableZ[x].next; - init_group_size = x - i + 1; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; - - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ - if (move_down != NULL) - x = move_down->y; - else { - while ((unsigned) x < table->subtableZ[x].next); - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + init_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ - result = cuddZddSymmSiftingBackward(table, move_down, + move_down = cuddZddSymmSifting_down(table, x, x_high, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else if (x == x_high) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_low, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ if (move_up != NULL) - x = move_up->x; - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { /* must go down first: - shorter */ - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; - - if (move_down != NULL) { - x = move_down->y; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; - - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + shorter */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ - if (move_up != NULL) { - x = move_up->x; + if (move_down != NULL) { + x = move_down->y; } else { - while ((unsigned) x < table->subtableZ[x].next) + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } i = table->subtableZ[x].next; final_group_size = x - i + 1; if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ + /* No new symmetry groups detected, + return to best position */ result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); } - else { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; } - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else { /* moving up first:shorter */ - /* Find top of x's symmetry group */ - x = table->subtableZ[x].next; + /* Find top of x's symmetry group */ + x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_high, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up != NULL) { - x = move_up->x; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } i = table->subtableZ[x].next; init_group_size = x - i + 1; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ if (move_down != NULL) { - x = move_down->y; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } i = x; while ((unsigned) i < table->subtableZ[i].next) { i = table->subtableZ[i].next; } - final_group_size = i - x + 1; + final_group_size = i - x + 1; if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ + /* No new symmetries detected, + go back to best position */ result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); } - else { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; } - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; } while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; } return(1); cuddZddSymmSiftingConvAuxOutOfMem: if (move_down != ZDD_MV_OOM) { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; - } + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } } if (move_up != ZDD_MV_OOM) { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } } return(0); @@ -1228,64 +1253,64 @@ cuddZddSymmSifting_up( int x_low, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; - int i, gytop; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gytop; moves = NULL; y = cuddZddNextLow(table, x); while (y >= x_low) { - gytop = table->subtableZ[y].next; - if (cuddZddSymmCheck(table, y, x)) { - /* Symmetry found, attach symm groups */ - table->subtableZ[y].next = x; - i = table->subtableZ[x].next; - while (table->subtableZ[i].next != (unsigned) x) - i = table->subtableZ[i].next; - table->subtableZ[i].next = gytop; - } - else if ((table->subtableZ[x].next == (unsigned) x) && - (table->subtableZ[y].next == (unsigned) y)) { - /* x and y have self symmetry */ - size = cuddZddSwapInPlace(table, y, x); - if (size == 0) - goto cuddZddSymmSifting_upOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSymmSifting_upOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - else { /* Group move */ - size = zdd_group_move(table, y, x, &moves); - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - x = gytop; - y = cuddZddNextLow(table, x); + gytop = table->subtableZ[y].next; + if (cuddZddSymmCheck(table, y, x)) { + /* Symmetry found, attach symm groups */ + table->subtableZ[y].next = x; + i = table->subtableZ[x].next; + while (table->subtableZ[i].next != (unsigned) x) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gytop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSymmSifting_upOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_upOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + else { /* Group move */ + size = zdd_group_move(table, y, x, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gytop; + y = cuddZddNextLow(table, x); } return(moves); cuddZddSymmSifting_upOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(ZDD_MV_OOM); @@ -1316,69 +1341,69 @@ cuddZddSymmSifting_down( int x_high, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; - int i, gxtop, gybot; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gxtop, gybot; moves = NULL; y = cuddZddNextHigh(table, x); while (y <= x_high) { - gybot = table->subtableZ[y].next; - while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; - if (cuddZddSymmCheck(table, x, y)) { - /* Symmetry found, attach symm groups */ - gxtop = table->subtableZ[x].next; - table->subtableZ[x].next = y; - i = table->subtableZ[y].next; - while (table->subtableZ[i].next != (unsigned) y) - i = table->subtableZ[i].next; - table->subtableZ[i].next = gxtop; - } - else if ((table->subtableZ[x].next == (unsigned) x) && - (table->subtableZ[y].next == (unsigned) y)) { - /* x and y have self symmetry */ - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddSymmSifting_downOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSymmSifting_downOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - x = y; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + if (cuddZddSymmCheck(table, x, y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtableZ[x].next; + table->subtableZ[x].next = y; + i = table->subtableZ[y].next; + while (table->subtableZ[i].next != (unsigned) y) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gxtop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSymmSifting_downOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_downOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + x = y; + y = cuddZddNextHigh(table, x); + } + else { /* Group move */ + size = zdd_group_move(table, x, y, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gybot; y = cuddZddNextHigh(table, x); } - else { /* Group move */ - size = zdd_group_move(table, x, y, &moves); - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - x = gybot; - y = cuddZddNextHigh(table, x); - } return(moves); cuddZddSymmSifting_downOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(ZDD_MV_OOM); @@ -1406,31 +1431,31 @@ cuddZddSymmSiftingBackward( Move * moves, int size) { - int i; - int i_best; - Move *move; - int res; + int i; + int i_best; + Move *move; + int res; i_best = -1; for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (move->size < size) { - i_best = i; - size = move->size; - } + if (move->size < size) { + i_best = i; + size = move->size; + } } for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (i == i_best) break; - if ((table->subtableZ[move->x].next == move->x) && - (table->subtableZ[move->y].next == move->y)) { - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) return(0); - } - else { /* Group move necessary */ - res = zdd_group_move_backward(table, move->x, move->y); - } - if (i_best == -1 && res == size) - break; + if (i == i_best) break; + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) return(0); + } + else { /* Group move necessary */ + res = zdd_group_move_backward(table, move->x, move->y); + } + if (i_best == -1 && res == size) + break; } return(1); @@ -1459,75 +1484,74 @@ zdd_group_move( int y, Move ** moves) { - Move *move; - int size; - int i, temp, gxtop, gxbot, gytop, gybot, yprev; - int swapx = 0, swapy = 0; // Suppress "might be used uninitialized" + Move *move; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + int swapx, swapy; #ifdef DD_DEBUG - assert(x < y); /* we assume that x < y */ + assert(x < y); /* we assume that x < y */ #endif /* Find top and bottom for the two groups. */ gxtop = table->subtableZ[x].next; - gytop = y; gxbot = x; gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; + gybot = table->subtableZ[gybot].next; yprev = gybot; while (x <= y) { - while (y > gxtop) { - /* Set correct symmetries. */ - temp = table->subtableZ[x].next; - if (temp == x) - temp = y; - i = gxtop; - for (;;) { - if (table->subtableZ[i].next == (unsigned) x) { - table->subtableZ[i].next = y; - break; - } else { - i = table->subtableZ[i].next; - } - } - if (table->subtableZ[y].next != (unsigned) y) { - table->subtableZ[x].next = table->subtableZ[y].next; - } else { - table->subtableZ[x].next = x; - } + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } - if (yprev != y) { - table->subtableZ[yprev].next = x; - } else { - yprev = x; - } - table->subtableZ[y].next = temp; + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto zdd_group_moveOutOfMem; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto zdd_group_moveOutOfMem; swapx = x; - swapy = y; - y = x; - x--; - } /* while y > gxtop */ - - /* Trying to find the next y. */ - if (table->subtableZ[y].next <= (unsigned) y) { - gybot = y; - } else { - y = table->subtableZ[y].next; - } + swapy = y; + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } - yprev = gxtop; - gxtop++; - gxbot++; - x = gxbot; + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; } /* while x <= y, end of group movement */ move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) - goto zdd_group_moveOutOfMem; + goto zdd_group_moveOutOfMem; move->x = swapx; move->y = swapy; move->size = table->keysZ; @@ -1538,9 +1562,9 @@ zdd_group_move( zdd_group_moveOutOfMem: while (*moves != NULL) { - move = (*moves)->next; - cuddDeallocNode(table, (DdNode *)(*moves)); - *moves = move; + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; } return(0); @@ -1566,67 +1590,66 @@ zdd_group_move_backward( int x, int y) { - int size = -1; // Suppress "might be used uninitialized" - int i, temp, gxtop, gxbot, gytop, gybot, yprev; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; #ifdef DD_DEBUG - assert(x < y); /* we assume that x < y */ + assert(x < y); /* we assume that x < y */ #endif /* Find top and bottom of the two groups. */ gxtop = table->subtableZ[x].next; - gytop = y; gxbot = x; gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; + gybot = table->subtableZ[gybot].next; yprev = gybot; while (x <= y) { - while (y > gxtop) { - /* Set correct symmetries. */ - temp = table->subtableZ[x].next; - if (temp == x) - temp = y; - i = gxtop; - for (;;) { - if (table->subtableZ[i].next == (unsigned) x) { - table->subtableZ[i].next = y; - break; - } else { - i = table->subtableZ[i].next; - } - } - if (table->subtableZ[y].next != (unsigned) y) { - table->subtableZ[x].next = table->subtableZ[y].next; - } else { - table->subtableZ[x].next = x; - } + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } - if (yprev != y) { - table->subtableZ[yprev].next = x; + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + return(0); + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; } else { - yprev = x; + y = table->subtableZ[y].next; } - table->subtableZ[y].next = temp; - - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - return(0); - y = x; - x--; - } /* while y > gxtop */ - - /* Trying to find the next y. */ - if (table->subtableZ[y].next <= (unsigned) y) { - gybot = y; - } else { - y = table->subtableZ[y].next; - } - yprev = gxtop; - gxtop++; - gxbot++; - x = gxbot; + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; } /* while x <= y, end of group movement backward */ return(size); @@ -1657,19 +1680,19 @@ cuddZddSymmSummary( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtableZ[i].next != (unsigned) i) { - TotalSymmGroups++; - x = i; - do { - TotalSymm++; - gbot = x; - x = table->subtableZ[x].next; - } while (x != i); + if (table->subtableZ[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); #ifdef DD_DEBUG - assert(table->subtableZ[gbot].next == (unsigned) i); + assert(table->subtableZ[gbot].next == (unsigned) i); #endif - i = gbot; - } + i = gbot; + } } *symvars = TotalSymm; *symgroups = TotalSymmGroups; @@ -1678,5 +1701,7 @@ cuddZddSymmSummary( } /* end of cuddZddSymmSummary */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddUtil.c b/src/bdd/cudd/cuddZddUtil.c index 72ee639a..1e89c610 100644 --- a/src/bdd/cudd/cuddZddUtil.c +++ b/src/bdd/cudd/cuddZddUtil.c @@ -7,40 +7,72 @@ Synopsis [Utility functions for ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddPrintMinterm() - <li> Cudd_zddPrintCover() - <li> Cudd_zddPrintDebug() - <li> Cudd_zddDumpDot() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddP() - </ul> - Static procedures included in this module: - <ul> - <li> zp2() - <li> zdd_print_minterm_aux() - </ul> - ] + <ul> + <li> Cudd_zddPrintMinterm() + <li> Cudd_zddPrintCover() + <li> Cudd_zddPrintDebug() + <li> Cudd_zddFirstPath() + <li> Cudd_zddNextPath() + <li> Cudd_zddCoverPathToString() + <li> Cudd_zddDumpDot() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddP() + </ul> + Static procedures included in this module: + <ul> + <li> zp2() + <li> zdd_print_minterm_aux() + <li> zddPrintCoverAux() + </ul> + ] SeeAlso [] - Author [Hyong-Kyoon Shin, In-Ho Moon] + Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -61,7 +93,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.27 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -75,9 +107,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int zp2 ARGS((DdManager *zdd, DdNode *f, st_table *t)); -static void zdd_print_minterm_aux ARGS((DdManager *zdd, DdNode *node, int level, int *list)); -static void zddPrintCoverAux ARGS((DdManager *zdd, DdNode *node, int level, int *list)); +static int zp2 (DdManager *zdd, DdNode *f, st_table *t); +static void zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list); /**AutomaticEnd***************************************************************/ @@ -104,14 +136,14 @@ Cudd_zddPrintMinterm( DdManager * zdd, DdNode * node) { - int i, size; - int *list; + int i, size; + int *list; size = (int)zdd->sizeZ; list = ABC_ALLOC(int, size); if (list == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ zdd_print_minterm_aux(zdd, node, 0, list); @@ -138,15 +170,15 @@ Cudd_zddPrintCover( DdManager * zdd, DdNode * node) { - int i, size; - int *list; + int i, size; + int *list; size = (int)zdd->sizeZ; if (size % 2 != 0) return(0); /* number of variables should be even */ list = ABC_ALLOC(int, size); if (list == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ zddPrintCoverAux(zdd, node, 0, list); @@ -186,31 +218,31 @@ Cudd_zddPrintDebug( int n, int pr) { - DdNode *empty = DD_ZERO(zdd); - int nodes; - double minterms; - int retval = 1; + DdNode *empty = DD_ZERO(zdd); + int nodes; + double minterms; + int retval = 1; if (f == empty && pr > 0) { - (void) fprintf(zdd->out,": is the empty ZDD\n"); - (void) fflush(zdd->out); - return(1); + (void) fprintf(zdd->out,": is the empty ZDD\n"); + (void) fflush(zdd->out); + return(1); } if (pr > 0) { - nodes = Cudd_zddDagSize(f); - if (nodes == CUDD_OUT_OF_MEM) retval = 0; - minterms = Cudd_zddCountMinterm(zdd, f, n); - if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; - (void) fprintf(zdd->out,": %d nodes %g minterms\n", - nodes, minterms); - if (pr > 2) - if (!cuddZddP(zdd, f)) retval = 0; - if (pr == 2 || pr > 3) { - if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; - (void) fprintf(zdd->out,"\n"); - } - (void) fflush(zdd->out); + nodes = Cudd_zddDagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_zddCountMinterm(zdd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(zdd->out,": %d nodes %g minterms\n", + nodes, minterms); + if (pr > 2) + if (!cuddZddP(zdd, f)) retval = 0; + if (pr == 2 || pr > 3) { + if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; + (void) fprintf(zdd->out,"\n"); + } + (void) fflush(zdd->out); } return(retval); @@ -256,8 +288,8 @@ Cudd_zddFirstPath( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = zdd; @@ -272,9 +304,9 @@ Cudd_zddFirstPath( nvars = zdd->sizeZ; gen->gen.cubes.cube = ABC_ALLOC(int,nvars); if (gen->gen.cubes.cube == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen); - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); } for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; @@ -282,12 +314,12 @@ Cudd_zddFirstPath( ** because a path may have nodes at all levels, including the ** constant level. */ - gen->stack.stack = ABC_ALLOC(DdNode *, nvars+1); + gen->stack.stack = ABC_ALLOC(DdNodePtr, nvars+1); if (gen->stack.stack == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen); - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen); + return(NULL); } for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; @@ -295,38 +327,38 @@ Cudd_zddFirstPath( gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - if (!cuddIsConstant(top)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[top->index] = 0; - next = cuddE(top); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == DD_ZERO(zdd)) { - /* Backtrack. */ - while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - prev = gen->stack.stack[gen->stack.sp-2]; - next = cuddT(prev); - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[prev->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[prev->index] = 2; - gen->stack.sp--; top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -361,42 +393,14 @@ Cudd_zddNextPath( /* Backtrack from previously reached terminal node. */ while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - top = gen->stack.stack[gen->stack.sp-1]; - prev = gen->stack.stack[gen->stack.sp-2]; - next = cuddT(prev); - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[prev->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[prev->index] = 2; - gen->stack.sp--; - } - - while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - if (!cuddIsConstant(top)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[top->index] = 0; - next = cuddE(top); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == DD_ZERO(zdd)) { - /* Backtrack. */ - while (1) { if (gen->stack.sp == 1) { /* The current node has no predecessor. */ gen->status = CUDD_GEN_EMPTY; gen->stack.sp--; goto done; } - prev = gen->stack.stack[gen->stack.sp-2]; + top = gen->stack.stack[gen->stack.sp-1]; + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); next = cuddT(prev); if (next != top) { /* follow the then branch next */ gen->gen.cubes.cube[prev->index] = 1; @@ -406,13 +410,41 @@ Cudd_zddNextPath( /* Pop the stack and try again. */ gen->gen.cubes.cube[prev->index] = 2; gen->stack.sp--; + } + + while (1) { top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -441,9 +473,9 @@ done: ******************************************************************************/ char * Cudd_zddCoverPathToString( - DdManager *zdd /* DD manager */, - int *path /* path of ZDD representing a cover */, - char *str /* pointer to string to use if != NULL */ + DdManager *zdd /* DD manager */, + int *path /* path of ZDD representing a cover */, + char *str /* pointer to string to use if != NULL */ ) { int nvars = zdd->sizeZ; @@ -453,31 +485,31 @@ Cudd_zddCoverPathToString( if (nvars & 1) return(NULL); nvars >>= 1; if (str == NULL) { - res = ABC_ALLOC(char, nvars+1); - if (res == NULL) return(NULL); + res = ABC_ALLOC(char, nvars+1); + if (res == NULL) return(NULL); } else { - res = str; + res = str; } for (i = 0; i < nvars; i++) { - int v = (path[2*i] << 2) | path[2*i+1]; - switch (v) { - case 0: - case 2: - case 8: - case 10: - res[i] = '-'; - break; - case 1: - case 9: - res[i] = '0'; - break; - case 4: - case 6: - res[i] = '1'; - break; - default: - res[i] = '?'; - } + int v = (path[2*i] << 2) | path[2*i+1]; + switch (v) { + case 0: + case 2: + case 8: + case 10: + res[i] = '-'; + break; + case 1: + case 9: + res[i] = '0'; + break; + case 4: + case 6: + res[i] = '1'; + break; + default: + res[i] = '?'; + } } res[nvars] = 0; @@ -522,37 +554,37 @@ Cudd_zddDumpDot( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->sizeZ; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->sizeZ; st_table *visited = NULL; st_generator *gen; - int retval; - int i, j; - int slots; - DdNodePtr *nodelist; - long refAddr, diff, mask; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; /* Take the union of the supports of each output function. */ for (i = 0; i < n; i++) { - support = Cudd_Support(dd,f[i]); - if (support == NULL) goto failure; - cuddRef(support); - scan = support; - while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); - } - Cudd_RecursiveDeref(dd,support); + support = Cudd_Support(dd,f[i]); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); } support = NULL; /* so that we do not try to free it in case of failure */ @@ -562,8 +594,8 @@ Cudd_zddDumpDot( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(f[i],visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(f[i],visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -581,22 +613,22 @@ Cudd_zddDumpDot( refAddr = (long) f[0]; diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (long) scan; } st_free_gen(gen); /* Choose the mask. */ for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + mask = (1 << i) - 1; + if (diff <= mask) break; } /* Write the header and the global attributes. */ retval = fprintf(fp,"digraph \"ZDD\" {\n"); if (retval == EOF) return(0); retval = fprintf(fp, - "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); if (retval == EOF) return(0); /* Write the input name subgraph by scanning the support array. */ @@ -611,11 +643,11 @@ Cudd_zddDumpDot( if (retval == EOF) goto failure; for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - if (inames == NULL) { - retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); - } else { - retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); - } + if (inames == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); + } if (retval == EOF) goto failure; } } @@ -626,63 +658,66 @@ Cudd_zddDumpDot( retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - if (i == n - 1) { - retval = fprintf(fp,"; }\n"); - } else { - retval = fprintf(fp," -> "); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; } /* Write rank info: All nodes with the same index have the same rank. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - retval = fprintf(fp,"{ rank = same; "); - if (retval == EOF) goto failure; - if (inames == NULL) { - retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); - } else { - retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); - } + retval = fprintf(fp,"{ rank = same; "); if (retval == EOF) goto failure; - nodelist = dd->subtableZ[i].nodelist; - slots = dd->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); + if (inames == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); + } if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; - } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; } - retval = fprintf(fp,"}\n"); - if (retval == EOF) goto failure; - } } /* All constants have the same rank. */ retval = fprintf(fp, - "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); if (retval == EOF) goto failure; nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } retval = fprintf(fp,"}\n}\n"); if (retval == EOF) goto failure; @@ -690,56 +725,63 @@ Cudd_zddDumpDot( /* Write edge info. */ /* Edges from the output nodes. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp," -> \"%lx\" [style = solid];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / + sizeof(DdNode))); + if (retval == EOF) goto failure; } /* Edges from internal nodes. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - nodelist = dd->subtableZ[i].nodelist; - slots = dd->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\";\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddT(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dashed];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) + / sizeof(DdNode)), + (void *) ((mask & (ptrint) + cuddE(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; } - } - } } /* Write constant labels. */ nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", - (mask & (long) scan) / sizeof(DdNode), cuddV(scan)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } /* Write trailer and return. */ @@ -752,7 +794,6 @@ Cudd_zddDumpDot( failure: if (sorted != NULL) ABC_FREE(sorted); - if (support != NULL) Cudd_RecursiveDeref(dd,support); if (visited != NULL) st_free_table(visited); return(0); @@ -769,7 +810,7 @@ failure: Synopsis [Prints a ZDD to the standard output. One line per node is printed.] - Description [Prints a ZDD to the standard output. One line per node is + Description [Prints a ZDD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.] SideEffects [None] @@ -818,63 +859,65 @@ zp2( DdNode * f, st_table * t) { - DdNode *n; - int T, E; - DdNode *base = DD_ONE(zdd); - + DdNode *n; + int T, E; + DdNode *base = DD_ONE(zdd); + if (f == NULL) - return(0); + return(0); if (Cudd_IsConstant(f)) { (void)fprintf(zdd->out, "ID = %d\n", (f == base)); - return(1); + return(1); } if (st_is_member(t, (char *)f) == 1) - return(1); + return(1); if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) - return(0); + return(0); #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %d\tr = %d\t", - (unsigned long)f / (unsigned long) sizeof(DdNode), f->index, f->ref); + (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); #else - (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t", - (unsigned)f / (unsigned) sizeof(DdNode), f->index, f->ref); + (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); #endif n = cuddT(f); if (Cudd_IsConstant(n)) { (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); - T = 1; + T = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n / - (unsigned long) sizeof(DdNode)); + (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / + (ptruint) sizeof(DdNode)); #else - (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / + (ptruint) sizeof(DdNode)); #endif - T = 0; + T = 0; } n = cuddE(f); if (Cudd_IsConstant(n)) { (void) fprintf(zdd->out, "E = %d\n", (n == base)); - E = 1; + E = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n / - (unsigned long) sizeof(DdNode)); + (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / + (ptruint) sizeof(DdNode)); #else - (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / + (ptruint) sizeof(DdNode)); #endif - E = 0; + E = 0; } if (E == 0) - if (zp2(zdd, cuddE(f), t) == 0) return(0); + if (zp2(zdd, cuddE(f), t) == 0) return(0); if (T == 0) - if (zp2(zdd, cuddT(f), t) == 0) return(0); + if (zp2(zdd, cuddT(f), t) == 0) return(0); return(1); } /* end of zp2 */ @@ -898,54 +941,54 @@ zdd_print_minterm_aux( int level /* depth in the recursion */, int * list /* current recursion path */) { - DdNode *Nv, *Nnv; - int i, v; - DdNode *base = DD_ONE(zdd); + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); if (Cudd_IsConstant(node)) { - if (node == base) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i++) { + v = list[i]; + if (v == 0) + (void) fprintf(zdd->out,"0"); + else if (v == 1) + (void) fprintf(zdd->out,"1"); + else if (v == 3) + (void) fprintf(zdd->out,"@"); /* should never happen */ + else + (void) fprintf(zdd->out,"-"); + } + (void) fprintf(zdd->out," 1\n"); + } + } else { /* Check for missing variable. */ - if (level != zdd->sizeZ) { - list[zdd->invpermZ[level]] = 0; - zdd_print_minterm_aux(zdd, node, level + 1, list); - return; + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; } - /* Terminal case: Print one cube based on the current recursion - ** path. - */ - for (i = 0; i < zdd->sizeZ; i++) { - v = list[i]; - if (v == 0) - (void) fprintf(zdd->out,"0"); - else if (v == 1) - (void) fprintf(zdd->out,"1"); - else if (v == 3) - (void) fprintf(zdd->out,"@"); /* should never happen */ - else - (void) fprintf(zdd->out,"-"); + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + return; } - (void) fprintf(zdd->out," 1\n"); - } - } else { - /* Check for missing variable. */ - if (level != cuddIZ(zdd,node->index)) { - list[zdd->invpermZ[level]] = 0; - zdd_print_minterm_aux(zdd, node, level + 1, list); - return; - } - Nnv = cuddE(node); - Nv = cuddT(node); - if (Nv == Nnv) { - list[node->index] = 2; + list[node->index] = 1; + zdd_print_minterm_aux(zdd, Nv, level + 1, list); + list[node->index] = 0; zdd_print_minterm_aux(zdd, Nnv, level + 1, list); - return; - } - - list[node->index] = 1; - zdd_print_minterm_aux(zdd, Nv, level + 1, list); - list[node->index] = 0; - zdd_print_minterm_aux(zdd, Nnv, level + 1, list); } return; @@ -970,57 +1013,59 @@ zddPrintCoverAux( int level /* depth in the recursion */, int * list /* current recursion path */) { - DdNode *Nv, *Nnv; - int i, v; - DdNode *base = DD_ONE(zdd); + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); if (Cudd_IsConstant(node)) { - if (node == base) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i += 2) { + v = list[i] * 4 + list[i+1]; + if (v == 0) + (void) putc('-',zdd->out); + else if (v == 4) + (void) putc('1',zdd->out); + else if (v == 1) + (void) putc('0',zdd->out); + else + (void) putc('@',zdd->out); /* should never happen */ + } + (void) fprintf(zdd->out," 1\n"); + } + } else { /* Check for missing variable. */ - if (level != zdd->sizeZ) { - list[zdd->invpermZ[level]] = 0; - zddPrintCoverAux(zdd, node, level + 1, list); - return; + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; } - /* Terminal case: Print one cube based on the current recursion - ** path. - */ - for (i = 0; i < zdd->sizeZ; i += 2) { - v = list[i] * 4 + list[i+1]; - if (v == 0) - (void) putc('-',zdd->out); - else if (v == 4) - (void) putc('1',zdd->out); - else if (v == 1) - (void) putc('0',zdd->out); - else - (void) putc('@',zdd->out); /* should never happen */ + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + return; } - (void) fprintf(zdd->out," 1\n"); - } - } else { - /* Check for missing variable. */ - if (level != cuddIZ(zdd,node->index)) { - list[zdd->invpermZ[level]] = 0; - zddPrintCoverAux(zdd, node, level + 1, list); - return; - } - Nnv = cuddE(node); - Nv = cuddT(node); - if (Nv == Nnv) { - list[node->index] = 2; + list[node->index] = 1; + zddPrintCoverAux(zdd, Nv, level + 1, list); + list[node->index] = 0; zddPrintCoverAux(zdd, Nnv, level + 1, list); - return; - } - - list[node->index] = 1; - zddPrintCoverAux(zdd, Nv, level + 1, list); - list[node->index] = 0; - zddPrintCoverAux(zdd, Nnv, level + 1, list); } return; } /* end of zddPrintCoverAux */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/r7x8.1.out b/src/bdd/cudd/r7x8.1.out new file mode 100644 index 00000000..0e7108ee --- /dev/null +++ b/src/bdd/cudd/r7x8.1.out @@ -0,0 +1,377 @@ +# TestCudd Version #1.0, Release date 3/17/01 +# ./testcudd -p 2 r7x8.1.mat +:name: r7x8.1.mat: 7 rows 9 columns +:1: M: 63 nodes 5 leaves 52 minterms +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +:2: time to read the matrix = 0.00 sec +:3: C: 22 nodes 1 leaves 52 minterms +0000---- 1 +0001-0-- 1 +0001-1-0 1 +001000-- 1 +001001-0 1 +001010-- 1 +001011-1 1 +001100-- 1 +001101-0 1 +001110-- 1 +01-0-0-0 1 +1000---- 1 +1001-0-- 1 +1001-1-0 1 +101000-1 1 +101001-- 1 +101100-- 1 +101101-0 1 +1100-0-0 1 +111000-0 1 + +Testing iterator on cubes: +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +Testing prime expansion of cubes: +-000---- 1 +-00--0-- 1 +0--0-0-0 1 +--00-0-0 1 +-0-100-- 1 +10-001-- 1 +-00----0 1 +00---0-- 1 +-1-000-0 1 +-0--01-0 1 +-0--00-1 1 +00-01--1 1 + +Testing iterator on primes (CNF): +-0-0---- 1 +-0---0-- 1 +0-0-0--- 1 +-0-----0 1 +---0-0-0 1 +0101-1-1 1 +--0-00-1 1 +1-0-10-0 1 + +Cache used slots = 58.06% (expected 58.92%) +xor1: 14 nodes 1 leaves 28 minterms +000--1-1 1 +001-11-1 1 +01---0-0 1 +100--1-1 1 +101-00-0 1 +101-01-1 1 +110--0-0 1 +111-00-0 1 + +Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms +11110010 1 + +Minimum Hamming distance = 1 +ycube: 5 nodes 1 leaves 8 minterms +-0-0-0-0 1 + +CP: 11 nodes 1 leaves 7 minterms +00-0-0-0 1 +1000-0-0 1 +101000-1 1 + +:4: ineq: 10 nodes 1 leaves 42 minterms +001000-- 1 +00101--- 1 +1000---- 1 +100100-- 1 +10011--- 1 +101----- 1 +111000-- 1 +11101--- 1 + +10------ 1 +-01----- 1 +1-1----- 1 +-0-0---- 1 +1--0---- 1 +-0--10-- 1 +--1010-- 1 +1---10-- 1 + +:4: ess: 1 nodes 1 leaves 128 minterms +-------- 1 + +:5: shortP: 7 nodes 1 leaves 2 minterms +000000-- 1 + +:5b: largest: 4 nodes 1 leaves 16 minterms +01-1---- 1 + +The value of M along the chosen shortest path is 1 +:6: shortP: 5 nodes 1 leaves 8 minterms +0000---- 1 + +Average distance: 4133.34 +Number of variables = 8 Number of slots = 2304 +Number of keys = 995 Number of min dead = 9216 +walsh1: 16 nodes 2 leaves 256 minterms +-0--0--0--0- 1 +-0--0--0--10 1 +-0--0--0--11 -1 +-0--0--10-0- 1 +-0--0--10-10 1 +-0--0--10-11 -1 +-0--0--11-0- -1 +-0--0--11-10 -1 +-0--0--11-11 1 +-0--10-0--0- 1 +-0--10-0--10 1 +-0--10-0--11 -1 +-0--10-10-0- 1 +-0--10-10-10 1 +-0--10-10-11 -1 +-0--10-11-0- -1 +-0--10-11-10 -1 +-0--10-11-11 1 +-0--11-0--0- -1 +-0--11-0--10 -1 +-0--11-0--11 1 +-0--11-10-0- -1 +-0--11-10-10 -1 +-0--11-10-11 1 +-0--11-11-0- 1 +-0--11-11-10 1 +-0--11-11-11 -1 +-10-0--0--0- 1 +-10-0--0--10 1 +-10-0--0--11 -1 +-10-0--10-0- 1 +-10-0--10-10 1 +-10-0--10-11 -1 +-10-0--11-0- -1 +-10-0--11-10 -1 +-10-0--11-11 1 +-10-10-0--0- 1 +-10-10-0--10 1 +-10-10-0--11 -1 +-10-10-10-0- 1 +-10-10-10-10 1 +-10-10-10-11 -1 +-10-10-11-0- -1 +-10-10-11-10 -1 +-10-10-11-11 1 +-10-11-0--0- -1 +-10-11-0--10 -1 +-10-11-0--11 1 +-10-11-10-0- -1 +-10-11-10-10 -1 +-10-11-10-11 1 +-10-11-11-0- 1 +-10-11-11-10 1 +-10-11-11-11 -1 +-11-0--0--0- -1 +-11-0--0--10 -1 +-11-0--0--11 1 +-11-0--10-0- -1 +-11-0--10-10 -1 +-11-0--10-11 1 +-11-0--11-0- 1 +-11-0--11-10 1 +-11-0--11-11 -1 +-11-10-0--0- -1 +-11-10-0--10 -1 +-11-10-0--11 1 +-11-10-10-0- -1 +-11-10-10-10 -1 +-11-10-10-11 1 +-11-10-11-0- 1 +-11-10-11-10 1 +-11-10-11-11 -1 +-11-11-0--0- 1 +-11-11-0--10 1 +-11-11-0--11 -1 +-11-11-10-0- 1 +-11-11-10-10 1 +-11-11-10-11 -1 +-11-11-11-0- -1 +-11-11-11-10 -1 +-11-11-11-11 1 + +wtw: 14 nodes 2 leaves 16 minterms +0-00-00-00-0 16 +0-00-00-01-1 16 +0-00-01-10-0 16 +0-00-01-11-1 16 +0-01-10-00-0 16 +0-01-10-01-1 16 +0-01-11-10-0 16 +0-01-11-11-1 16 +1-10-00-00-0 16 +1-10-00-01-1 16 +1-10-01-10-0 16 +1-10-01-11-1 16 +1-11-10-00-0 16 +1-11-10-01-1 16 +1-11-11-10-0 16 +1-11-11-11-1 16 + +Average length of non-empty lists = 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 0 +Arc violation threshold: 0 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4274484 +Peak number of nodes: 2044 +Peak number of live nodes: 119 +Number of BDD variables: 9 +Number of ZDD variables: 0 +Number of cache entries: 2048 +Number of cache look-ups: 2846 +Number of cache hits: 715 +Number of cache insertions: 2289 +Number of cache collisions: 937 +Number of cache deletions: 1348 +Cache used slots = 66.02% (expected 67.30%) +Soft limit for cache size: 13312 +Number of buckets in unique table: 2560 +Used buckets in unique table: 0.51% (expected 0.51%) +Number of BDD and ADD nodes: 13 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 1091 +Total number of nodes reclaimed: 950 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131644K +Virtual data size = 151K + data size initialized = 17K + data size uninitialized = 0K + data size sbrk = 134K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1318 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 1 diff --git a/src/bdd/cudd/testcudd.c b/src/bdd/cudd/testcudd.c index 1b6de5aa..f21f7816 100644 --- a/src/bdd/cudd/testcudd.c +++ b/src/bdd/cudd/testcudd.c @@ -16,19 +16,43 @@ Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ -#include "util_hack.h" +#include "util.h" #include "cuddInt.h" -ABC_NAMESPACE_IMPL_START - - /*---------------------------------------------------------------------------*/ /* Constant declarations */ @@ -41,10 +65,10 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.20 2009/03/08 02:49:02 fabio Exp $"; #endif -static char *onames[] = { "C", "M" }; /* names of functions to be dumped */ +static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */ /**AutomaticStart*************************************************************/ @@ -52,12 +76,12 @@ static char *onames[] = { "C", "M" }; /* names of functions to be dumped */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void usage ARGS((char * prog)); -static FILE *open_file ARGS((char *filename, char *mode)); -static int testIterators ARGS((DdManager *dd, DdNode *M, DdNode *C, int pr)); -static int testXor ARGS((DdManager *dd, DdNode *f, int pr, int nvars)); -static int testHamming ARGS((DdManager *dd, DdNode *f, int pr, int nvars)); -static int testWalsh ARGS((DdManager *dd, int N, int cmu, int approach, int pr)); +static void usage (char * prog); +static FILE *open_file (char *filename, const char *mode); +static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr); +static int testXor (DdManager *dd, DdNode *f, int pr, int nvars); +static int testHamming (DdManager *dd, DdNode *f, int pr); +static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr); /**AutomaticEnd***************************************************************/ @@ -77,17 +101,17 @@ int main(int argc, char **argv) { FILE *fp; /* pointer to input file */ - char *file = ""; /* input file name */ + char *file = (char *) ""; /* input file name */ FILE *dfp = NULL; /* pointer to dump file */ char *dfile; /* file for DD dump */ DdNode *dfunc[2]; /* addresses of the functions to be dumped */ DdManager *dd; /* pointer to DD manager */ - DdNode *one, *zero; /* fast access to constant functions */ + DdNode *one; /* fast access to constant function */ DdNode *M; DdNode **x; /* pointers to variables */ DdNode **y; /* pointers to variables */ - DdNode **xn; /* complements of row variables */ - DdNode **yn_; /* complements of column variables */ + DdNode **xn; /* complements of row variables */ + DdNode **yn_; /* complements of column variables */ DdNode **xvars; DdNode **yvars; DdNode *C; /* result of converting from ADD to BDD */ @@ -149,7 +173,7 @@ main(int argc, char **argv) blifOrDot = 0; /* dot format */ /* Parse command line. */ - while ((c = util_getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) + while ((c = util_getopt(argc, argv, (char *) "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) != EOF) { switch(c) { case 'C': @@ -216,7 +240,7 @@ main(int argc, char **argv) } if (argc - util_optind == 0) { - file = "-"; + file = (char *) "-"; } else if (argc - util_optind == 1) { file = argv[util_optind]; } else { @@ -241,7 +265,6 @@ main(int argc, char **argv) /* Initialize manager and provide easy reference to terminals. */ dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); one = DD_ONE(dd); - zero = DD_ZERO(dd); dd->groupcheck = (Cudd_AggregationType) groupcheck; if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); @@ -335,7 +358,7 @@ main(int argc, char **argv) if (retval == 0) exit(2); /* Test Hamming distance functions. */ - retval = testHamming(dd,C,pr,nx+ny); + retval = testHamming(dd,C,pr); if (retval == 0) exit(2); /* Test selection functions. */ @@ -356,6 +379,43 @@ main(int argc, char **argv) } Cudd_RecursiveDeref(dd, CPr); } + + /* Test inequality generator. */ + { + int Nmin = ddMin(nx,ny); + int q; + DdGen *gen; + int *cube; + DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars); + if (f == NULL) exit(2); + Cudd_Ref(f); + if (pr>0) { + (void) printf(":4: ineq"); + Cudd_PrintDebug(dd,f,nx+ny,pr); + if (pr>1) { + Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + } + Cudd_IterDerefBdd(dd, f); + } FREE(xvars); FREE(yvars); Cudd_RecursiveDeref(dd, CP); @@ -419,7 +479,7 @@ main(int argc, char **argv) } /* Reorder if so requested. */ - if (approach != CUDD_REORDER_NONE) { + if (approach != CUDD_REORDER_NONE) { #ifndef DD_STATS retval = Cudd_EnableReorderingReporting(dd); if (retval == 0) { @@ -502,9 +562,10 @@ main(int argc, char **argv) dfunc[1] = M; if (blifOrDot == 1) { /* Only dump C because blif cannot handle ADDs */ - retval = Cudd_DumpBlif(dd,1,dfunc,NULL,onames,NULL,dfp); + retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, + NULL,dfp,0); } else { - retval = Cudd_DumpDot(dd,2,dfunc,NULL,onames,dfp); + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); } if (retval != 1) { (void) fprintf(stderr,"abnormal termination\n"); @@ -524,9 +585,9 @@ main(int argc, char **argv) } if (pr>0) { (void) printf("Number of variables = %6d\t",dd->size); - (void) printf("Number of slots = %6d\n",dd->slots); - (void) printf("Number of keys = %6d\t",dd->keys); - (void) printf("Number of min dead = %6d\n",dd->minDead); + (void) printf("Number of slots = %6u\n",dd->slots); + (void) printf("Number of keys = %6u\t",dd->keys); + (void) printf("Number of min dead = %6u\n",dd->minDead); } } while (multiple && !feof(fp)); @@ -643,15 +704,15 @@ usage(char *prog) ******************************************************************************/ static FILE * -open_file(char *filename, char *mode) +open_file(char *filename, const char *mode) { FILE *fp; if (strcmp(filename, "-") == 0) { - return mode[0] == 'r' ? stdin : stdout; + return mode[0] == 'r' ? stdin : stdout; } else if ((fp = fopen(filename, mode)) == NULL) { - perror(filename); - exit(1); + perror(filename); + exit(1); } return fp; @@ -798,34 +859,56 @@ testIterators( if (!Cudd_bddPrintCover(dd,C,C)) return(0); } + if (pr>1) { + (void) printf("Testing iterator on primes (CNF):\n"); + Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + /* Test iterator on nodes. */ if (pr>2) { - DdGen *gen; DdNode *node; (void) printf("Testing iterator on nodes:\n"); Cudd_ForeachNode(dd,M,gen,node) { if (Cudd_IsConstant(node)) { #if SIZEOF_VOID_P == 8 (void) printf("ID = 0x%lx\tvalue = %-9g\n", - (unsigned long) node / - (unsigned long) sizeof(DdNode), + (ptruint) node / + (ptruint) sizeof(DdNode), Cudd_V(node)); #else (void) printf("ID = 0x%x\tvalue = %-9g\n", - (unsigned int) node / - (unsigned int) sizeof(DdNode), + (ptruint) node / + (ptruint) sizeof(DdNode), Cudd_V(node)); #endif } else { #if SIZEOF_VOID_P == 8 - (void) printf("ID = 0x%lx\tindex = %d\tr = %d\n", - (unsigned long) node / - (unsigned long) sizeof(DdNode), + (void) printf("ID = 0x%lx\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), node->index, node->ref); #else - (void) printf("ID = 0x%x\tindex = %d\tr = %d\n", - (unsigned int) node / - (unsigned int) sizeof(DdNode), + (void) printf("ID = 0x%x\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), node->index, node->ref); #endif } @@ -932,8 +1015,7 @@ static int testHamming( DdManager *dd, DdNode *f, - int pr, - int nvars) + int pr) { DdNode **vars, *minBdd, *zero, *scan; int i; @@ -989,5 +1071,3 @@ testHamming( return(1); } /* end of testHamming */ -ABC_NAMESPACE_IMPL_END - diff --git a/src/bdd/epd/epd.c b/src/bdd/epd/epd.c index f86f24f4..3f92af94 100644 --- a/src/bdd/epd/epd.c +++ b/src/bdd/epd/epd.c @@ -12,12 +12,39 @@ Author [In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: epd.c,v 1.1.1.1 2003/02/24 22:23:57 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.c,v 1.10 2004/08/13 18:20:30 fabio Exp $] ******************************************************************************/ @@ -30,8 +57,6 @@ ABC_NAMESPACE_IMPL_START - - /**Function******************************************************************** Synopsis [Allocates an EpDouble struct.] @@ -44,9 +69,9 @@ ABC_NAMESPACE_IMPL_START ******************************************************************************/ EpDouble * -EpdAlloc() +EpdAlloc(void) { - EpDouble *epd; + EpDouble *epd; epd = ABC_ALLOC(EpDouble, 1); return(epd); @@ -97,9 +122,9 @@ EpdFree(EpDouble *epd) /**Function******************************************************************** - Synopsis [Multiplies two arbitrary precision double values.] + Synopsis [Converts an arbitrary precision double value to a string.] - Description [Multiplies two arbitrary precision double values.] + Description [Converts an arbitrary precision double value to a string.] SideEffects [] @@ -109,9 +134,9 @@ EpdFree(EpDouble *epd) void EpdGetString(EpDouble *epd, char *str) { - double value; - int exponent; - char *pos; + double value; + int exponent; + char *pos; if (IsNanDouble(epd->type.value)) { sprintf(str, "NaN"); @@ -125,7 +150,7 @@ EpdGetString(EpDouble *epd, char *str) } assert(epd->type.bits.exponent == EPD_MAX_BIN || - epd->type.bits.exponent == 0); + epd->type.bits.exponent == 0); EpdGetValueAndDecimalExponent(epd, &value, &exponent); sprintf(str, "%e", value); @@ -179,15 +204,15 @@ EpdConvert(double value, EpDouble *epd) void EpdMultiply(EpDouble *epd1, double value) { - EpDouble epd2; - double tmp; - int exponent; + EpDouble epd2; + double tmp; + int exponent; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { - int sign; + int sign; EpdConvert(value, &epd2); sign = epd1->type.bits.sign ^ epd2.type.bits.sign; @@ -220,14 +245,14 @@ EpdMultiply(EpDouble *epd1, double value) void EpdMultiply2(EpDouble *epd1, EpDouble *epd2) { - double value; - int exponent; + double value; + int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd1, sign); @@ -259,14 +284,14 @@ EpdMultiply2(EpDouble *epd1, EpDouble *epd2) void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2) { - double value; - int exponent; + double value; + int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd1, sign); @@ -299,7 +324,7 @@ EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd3, sign); @@ -333,7 +358,7 @@ EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd3, sign); @@ -360,15 +385,15 @@ EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) void EpdDivide(EpDouble *epd1, double value) { - EpDouble epd2; - double tmp; - int exponent; + EpDouble epd2; + double tmp; + int exponent; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { - int sign; + int sign; EpdConvert(value, &epd2); if (EpdIsInf(epd1) && IsInfDouble(value)) { @@ -413,14 +438,14 @@ EpdDivide(EpDouble *epd1, double value) void EpdDivide2(EpDouble *epd1, EpDouble *epd2) { - double value; - int exponent; + double value; + int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { EpdMakeNan(epd1); @@ -468,7 +493,7 @@ EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) EpdMakeNan(epd3); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { EpdMakeNan(epd3); @@ -510,21 +535,21 @@ EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) void EpdAdd(EpDouble *epd1, double value) { - EpDouble epd2; - double tmp; - int exponent, diff; + EpDouble epd2; + double tmp; + int exponent, diff; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { - int sign; + int sign; EpdConvert(value, &epd2); if (EpdIsInf(epd1) && IsInfDouble(value)) { sign = epd1->type.bits.sign ^ epd2.type.bits.sign; if (sign == 1) - EpdMakeNan(epd1); + EpdMakeNan(epd1); } else if (EpdIsInf(&epd2)) { EpdCopy(&epd2, epd1); } @@ -572,19 +597,19 @@ EpdAdd(EpDouble *epd1, double value) void EpdAdd2(EpDouble *epd1, EpDouble *epd2) { - double value; - int exponent, diff; + double value; + int exponent, diff; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; if (sign == 1) - EpdMakeNan(epd1); + EpdMakeNan(epd1); } else if (EpdIsInf(epd2)) { EpdCopy(epd2, epd1); } @@ -598,7 +623,7 @@ EpdAdd2(EpDouble *epd1, EpDouble *epd2) diff = epd1->exponent - epd2->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value + - epd2->type.value / pow((double)2.0, (double)diff); + epd2->type.value / pow((double)2.0, (double)diff); } else value = epd1->type.value; exponent = epd1->exponent; @@ -606,7 +631,7 @@ EpdAdd2(EpDouble *epd1, EpDouble *epd2) diff = epd2->exponent - epd1->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value / pow((double)2.0, (double)diff) + - epd2->type.value; + epd2->type.value; } else value = epd2->type.value; exponent = epd2->exponent; @@ -634,21 +659,21 @@ EpdAdd2(EpDouble *epd1, EpDouble *epd2) void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) { - double value; - int exponent, diff; + double value; + int exponent, diff; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd3); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; if (sign == 1) - EpdMakeNan(epd3); + EpdMakeNan(epd3); else - EpdCopy(epd1, epd3); + EpdCopy(epd1, epd3); } else if (EpdIsInf(epd1)) { EpdCopy(epd1, epd3); } else { @@ -664,7 +689,7 @@ EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) diff = epd1->exponent - epd2->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value + - epd2->type.value / pow((double)2.0, (double)diff); + epd2->type.value / pow((double)2.0, (double)diff); } else value = epd1->type.value; exponent = epd1->exponent; @@ -672,7 +697,7 @@ EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) diff = epd2->exponent - epd1->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value / pow((double)2.0, (double)diff) + - epd2->type.value; + epd2->type.value; } else value = epd2->type.value; exponent = epd2->exponent; @@ -700,21 +725,21 @@ EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) void EpdSubtract(EpDouble *epd1, double value) { - EpDouble epd2; - double tmp; - int exponent, diff; + EpDouble epd2; + double tmp; + int exponent, diff; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { - int sign; + int sign; EpdConvert(value, &epd2); if (EpdIsInf(epd1) && IsInfDouble(value)) { sign = epd1->type.bits.sign ^ epd2.type.bits.sign; if (sign == 0) - EpdMakeNan(epd1); + EpdMakeNan(epd1); } else if (EpdIsInf(&epd2)) { EpdCopy(&epd2, epd1); } @@ -762,19 +787,19 @@ EpdSubtract(EpDouble *epd1, double value) void EpdSubtract2(EpDouble *epd1, EpDouble *epd2) { - double value; - int exponent, diff; + double value; + int exponent, diff; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; if (sign == 0) - EpdMakeNan(epd1); + EpdMakeNan(epd1); } else if (EpdIsInf(epd2)) { EpdCopy(epd2, epd1); } @@ -788,7 +813,7 @@ EpdSubtract2(EpDouble *epd1, EpDouble *epd2) diff = epd1->exponent - epd2->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value - - epd2->type.value / pow((double)2.0, (double)diff); + epd2->type.value / pow((double)2.0, (double)diff); } else value = epd1->type.value; exponent = epd1->exponent; @@ -796,7 +821,7 @@ EpdSubtract2(EpDouble *epd1, EpDouble *epd2) diff = epd2->exponent - epd1->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value / pow((double)2.0, (double)diff) - - epd2->type.value; + epd2->type.value; } else value = epd2->type.value * (double)(-1.0); exponent = epd2->exponent; @@ -824,21 +849,21 @@ EpdSubtract2(EpDouble *epd1, EpDouble *epd2) void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) { - double value; - int exponent, diff; + double value; + int exponent, diff; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd3); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { - int sign; + int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; if (sign == 0) - EpdCopy(epd1, epd3); + EpdCopy(epd1, epd3); else - EpdMakeNan(epd3); + EpdMakeNan(epd3); } else if (EpdIsInf(epd1)) { EpdCopy(epd1, epd1); } else { @@ -855,7 +880,7 @@ EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) diff = epd1->exponent - epd2->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value - - epd2->type.value / pow((double)2.0, (double)diff); + epd2->type.value / pow((double)2.0, (double)diff); } else value = epd1->type.value; exponent = epd1->exponent; @@ -863,7 +888,7 @@ EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3) diff = epd2->exponent - epd1->exponent; if (diff <= EPD_MAX_BIN) { value = epd1->type.value / pow((double)2.0, (double)diff) - - epd2->type.value; + epd2->type.value; } else value = epd2->type.value * (double)(-1.0); exponent = epd2->exponent; @@ -895,7 +920,7 @@ EpdPow2(int n, EpDouble *epd) EpdConvert(pow((double)2.0, (double)n), epd); } else { EpDouble epd1, epd2; - int n1, n2; + int n1, n2; n1 = n / 2; n2 = n - n1; @@ -926,7 +951,7 @@ EpdPow2Decimal(int n, EpDouble *epd) EpdNormalizeDecimal(epd); } else { EpDouble epd1, epd2; - int n1, n2; + int n1, n2; n1 = n / 2; n2 = n - n1; @@ -951,7 +976,7 @@ EpdPow2Decimal(int n, EpDouble *epd) void EpdNormalize(EpDouble *epd) { - int exponent; + int exponent; if (IsNanOrInfDouble(epd->type.value)) { epd->exponent = 0; @@ -981,7 +1006,7 @@ EpdNormalize(EpDouble *epd) void EpdNormalizeDecimal(EpDouble *epd) { - int exponent; + int exponent; if (IsNanOrInfDouble(epd->type.value)) { epd->exponent = 0; @@ -1008,7 +1033,7 @@ EpdNormalizeDecimal(EpDouble *epd) void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent) { - EpDouble epd1, epd2; + EpDouble epd1, epd2; if (EpdIsNanOrInf(epd)) return; @@ -1042,8 +1067,8 @@ EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent) int EpdGetExponent(double value) { - int exponent; - EpDouble epd; + int exponent; + EpDouble epd; epd.type.value = value; exponent = epd.type.bits.exponent; @@ -1065,8 +1090,8 @@ EpdGetExponent(double value) int EpdGetExponentDecimal(double value) { - char *pos, str[24]; - int exponent; + char *pos, str[24]; + int exponent; sprintf(str, "%E", value); pos = strstr(str, "E"); @@ -1250,12 +1275,13 @@ EpdIsNanOrInf(EpDouble *epd) int IsInfDouble(double value) { - IeeeDouble *ptr = (IeeeDouble *)(&value); + EpType val; - if (ptr->exponent == EPD_EXP_INF && - ptr->mantissa0 == 0 && - ptr->mantissa1 == 0) { - if (ptr->sign == 0) + val.value = value; + if (val.bits.exponent == EPD_EXP_INF && + val.bits.mantissa0 == 0 && + val.bits.mantissa1 == 0) { + if (val.bits.sign == 0) return(1); else return(-1); @@ -1278,13 +1304,14 @@ IsInfDouble(double value) int IsNanDouble(double value) { - IeeeNan *ptr = (IeeeNan *)(&value); - - if (ptr->exponent == EPD_EXP_INF && - ptr->sign == 1 && - ptr->quiet_bit == 1 && - ptr->mantissa0 == 0 && - ptr->mantissa1 == 0) { + EpType val; + + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.sign == 1 && + val.nan.quiet_bit == 1 && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0) { return(1); } return(0); @@ -1305,15 +1332,16 @@ IsNanDouble(double value) int IsNanOrInfDouble(double value) { - IeeeNan *ptr = (IeeeNan *)(&value); + EpType val; - if (ptr->exponent == EPD_EXP_INF && - ptr->mantissa0 == 0 && - ptr->mantissa1 == 0 && - (ptr->sign == 1 || ptr->quiet_bit == 0)) { + val.value = value; + if (val.nan.exponent == EPD_EXP_INF && + val.nan.mantissa0 == 0 && + val.nan.mantissa1 == 0 && + (val.nan.sign == 1 || val.nan.quiet_bit == 0)) { return(1); } return(0); } -ABC_NAMESPACE_IMPL_END +ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/epd/epd.h b/src/bdd/epd/epd.h index 733d7a52..1ca033d2 100644 --- a/src/bdd/epd/epd.h +++ b/src/bdd/epd/epd.h @@ -12,29 +12,54 @@ Author [In-Ho Moon] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: epd.h,v 1.1.1.1 2003/02/24 22:23:57 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: epd.h,v 1.9 2004/08/13 18:20:30 fabio Exp $] ******************************************************************************/ #ifndef _EPD #define _EPD - ABC_NAMESPACE_HEADER_START - /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define EPD_MAX_BIN 1023 -#define EPD_MAX_DEC 308 -#define EPD_EXP_INF 0x7ff +#define EPD_MAX_BIN 1023 +#define EPD_MAX_DEC 308 +#define EPD_EXP_INF 0x7ff /*---------------------------------------------------------------------------*/ /* Structure declarations */ @@ -49,15 +74,15 @@ ABC_NAMESPACE_HEADER_START SeeAlso [] ******************************************************************************/ -#ifdef EPD_BIG_ENDIAN -struct IeeeDoubleStruct { /* BIG_ENDIAN */ +#ifdef EPD_BIG_ENDIAN +struct IeeeDoubleStruct { /* BIG_ENDIAN */ unsigned int sign: 1; unsigned int exponent: 11; unsigned int mantissa0: 20; unsigned int mantissa1: 32; }; #else -struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ +struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ unsigned int mantissa1: 32; unsigned int mantissa0: 20; unsigned int exponent: 11; @@ -74,8 +99,8 @@ struct IeeeDoubleStruct { /* LITTLE_ENDIAN */ SeeAlso [] ******************************************************************************/ -#ifdef EPD_BIG_ENDIAN -struct IeeeNanStruct { /* BIG_ENDIAN */ +#ifdef EPD_BIG_ENDIAN +struct IeeeNanStruct { /* BIG_ENDIAN */ unsigned int sign: 1; unsigned int exponent: 11; unsigned int quiet_bit: 1; @@ -83,7 +108,7 @@ struct IeeeNanStruct { /* BIG_ENDIAN */ unsigned int mantissa1: 32; }; #else -struct IeeeNanStruct { /* LITTLE_ENDIAN */ +struct IeeeNanStruct { /* LITTLE_ENDIAN */ unsigned int mantissa1: 32; unsigned int mantissa0: 19; unsigned int quiet_bit: 1; @@ -101,13 +126,15 @@ struct IeeeNanStruct { /* LITTLE_ENDIAN */ SeeAlso [] ******************************************************************************/ +union EpTypeUnion { + double value; + struct IeeeDoubleStruct bits; + struct IeeeNanStruct nan; +}; + struct EpDoubleStruct { - union { - double value; - struct IeeeDoubleStruct bits; - struct IeeeNanStruct nan; - } type; - int exponent; + union EpTypeUnion type; + int exponent; }; /*---------------------------------------------------------------------------*/ @@ -116,51 +143,53 @@ struct EpDoubleStruct { typedef struct EpDoubleStruct EpDouble; typedef struct IeeeDoubleStruct IeeeDouble; typedef struct IeeeNanStruct IeeeNan; +typedef union EpTypeUnion EpType; +/**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EpDouble *EpdAlloc(); -int EpdCmp(const char *key1, const char *key2); -void EpdFree(EpDouble *epd); -void EpdGetString(EpDouble *epd, char *str); -void EpdConvert(double value, EpDouble *epd); -void EpdMultiply(EpDouble *epd1, double value); -void EpdMultiply2(EpDouble *epd1, EpDouble *epd2); -void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2); -void EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); -void EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); -void EpdDivide(EpDouble *epd1, double value); -void EpdDivide2(EpDouble *epd1, EpDouble *epd2); -void EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); -void EpdAdd(EpDouble *epd1, double value); -void EpdAdd2(EpDouble *epd1, EpDouble *epd2); -void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); -void EpdSubtract(EpDouble *epd1, double value); -void EpdSubtract2(EpDouble *epd1, EpDouble *epd2); -void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); -void EpdPow2(int n, EpDouble *epd); -void EpdPow2Decimal(int n, EpDouble *epd); -void EpdNormalize(EpDouble *epd); -void EpdNormalizeDecimal(EpDouble *epd); -void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent); -int EpdGetExponent(double value); -int EpdGetExponentDecimal(double value); -void EpdMakeInf(EpDouble *epd, int sign); -void EpdMakeZero(EpDouble *epd, int sign); -void EpdMakeNan(EpDouble *epd); -void EpdCopy(EpDouble *from, EpDouble *to); -int EpdIsInf(EpDouble *epd); -int EpdIsZero(EpDouble *epd); -int EpdIsNan(EpDouble *epd); -int EpdIsNanOrInf(EpDouble *epd); -int IsInfDouble(double value); -int IsNanDouble(double value); -int IsNanOrInfDouble(double value); - - +extern EpDouble *EpdAlloc(void); +extern int EpdCmp(const char *key1, const char *key2); +extern void EpdFree(EpDouble *epd); +extern void EpdGetString(EpDouble *epd, char *str); +extern void EpdConvert(double value, EpDouble *epd); +extern void EpdMultiply(EpDouble *epd1, double value); +extern void EpdMultiply2(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2); +extern void EpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdDivide(EpDouble *epd1, double value); +extern void EpdDivide2(EpDouble *epd1, EpDouble *epd2); +extern void EpdDivide3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdAdd(EpDouble *epd1, double value); +extern void EpdAdd2(EpDouble *epd1, EpDouble *epd2); +extern void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdSubtract(EpDouble *epd1, double value); +extern void EpdSubtract2(EpDouble *epd1, EpDouble *epd2); +extern void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3); +extern void EpdPow2(int n, EpDouble *epd); +extern void EpdPow2Decimal(int n, EpDouble *epd); +extern void EpdNormalize(EpDouble *epd); +extern void EpdNormalizeDecimal(EpDouble *epd); +extern void EpdGetValueAndDecimalExponent(EpDouble *epd, double *value, int *exponent); +extern int EpdGetExponent(double value); +extern int EpdGetExponentDecimal(double value); +extern void EpdMakeInf(EpDouble *epd, int sign); +extern void EpdMakeZero(EpDouble *epd, int sign); +extern void EpdMakeNan(EpDouble *epd); +extern void EpdCopy(EpDouble *from, EpDouble *to); +extern int EpdIsInf(EpDouble *epd); +extern int EpdIsZero(EpDouble *epd); +extern int EpdIsNan(EpDouble *epd); +extern int EpdIsNanOrInf(EpDouble *epd); +extern int IsInfDouble(double value); +extern int IsNanDouble(double value); +extern int IsNanOrInfDouble(double value); + +/**AutomaticEnd***************************************************************/ ABC_NAMESPACE_HEADER_END diff --git a/src/bdd/mtr/mtr.h b/src/bdd/mtr/mtr.h index 189ac1be..5ac35313 100644 --- a/src/bdd/mtr/mtr.h +++ b/src/bdd/mtr/mtr.h @@ -20,12 +20,39 @@ Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: mtr.h,v 1.1.1.1 2003/02/24 22:24:02 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtr.h,v 1.14 2009/02/20 02:03:47 fabio Exp $] ******************************************************************************/ @@ -38,7 +65,6 @@ ABC_NAMESPACE_HEADER_START - /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -57,23 +83,6 @@ ABC_NAMESPACE_HEADER_START #define CONST #endif /* !(__STDC__ || __cplusplus) */ -/* These are potential duplicates. */ -#ifndef EXTERN -# ifdef __cplusplus -# ifdef ABC_NAMESPACE -# define EXTERN extern -# else -# define EXTERN extern "C" -# endif -# else -# define EXTERN extern -# endif -#endif - -#ifndef ARGS -#define ARGS(protos) protos -#endif - #if defined(__GNUC__) #define MTR_INLINE __inline__ # if (__GNUC__ >2 || __GNUC_MINOR__ >=7) @@ -85,22 +94,22 @@ ABC_NAMESPACE_HEADER_START #define MTR_INLINE #define MTR_UNUSED #endif - + /* Flag definitions */ -#define MTR_DEFAULT 0x00000000 -#define MTR_TERMINAL 0x00000001 -#define MTR_SOFT 0x00000002 -#define MTR_FIXED 0x00000004 -#define MTR_NEWNODE 0x00000008 +#define MTR_DEFAULT 0x00000000 +#define MTR_TERMINAL 0x00000001 +#define MTR_SOFT 0x00000002 +#define MTR_FIXED 0x00000004 +#define MTR_NEWNODE 0x00000008 /* MTR_MAXHIGH is defined in such a way that on 32-bit and 64-bit ** machines one can cast a value to (int) without generating a negative ** number. */ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 -#define MTR_MAXHIGH (((MtrHalfWord) ~0) >> 1) +#define MTR_MAXHIGH (((MtrHalfWord) ~0) >> 1) #else -#define MTR_MAXHIGH ((MtrHalfWord) ~0) +#define MTR_MAXHIGH ((MtrHalfWord) ~0) #endif @@ -141,8 +150,8 @@ typedef struct MtrNode { /*---------------------------------------------------------------------------*/ /* Flag manipulation macros */ -#define MTR_SET(node, flag) (node->flags |= (flag)) -#define MTR_RESET(node, flag) (node->flags &= ~ (flag)) +#define MTR_SET(node, flag) (node->flags |= (flag)) +#define MTR_RESET(node, flag) (node->flags &= ~ (flag)) #define MTR_TEST(node, flag) (node->flags & (flag)) @@ -152,24 +161,24 @@ typedef struct MtrNode { /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EXTERN MtrNode * Mtr_AllocNode ARGS(()); -EXTERN void Mtr_DeallocNode ARGS((MtrNode *node)); -EXTERN MtrNode * Mtr_InitTree ARGS(()); -EXTERN void Mtr_FreeTree ARGS((MtrNode *node)); -EXTERN MtrNode * Mtr_CopyTree ARGS((MtrNode *node, int expansion)); -EXTERN void Mtr_MakeFirstChild ARGS((MtrNode *parent, MtrNode *child)); -EXTERN void Mtr_MakeLastChild ARGS((MtrNode *parent, MtrNode *child)); -EXTERN MtrNode * Mtr_CreateFirstChild ARGS((MtrNode *parent)); -EXTERN MtrNode * Mtr_CreateLastChild ARGS((MtrNode *parent)); -EXTERN void Mtr_MakeNextSibling ARGS((MtrNode *first, MtrNode *second)); -EXTERN void Mtr_PrintTree ARGS((MtrNode *node)); -EXTERN MtrNode * Mtr_InitGroupTree ARGS((int lower, int size)); -EXTERN MtrNode * Mtr_MakeGroup ARGS((MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)); -EXTERN MtrNode * Mtr_DissolveGroup ARGS((MtrNode *group)); -EXTERN MtrNode * Mtr_FindGroup ARGS((MtrNode *root, unsigned int low, unsigned int high)); -EXTERN int Mtr_SwapGroups ARGS((MtrNode *first, MtrNode *second)); -EXTERN void Mtr_PrintGroups ARGS((MtrNode *root, int silent)); -EXTERN MtrNode * Mtr_ReadGroups ARGS((FILE *fp, int nleaves)); +extern MtrNode * Mtr_AllocNode (void); +extern void Mtr_DeallocNode (MtrNode *node); +extern MtrNode * Mtr_InitTree (void); +extern void Mtr_FreeTree (MtrNode *node); +extern MtrNode * Mtr_CopyTree (MtrNode *node, int expansion); +extern void Mtr_MakeFirstChild (MtrNode *parent, MtrNode *child); +extern void Mtr_MakeLastChild (MtrNode *parent, MtrNode *child); +extern MtrNode * Mtr_CreateFirstChild (MtrNode *parent); +extern MtrNode * Mtr_CreateLastChild (MtrNode *parent); +extern void Mtr_MakeNextSibling (MtrNode *first, MtrNode *second); +extern void Mtr_PrintTree (MtrNode *node); +extern MtrNode * Mtr_InitGroupTree (int lower, int size); +extern MtrNode * Mtr_MakeGroup (MtrNode *root, unsigned int low, unsigned int high, unsigned int flags); +extern MtrNode * Mtr_DissolveGroup (MtrNode *group); +extern MtrNode * Mtr_FindGroup (MtrNode *root, unsigned int low, unsigned int high); +extern int Mtr_SwapGroups (MtrNode *first, MtrNode *second); +extern void Mtr_PrintGroups (MtrNode *root, int silent); +extern MtrNode * Mtr_ReadGroups (FILE *fp, int nleaves); /**AutomaticEnd***************************************************************/ diff --git a/src/bdd/mtr/mtrBasic.c b/src/bdd/mtr/mtrBasic.c index 56c78a23..a2420d4a 100644 --- a/src/bdd/mtr/mtrBasic.c +++ b/src/bdd/mtr/mtrBasic.c @@ -7,29 +7,56 @@ Synopsis [Basic manipulation of multiway branching trees.] Description [External procedures included in this module: - <ul> - <li> Mtr_AllocNode() - <li> Mtr_DeallocNode() - <li> Mtr_InitTree() - <li> Mtr_FreeTree() - <li> Mtr_CopyTree() - <li> Mtr_MakeFirstChild() - <li> Mtr_MakeLastChild() - <li> Mtr_CreateFirstChild() - <li> Mtr_CreateLastChild() - <li> Mtr_MakeNextSibling() - <li> Mtr_PrintTree() - </ul> - ] + <ul> + <li> Mtr_AllocNode() + <li> Mtr_DeallocNode() + <li> Mtr_InitTree() + <li> Mtr_FreeTree() + <li> Mtr_CopyTree() + <li> Mtr_MakeFirstChild() + <li> Mtr_MakeLastChild() + <li> Mtr_CreateFirstChild() + <li> Mtr_CreateLastChild() + <li> Mtr_MakeNextSibling() + <li> Mtr_PrintTree() + </ul> + ] SeeAlso [cudd package] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -38,8 +65,6 @@ ABC_NAMESPACE_IMPL_START - - /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -57,7 +82,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.1.1.1 2003/02/24 22:24:02 wjiang Exp $"; +static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.13 2009/02/20 02:03:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -90,8 +115,7 @@ static char rcsid[] MTR_UNUSED = "$Id: mtrBasic.c,v 1.1.1.1 2003/02/24 22:24:02 ******************************************************************************/ MtrNode * -Mtr_AllocNode( - ) +Mtr_AllocNode(void) { MtrNode *node; @@ -134,8 +158,7 @@ Mtr_DeallocNode( ******************************************************************************/ MtrNode * -Mtr_InitTree( - ) +Mtr_InitTree(void) { MtrNode *node; @@ -201,18 +224,18 @@ Mtr_CopyTree( if (copy == NULL) return(NULL); copy->parent = copy->elder = copy->child = copy->younger = NULL; if (node->child != NULL) { - copy->child = Mtr_CopyTree(node->child, expansion); - if (copy->child == NULL) { - Mtr_DeallocNode(copy); - return(NULL); - } + copy->child = Mtr_CopyTree(node->child, expansion); + if (copy->child == NULL) { + Mtr_DeallocNode(copy); + return(NULL); + } } if (node->younger != NULL) { - copy->younger = Mtr_CopyTree(node->younger, expansion); - if (copy->younger == NULL) { - Mtr_FreeTree(copy); - return(NULL); - } + copy->younger = Mtr_CopyTree(node->younger, expansion); + if (copy->younger == NULL) { + Mtr_FreeTree(copy); + return(NULL); + } } copy->flags = node->flags; copy->low = node->low * expansion; @@ -220,14 +243,14 @@ Mtr_CopyTree( copy->index = node->index * expansion; if (copy->younger) copy->younger->elder = copy; if (copy->child) { - MtrNode *auxnode = copy->child; - while (auxnode != NULL) { - auxnode->parent = copy; - auxnode = auxnode->younger; - } + MtrNode *auxnode = copy->child; + while (auxnode != NULL) { + auxnode->parent = copy; + auxnode = auxnode->younger; + } } return(copy); - + } /* end of Mtr_CopyTree */ @@ -252,9 +275,9 @@ Mtr_MakeFirstChild( child->elder = NULL; if (parent->child != NULL) { #ifdef MTR_DEBUG - assert(parent->child->elder == NULL); + assert(parent->child->elder == NULL); #endif - parent->child->elder = child; + parent->child->elder = child; } parent->child = child; return; @@ -283,14 +306,14 @@ Mtr_MakeLastChild( child->younger = NULL; if (parent->child == NULL) { - parent->child = child; - child->elder = NULL; + parent->child = child; + child->elder = NULL; } else { - for (node = parent->child; - node->younger != NULL; - node = node->younger); - node->younger = child; - child->elder = node; + for (node = parent->child; + node->younger != NULL; + node = node->younger); + node->younger = child; + child->elder = node; } child->parent = parent; return; @@ -375,7 +398,7 @@ Mtr_MakeNextSibling( { second->younger = first->younger; if (first->younger != NULL) { - first->younger->elder = second; + first->younger->elder = second; } second->parent = first->parent; first->younger = second; @@ -403,12 +426,12 @@ Mtr_PrintTree( if (node == NULL) return; (void) fprintf(stdout, #if SIZEOF_VOID_P == 8 - "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%d S=%d\n", + "N=0x%-8lx C=0x%-8lx Y=0x%-8lx E=0x%-8lx P=0x%-8lx F=%x L=%u S=%u\n", (unsigned long) node, (unsigned long) node->child, (unsigned long) node->younger, (unsigned long) node->elder, (unsigned long) node->parent, node->flags, node->low, node->size); #else - "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%d S=%d\n", + "N=0x%-8x C=0x%-8x Y=0x%-8x E=0x%-8x P=0x%-8x F=%x L=%hu S=%hu\n", (unsigned) node, (unsigned) node->child, (unsigned) node->younger, (unsigned) node->elder, (unsigned) node->parent, node->flags, node->low, node->size); @@ -428,4 +451,3 @@ Mtr_PrintTree( /*---------------------------------------------------------------------------*/ ABC_NAMESPACE_IMPL_END - diff --git a/src/bdd/mtr/mtrGroup.c b/src/bdd/mtr/mtrGroup.c index 176643f4..280108c9 100644 --- a/src/bdd/mtr/mtrGroup.c +++ b/src/bdd/mtr/mtrGroup.c @@ -7,29 +7,56 @@ Synopsis [Functions to support group specification for reordering.] Description [External procedures included in this module: - <ul> - <li> Mtr_InitGroupTree() - <li> Mtr_MakeGroup() - <li> Mtr_DissolveGroup() - <li> Mtr_FindGroup() - <li> Mtr_SwapGroups() - <li> Mtr_PrintGroups() - <li> Mtr_ReadGroups() - </ul> - Static procedures included in this module: - <ul> - <li> mtrShiftHL - </ul> - ] + <ul> + <li> Mtr_InitGroupTree() + <li> Mtr_MakeGroup() + <li> Mtr_DissolveGroup() + <li> Mtr_FindGroup() + <li> Mtr_SwapGroups() + <li> Mtr_PrintGroups() + <li> Mtr_ReadGroups() + </ul> + Static procedures included in this module: + <ul> + <li> mtrShiftHL + </ul> + ] SeeAlso [cudd package] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] ******************************************************************************/ @@ -38,7 +65,6 @@ ABC_NAMESPACE_IMPL_START - /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -56,7 +82,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.1.1.1 2003/02/24 22:24:02 wjiang Exp $"; +static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.18 2009/02/20 02:03:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -69,7 +95,7 @@ static char rcsid[] MTR_UNUSED = "$Id: mtrGroup.c,v 1.1.1.1 2003/02/24 22:24:02 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int mtrShiftHL ARGS((MtrNode *node, int shift)); +static int mtrShiftHL (MtrNode *node, int shift); /**AutomaticEnd***************************************************************/ @@ -136,27 +162,27 @@ Mtr_MakeGroup( unsigned int flags /* flags for the new group */) { MtrNode *node, - *first, - *last, - *previous, - *newn; + *first, + *last, + *previous, + *newn; /* Sanity check. */ if (size == 0) - return(NULL); + return(NULL); /* Check whether current group includes new group. This check is ** necessary at the top-level call. In the subsequent calls it is ** redundant. */ if (low < (unsigned int) root->low || - low + size > (unsigned int) (root->low + root->size)) - return(NULL); + low + size > (unsigned int) (root->low + root->size)) + return(NULL); /* Trying to create an existing group has the effect of updating ** the flags. */ if (root->size == size && root->low == low) { - root->flags = flags; - return(root); + root->flags = flags; + return(root); } /* At this point we know that the new group is properly contained @@ -165,15 +191,15 @@ Mtr_MakeGroup( /* Root has no children: create a new group. */ if (root->child == NULL) { - newn = Mtr_AllocNode(); - if (newn == NULL) return(NULL); /* out of memory */ - newn->low = low; - newn->size = size; - newn->flags = flags; - newn->parent = root; - newn->elder = newn->younger = newn->child = NULL; - root->child = newn; - return(newn); + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = newn->younger = newn->child = NULL; + root->child = newn; + return(newn); } /* Root has children: Find all chidren of root that are included @@ -182,58 +208,58 @@ Mtr_MakeGroup( previous = NULL; first = root->child; /* guaranteed to be non-NULL */ while (first != NULL && low >= (unsigned int) (first->low + first->size)) { - previous = first; - first = first->younger; + previous = first; + first = first->younger; } if (first == NULL) { - /* We have scanned the entire list and we need to append a new - ** child at the end of it. Previous points to the last child - ** of root. */ - newn = Mtr_AllocNode(); - if (newn == NULL) return(NULL); /* out of memory */ - newn->low = low; - newn->size = size; - newn->flags = flags; - newn->parent = root; - newn->elder = previous; - previous->younger = newn; - newn->younger = newn->child = NULL; - return(newn); + /* We have scanned the entire list and we need to append a new + ** child at the end of it. Previous points to the last child + ** of root. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->parent = root; + newn->elder = previous; + previous->younger = newn; + newn->younger = newn->child = NULL; + return(newn); } /* Here first is non-NULL and low < first->low + first->size. */ if (low >= (unsigned int) first->low && - low + size <= (unsigned int) (first->low + first->size)) { - /* The new group is contained in the group of first. */ - newn = Mtr_MakeGroup(first, low, size, flags); - return(newn); + low + size <= (unsigned int) (first->low + first->size)) { + /* The new group is contained in the group of first. */ + newn = Mtr_MakeGroup(first, low, size, flags); + return(newn); } else if (low + size <= first->low) { - /* The new group is entirely contained in the gap between - ** previous and first. */ - newn = Mtr_AllocNode(); - if (newn == NULL) return(NULL); /* out of memory */ - newn->low = low; - newn->size = size; - newn->flags = flags; - newn->child = NULL; - newn->parent = root; - newn->elder = previous; - newn->younger = first; - first->elder = newn; - if (previous != NULL) { - previous->younger = newn; - } else { - root->child = newn; - } - return(newn); + /* The new group is entirely contained in the gap between + ** previous and first. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = NULL; + newn->parent = root; + newn->elder = previous; + newn->younger = first; + first->elder = newn; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + return(newn); } else if (low < (unsigned int) first->low && - low + size < (unsigned int) (first->low + first->size)) { - /* Trying to cut an existing group: not allowed. */ - return(NULL); + low + size < (unsigned int) (first->low + first->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); } else if (low > first->low) { - /* The new group neither is contained in the group of first - ** (this was tested above) nor contains it. It is therefore - ** trying to cut an existing group: not allowed. */ - return(NULL); + /* The new group neither is contained in the group of first + ** (this was tested above) nor contains it. It is therefore + ** trying to cut an existing group: not allowed. */ + return(NULL); } /* First holds the pointer to the first child contained in the new @@ -241,40 +267,40 @@ Mtr_MakeGroup( ** first->size. One of the two inequalities is strict. */ last = first->younger; while (last != NULL && - (unsigned int) (last->low + last->size) < low + size) { - last = last->younger; - } - if (last == NULL) { - /* All the chilren of root from first onward become children - ** of the new group. */ - newn = Mtr_AllocNode(); - if (newn == NULL) return(NULL); /* out of memory */ - newn->low = low; - newn->size = size; - newn->flags = flags; - newn->child = first; - newn->parent = root; - newn->elder = previous; - newn->younger = NULL; - first->elder = NULL; - if (previous != NULL) { - previous->younger = newn; - } else { - root->child = newn; - } - last = first; - while (last != NULL) { - last->parent = newn; + (unsigned int) (last->low + last->size) < low + size) { last = last->younger; } - return(newn); + if (last == NULL) { + /* All the chilren of root from first onward become children + ** of the new group. */ + newn = Mtr_AllocNode(); + if (newn == NULL) return(NULL); /* out of memory */ + newn->low = low; + newn->size = size; + newn->flags = flags; + newn->child = first; + newn->parent = root; + newn->elder = previous; + newn->younger = NULL; + first->elder = NULL; + if (previous != NULL) { + previous->younger = newn; + } else { + root->child = newn; + } + last = first; + while (last != NULL) { + last->parent = newn; + last = last->younger; + } + return(newn); } /* Here last != NULL and low + size <= last->low + last->size. */ if (low + size - 1 >= (unsigned int) last->low && - low + size < (unsigned int) (last->low + last->size)) { - /* Trying to cut an existing group: not allowed. */ - return(NULL); + low + size < (unsigned int) (last->low + last->size)) { + /* Trying to cut an existing group: not allowed. */ + return(NULL); } /* First and last point to the first and last of the children of @@ -284,26 +310,26 @@ Mtr_MakeGroup( ** preceeding first. If it is NULL, then first is the first child ** of root. */ newn = Mtr_AllocNode(); - if (newn == NULL) return(NULL); /* out of memory */ + if (newn == NULL) return(NULL); /* out of memory */ newn->low = low; newn->size = size; newn->flags = flags; newn->child = first; newn->parent = root; if (previous == NULL) { - root->child = newn; + root->child = newn; } else { - previous->younger = newn; + previous->younger = newn; } newn->elder = previous; newn->younger = last->younger; if (last->younger != NULL) { - last->younger->elder = newn; + last->younger->elder = newn; } last->younger = NULL; first->elder = NULL; for (node = first; node != NULL; node = node->younger) { - node->parent = newn; + node->parent = newn; } return(newn); @@ -342,20 +368,20 @@ Mtr_DissolveGroup( /* Make all children of group children of its parent, and make ** last point to the last child of group. */ for (last = group->child; last->younger != NULL; last = last->younger) { - last->parent = parent; + last->parent = parent; } last->parent = parent; last->younger = group->younger; if (group->younger != NULL) { - group->younger->elder = last; + group->younger->elder = last; } group->child->elder = group->elder; if (group == parent->child) { - parent->child = group->child; + parent->child = group->child; } else { - group->elder->younger = group->child; + group->elder->younger = group->child; } Mtr_DeallocNode(group); @@ -399,28 +425,28 @@ Mtr_FindGroup( ** check is necessary at the top-level call. In the subsequent ** calls it is redundant. */ if (low < (unsigned int) root->low || - low + size > (unsigned int) (root->low + root->size)) - return(NULL); + low + size > (unsigned int) (root->low + root->size)) + return(NULL); if (root->size == size && root->low == low) - return(root); + return(root); if (root->child == NULL) - return(NULL); + return(NULL); /* Find all chidren of root that are included in the new group. If ** the group of any child entirely contains the new group, call ** Mtr_MakeGroup recursively. */ node = root->child; while (low >= (unsigned int) (node->low + node->size)) { - node = node->younger; + node = node->younger; } if (low + size <= (unsigned int) (node->low + node->size)) { - /* The group is contained in the group of node. */ - node = Mtr_FindGroup(node, low, size); - return(node); + /* The group is contained in the group of node. */ + node = Mtr_FindGroup(node, low, size); + return(node); } else { - return(NULL); + return(NULL); } } /* end of Mtr_FindGroup */ @@ -451,11 +477,11 @@ Mtr_SwapGroups( int sizeSecond; if (second->younger == first) { /* make first first */ - node = first; - first = second; - second = node; + node = first; + first = second; + second = node; } else if (first->younger != second) { /* non-adjacent */ - return(0); + return(0); } sizeFirst = first->size; @@ -465,12 +491,12 @@ Mtr_SwapGroups( parent = first->parent; if (parent == NULL || second->parent != parent) return(0); if (parent->child == first) { - parent->child = second; + parent->child = second; } else { /* first->elder != NULL */ - first->elder->younger = second; + first->elder->younger = second; } if (second->younger != NULL) { - second->younger->elder = first; + second->younger->elder = first; } first->younger = second->younger; second->elder = first->elder; @@ -517,28 +543,36 @@ Mtr_PrintGroups( assert(root != NULL); assert(root->younger == NULL || root->younger->elder == root); assert(root->elder == NULL || root->elder->younger == root); - if (!silent) (void) printf("(%d",root->low); +#if SIZEOF_VOID_P == 8 + if (!silent) (void) printf("(%u",root->low); +#else + if (!silent) (void) printf("(%hu",root->low); +#endif if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { - if (!silent) (void) printf(","); + if (!silent) (void) printf(","); } else { - node = root->child; - while (node != NULL) { - assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); - assert(node->parent == root); - Mtr_PrintGroups(node,silent); - node = node->younger; - } + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + Mtr_PrintGroups(node,silent); + node = node->younger; + } } if (!silent) { - (void) printf("%d", root->low + root->size - 1); - if (root->flags != MTR_DEFAULT) { - (void) printf("|"); - if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); - if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); - if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); - } - (void) printf(")"); - if (root->parent == NULL) (void) printf("\n"); +#if SIZEOF_VOID_P == 8 + (void) printf("%u", root->low + root->size - 1); +#else + (void) printf("%hu", root->low + root->size - 1); +#endif + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); } assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); return; @@ -591,47 +625,53 @@ Mtr_ReadGroups( if (root == NULL) return NULL; while (! feof(fp)) { - /* Read a triple and check for consistency. */ - err = fscanf(fp, "%d %d %s", &low, &size, attrib); - if (err == EOF) { - break; - } else if (err != 3) { - return(NULL); - } else if (low < 0 || low+size > nleaves || size < 1) { - return(NULL); - } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) { - /* Not enough bits in the flags word to store these many - ** attributes. */ - return(NULL); - } + /* Read a triple and check for consistency. */ + err = fscanf(fp, "%d %d %s", &low, &size, attrib); + if (err == EOF) { + break; + } else if (err != 3) { + Mtr_FreeTree(root); + return(NULL); + } else if (low < 0 || low+size > nleaves || size < 1) { + Mtr_FreeTree(root); + return(NULL); + } else if (strlen(attrib) > 8 * sizeof(MtrHalfWord)) { + /* Not enough bits in the flags word to store these many + ** attributes. */ + Mtr_FreeTree(root); + return(NULL); + } - /* Parse the flag string. Currently all flags are permitted, - ** to make debugging easier. Normally, specifying NEWNODE - ** wouldn't be allowed. */ - flags = MTR_DEFAULT; - for (c=attrib; *c != 0; c++) { - switch (*c) { - case 'D': - break; - case 'F': - flags |= MTR_FIXED; - break; - case 'N': - flags |= MTR_NEWNODE; - break; - case 'S': - flags |= MTR_SOFT; - break; - case 'T': - flags |= MTR_TERMINAL; - break; - default: - return NULL; + /* Parse the flag string. Currently all flags are permitted, + ** to make debugging easier. Normally, specifying NEWNODE + ** wouldn't be allowed. */ + flags = MTR_DEFAULT; + for (c=attrib; *c != 0; c++) { + switch (*c) { + case 'D': + break; + case 'F': + flags |= MTR_FIXED; + break; + case 'N': + flags |= MTR_NEWNODE; + break; + case 'S': + flags |= MTR_SOFT; + break; + case 'T': + flags |= MTR_TERMINAL; + break; + default: + return NULL; + } + } + node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size, + flags); + if (node == NULL) { + Mtr_FreeTree(root); + return(NULL); } - } - node = Mtr_MakeGroup(root, (MtrHalfWord) low, (MtrHalfWord) size, - flags); - if (node == NULL) return(NULL); } return(root); @@ -680,11 +720,11 @@ mtrShiftHL( node->low = (MtrHalfWord) low; if (!MTR_TEST(node,MTR_TERMINAL) && node->child != NULL) { - auxnode = node->child; - do { - if (!mtrShiftHL(auxnode,shift)) return(0); - auxnode = auxnode->younger; - } while (auxnode != NULL); + auxnode = node->child; + do { + if (!mtrShiftHL(auxnode,shift)) return(0); + auxnode = auxnode->younger; + } while (auxnode != NULL); } return(1); @@ -692,4 +732,3 @@ mtrShiftHL( } /* end of mtrShiftHL */ ABC_NAMESPACE_IMPL_END - diff --git a/src/bdd/mtr/mtrInt.h b/src/bdd/mtr/mtrInt.h index 2a470411..9c8c6e26 100644 --- a/src/bdd/mtr/mtrInt.h +++ b/src/bdd/mtr/mtrInt.h @@ -12,28 +12,52 @@ Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: mtrInt.h,v 1.1.1.1 2003/02/24 22:24:02 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: mtrInt.h,v 1.2 2004/08/13 18:15:12 fabio Exp $] ******************************************************************************/ #ifndef _MTRINT #define _MTRINT - #include "mtr.h" -ABC_NAMESPACE_HEADER_START - - /*---------------------------------------------------------------------------*/ /* Nested includes */ /*---------------------------------------------------------------------------*/ +ABC_NAMESPACE_HEADER_START /*---------------------------------------------------------------------------*/ /* Constant declarations */ @@ -63,11 +87,8 @@ ABC_NAMESPACE_HEADER_START /* Function prototypes */ /*---------------------------------------------------------------------------*/ +ABC_NAMESPACE_HEADER_END /**AutomaticEnd***************************************************************/ - - -ABC_NAMESPACE_HEADER_END - #endif /* _MTRINT */ diff --git a/src/bdd/reo/reoCore.c b/src/bdd/reo/reoCore.c index d0535ff9..78a8b211 100644 --- a/src/bdd/reo/reoCore.c +++ b/src/bdd/reo/reoCore.c @@ -122,7 +122,7 @@ void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * Fu if ( p->fVerbose ) { - printf( "INITIAL: " ); + printf( "INITIAL:\n" ); if ( p->fMinWidth ) reoProfileWidthPrint(p); else if ( p->fMinApl ) @@ -141,7 +141,7 @@ void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * Fu // print statistics after each iteration if ( p->fVerbose ) { - printf( "ITER #%d: ", i+1 ); + printf( "ITER #%d:\n", i+1 ); if ( p->fMinWidth ) reoProfileWidthPrint(p); else if ( p->fMinApl ) diff --git a/src/bdd/reo/reoProfile.c b/src/bdd/reo/reoProfile.c index 68d4b3cc..037e3202 100644 --- a/src/bdd/reo/reoProfile.c +++ b/src/bdd/reo/reoProfile.c @@ -200,7 +200,7 @@ void reoProfileWidthStart( reo_man * p ) p->pPlanes[v].statsWidth = p->pPlanes[v-1].statsWidth + pWidthStart[v] - pWidthStop[v]; p->pPlanes[v].statsCost = p->pPlanes[v].statsWidth; p->nWidthCur += p->pPlanes[v].statsWidth; -// printf( "Level %2d: Width = %5d. Correct = %d.\n", v, Temp, p->pPlanes[v].statsWidth ); + printf( "Level %2d: Width = %5d.\n", v, p->pPlanes[v].statsWidth ); } p->nWidthBeg = p->nWidthCur; ABC_FREE( pWidthStart ); @@ -328,13 +328,13 @@ void reoProfileWidthPrint( reo_man * p ) TotalWidth = 0; for ( i = 0; i <= p->nSupp; i++ ) { -// printf( "Level = %2d. Width = %3d.\n", i, p->pProfile[i] ); + printf( "Level = %2d. Width = %3d.\n", i, p->pPlanes[i].statsWidth ); if ( WidthMax < p->pPlanes[i].statsWidth ) WidthMax = p->pPlanes[i].statsWidth; TotalWidth += p->pPlanes[i].statsWidth; } assert( p->nWidthCur == TotalWidth ); - printf( "WIDTH: " ); + printf( "WIDTH: " ); printf( "Maximum = %5d. ", WidthMax ); printf( "Total = %7d. ", p->nWidthCur ); printf( "Average = %6.2f.\n", TotalWidth / (float)p->nSupp ); diff --git a/src/bdd/reo/reoUnits.c b/src/bdd/reo/reoUnits.c index 70be8b82..7e57ff35 100644 --- a/src/bdd/reo/reoUnits.c +++ b/src/bdd/reo/reoUnits.c @@ -97,7 +97,8 @@ void reoUnitsRecycleUnitList( reo_man * p, reo_plane * pPlane ) pTail = pUnit; pTail->Next = p->pUnitFreeList; p->pUnitFreeList = pPlane->pHead; - memset( pPlane, 0, sizeof(reo_plane) ); +// memset( pPlane, 0, sizeof(reo_plane) ); + pPlane->pHead = NULL; } /**Function************************************************************* diff --git a/src/map/cov/cov.h b/src/map/cov/cov.h index f8136a7f..80ef1925 100644 --- a/src/map/cov/cov.h +++ b/src/map/cov/cov.h @@ -22,6 +22,7 @@ #define __COV_H__ #include "abc.h" +#include "extra.h" #include "covInt.h" diff --git a/src/map/cov/covBuild.c b/src/map/cov/covBuild.c index 3975c91d..6ca17583 100644 --- a/src/map/cov/covBuild.c +++ b/src/map/cov/covBuild.c @@ -82,7 +82,7 @@ Abc_Obj_t * Abc_NtkCovDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cub Vec_IntWriteEntry( vLits, i, Lit==1 ); Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); } - pNodeNew->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); + pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); if ( fCompl ) Abc_SopComplement( (char *)pNodeNew->pData ); Vec_IntFree( vLits ); @@ -153,7 +153,7 @@ Abc_Obj_t * Abc_NtkCovDeriveNode_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Ob pFaninNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCube, vSupp, 0 ); Abc_ObjAddFanin( pNodeNew, pFaninNew ); } - pNodeNew->pData = Abc_SopCreateXorSpecial( (Extra_MmFlex_t *)pNtkNew->pManFunc, nCubes ); + pNodeNew->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtkNew->pManFunc, nCubes ); } /* printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); @@ -280,8 +280,8 @@ Abc_Obj_t * Abc_NtkCovDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_ // Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); Abc_ObjAddFanin( pNodeNew, Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ) ); } -// pNodeNew->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); - pNodeNew->pData = Abc_SopCreateAnd( (Extra_MmFlex_t *)pNtkNew->pManFunc, vLits->nSize, NULL ); +// pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); + pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, vLits->nSize, NULL ); Vec_IntFree( vLits ); return pNodeNew; } @@ -335,7 +335,7 @@ Abc_Obj_t * Abc_NtkCovDeriveNodeInv_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc pFaninNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCube, vSupp ); Abc_ObjAddFanin( pNodeNew, pFaninNew ); } - pNodeNew->pData = Abc_SopCreateXorSpecial( (Extra_MmFlex_t *)pNtkNew->pManFunc, nCubes ); + pNodeNew->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtkNew->pManFunc, nCubes ); } pObj->pCopy = pNodeNew; @@ -472,7 +472,7 @@ Abc_Obj_t * Abc_NtkCovDerive_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t // derive the function vCover = Vec_StrAlloc( 100 ); Min_CoverCreate( vCover, pCover, (char)Type ); - pNodeNew->pData = Abc_SopRegister((Extra_MmFlex_t *)pNtkNew->pManFunc, Vec_StrArray(vCover) ); + pNodeNew->pData = Abc_SopRegister((Mem_Flex_t *)pNtkNew->pManFunc, Vec_StrArray(vCover) ); Vec_StrFree( vCover ); } diff --git a/src/map/cov/covInt.h b/src/map/cov/covInt.h index b2d293d4..73c6bc20 100644 --- a/src/map/cov/covInt.h +++ b/src/map/cov/covInt.h @@ -22,6 +22,7 @@ #define __COV_INT_H__ #include "abc.h" +#include "extra.h" ABC_NAMESPACE_HEADER_START diff --git a/src/map/mio/mioFunc.c b/src/map/mio/mioFunc.c index e58d3958..c14944c4 100644 --- a/src/map/mio/mioFunc.c +++ b/src/map/mio/mioFunc.c @@ -90,6 +90,7 @@ int Mio_LibraryParseFormulas( Mio_Library_t * pLib ) ***********************************************************************/ int Mio_GateParseFormula( Mio_Gate_t * pGate ) { + extern char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ); DdManager * dd = pGate->pLib->dd; char * pPinNames[100]; char * pPinNamesCopy[100]; @@ -114,13 +115,13 @@ int Mio_GateParseFormula( Mio_Gate_t * pGate ) if ( strcmp( pGate->pForm, MIO_STRING_CONST0 ) == 0 ) { pGate->bFunc = b0; - pGate->pSop = Abc_SopRegister( (Extra_MmFlex_t *)pGate->pLib->pMmFlex, " 0\n" ); + pGate->pSop = Abc_SopRegister( (Mem_Flex_t *)pGate->pLib->pMmFlex, " 0\n" ); pGate->pLib->pGate0 = pGate; } else if ( strcmp( pGate->pForm, MIO_STRING_CONST1 ) == 0 ) { pGate->bFunc = b1; - pGate->pSop = Abc_SopRegister( (Extra_MmFlex_t *)pGate->pLib->pMmFlex, " 1\n" ); + pGate->pSop = Abc_SopRegister( (Mem_Flex_t *)pGate->pLib->pMmFlex, " 1\n" ); pGate->pLib->pGate1 = pGate; } else diff --git a/src/map/mio/mioInt.h b/src/map/mio/mioInt.h index 35a583b6..87bd7d4e 100644 --- a/src/map/mio/mioInt.h +++ b/src/map/mio/mioInt.h @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////////////////// #include "abc.h" +#include "mem.h" #include "mvc.h" #include "main.h" #include "mio.h" @@ -69,7 +70,7 @@ struct Mio_LibraryStruct_t_ Mio_Gate_t * pGateAnd2; // the AND2 gate st_table * tName2Gate; // the mapping of gate names into their pointer DdManager * dd; // the nanager storing functions of gates - Extra_MmFlex_t * pMmFlex; // the memory manaqer for SOPs + Mem_Flex_t * pMmFlex; // the memory manaqer for SOPs Vec_Str_t * vCube; // temporary cube }; diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c index 42c6d8bf..eb5d47ea 100644 --- a/src/map/mio/mioRead.c +++ b/src/map/mio/mioRead.c @@ -101,7 +101,7 @@ Mio_Library_t * Mio_LibraryReadOne( Abc_Frame_t * pAbc, char * FileName, int fEx memset( pLib, 0, sizeof(Mio_Library_t) ); pLib->pName = Extra_UtilStrsav( FileName ); pLib->tName2Gate = st_init_table(strcmp, st_strhash); - pLib->pMmFlex = Extra_MmFlexStart(); + pLib->pMmFlex = Mem_FlexStart(); pLib->vCube = Vec_StrAlloc( 100 ); // read the file and clean comments diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index 0e8cbb03..d0d47060 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -56,7 +56,7 @@ void Mio_LibraryDelete( Mio_Library_t * pLib ) ABC_FREE( pLib->pName ); Mio_LibraryForEachGateSafe( pLib, pGate, pGate2 ) Mio_GateDelete( pGate ); - Extra_MmFlexStop( pLib->pMmFlex ); + Mem_FlexStop( pLib->pMmFlex, 0 ); Vec_StrFree( pLib->vCube ); if ( pLib->tName2Gate ) st_free_table( pLib->tName2Gate ); diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index 240fee03..693c25bd 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -198,6 +198,8 @@ extern void Extra_bddPermuteArray( DdManager * dd, DdNode ** bNodesIn, D 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 ); #ifndef ABC_PRB #define ABC_PRB(dd,f) printf("%s = ", #f); Extra_bddPrint(dd,f); printf("\n") @@ -611,7 +613,7 @@ extern char * Extra_UtilTildeExpand( char *fname ); extern char * Extra_UtilFileSearch( char *file, char *path, char *mode ); extern void (*Extra_UtilMMoutOfMemory)( long size ); -extern const char * globalUtilOptarg; +extern const char * globalUtilOptarg; extern int globalUtilOptind; /**AutomaticEnd***************************************************************/ diff --git a/src/misc/extra/extraBddMisc.c b/src/misc/extra/extraBddMisc.c index 69309a4d..7d63980a 100644 --- a/src/misc/extra/extraBddMisc.c +++ b/src/misc/extra/extraBddMisc.c @@ -55,6 +55,8 @@ static DdNode * extraTransferPermuteRecur( DdManager * ddS, DdManager * ddD, DdN 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); @@ -1039,6 +1041,75 @@ DdNode * Extra_bddChangePolarity( } /* 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 */ /*---------------------------------------------------------------------------*/ @@ -1277,6 +1348,11 @@ extraTransferPermuteRecur( if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) ) return ( Cudd_NotCond( res, comple ) ); + if ( ddS->TimeStop && ddS->TimeStop < clock() ) + return NULL; + if ( ddD->TimeStop && ddD->TimeStop < clock() ) + return NULL; + /* Recursive step. */ if ( Permute ) index = Permute[f->index]; @@ -1800,6 +1876,158 @@ DdNode * extraBddChangePolarity( } /* 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 && ddF->TimeStop < clock() ) + return NULL; + if ( ddG->TimeStop && ddG->TimeStop < clock() ) + 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_MIN( 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; + int 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 = clock(); + bRes1 = Cudd_bddAnd( ddF, bF, bG ); Cudd_Ref( bRes1 ); +Abc_PrintTime( 1, "Runtime of Cudd_bddAnd ", clock() - clk ); + + // compute the result +Counter = 0; +clk = clock(); + bRes2 = Extra_bddAndPermute( ddF, bF, ddG, bG2, NULL ); Cudd_Ref( bRes2 ); +Abc_PrintTime( 1, "Runtime of new procedure", 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 ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/misc/hash/hashGen.h b/src/misc/hash/hashGen.h index 257b9dba..e26a3c84 100644 --- a/src/misc/hash/hashGen.h +++ b/src/misc/hash/hashGen.h @@ -50,14 +50,17 @@ struct Hash_Gen_Entry_t_ struct Hash_Gen_Entry_t_ * pNext; }; +typedef int (*Hash_GenHashFunction_t)(void* key, int nBins); +typedef int (*Hash_GenCompFunction_t)(void* key, void* data); + struct Hash_Gen_t_ { int nSize; int nBins; - int (* fHash)(void *key, int nBins); - int (* fComp)(void *key, void *data); + Hash_GenHashFunction_t fHash; + Hash_GenCompFunction_t fComp; int fFreeKey; - Hash_Gen_Entry_t ** pArray; + Hash_Gen_Entry_t ** pArray; }; @@ -229,7 +232,7 @@ static inline void Hash_GenWriteEntry( Hash_Gen_t *p, void * key, void * data ) p->nSize++; (*pLast) = pEntry = ABC_ALLOC( Hash_Gen_Entry_t, 1 ); pEntry->pNext = NULL; - pEntry->key = key; + pEntry->key = (char *)key; pEntry->data = data; return; @@ -271,7 +274,7 @@ static inline Hash_Gen_Entry_t * Hash_GenEntry( Hash_Gen_t *p, void * key, int f p->nSize++; (*pLast) = pEntry = ABC_ALLOC( Hash_Gen_Entry_t, 1 ); pEntry->pNext = NULL; - pEntry->key = key; + pEntry->key = (char *)key; pEntry->data = NULL; return pEntry; } diff --git a/src/misc/st/st.c b/src/misc/st/st.c index 9705b987..cadddb0b 100644 --- a/src/misc/st/st.c +++ b/src/misc/st/st.c @@ -79,7 +79,7 @@ st_init_table(st_compare_func_type compare, st_hash_func_type hash) void st_free_table(st_table *table) { - register st_table_entry *ptr, *next; + st_table_entry *ptr, *next; int i; for(i = 0; i < table->num_bins ; i++) { @@ -110,10 +110,10 @@ st_free_table(st_table *table) } int -st_lookup(st_table *table, register const char *key, char **value) +st_lookup(st_table *table, const char *key, char **value) { int hash_val; - register st_table_entry *ptr, **last; + st_table_entry *ptr, **last; hash_val = do_hash(key, table); @@ -130,10 +130,10 @@ st_lookup(st_table *table, register const char *key, char **value) } int -st_lookup_int(st_table *table, register char *key, int *value) +st_lookup_int(st_table *table, char *key, int *value) { int hash_val; - register st_table_entry *ptr, **last; + st_table_entry *ptr, **last; hash_val = do_hash(key, table); @@ -167,11 +167,11 @@ st_lookup_int(st_table *table, register char *key, int *value) } int -st_insert(register st_table *table, register const char *key, char *value) +st_insert(st_table *table, const char *key, char *value) { int hash_val; st_table_entry *newEntry; - register st_table_entry *ptr, **last; + st_table_entry *ptr, **last; hash_val = do_hash(key, table); @@ -188,7 +188,7 @@ st_insert(register st_table *table, register const char *key, char *value) if (newEntry == NULL) { return ST_OUT_OF_MEM; } - newEntry->key = key; + newEntry->key = (char *)key; newEntry->record = value; newEntry->next = table->bins[hash_val]; table->bins[hash_val] = newEntry; @@ -280,9 +280,9 @@ st_find(st_table *table, char *key, char ***slot) } static int -rehash(register st_table *table) +rehash(st_table *table) { - register st_table_entry *ptr, *next, **old_bins; + st_table_entry *ptr, *next, **old_bins; int i, old_num_bins, hash_val, old_num_entries; /* save old values */ @@ -371,11 +371,11 @@ st_copy(st_table *old_table) } int -st_delete(register st_table *table, register const char **keyp, char **value) +st_delete(st_table *table, const char **keyp, char **value) { int hash_val; const char *key = *keyp; - register st_table_entry *ptr, **last; + st_table_entry *ptr, **last; hash_val = do_hash(key, table); @@ -394,11 +394,11 @@ st_delete(register st_table *table, register const char **keyp, char **value) } int -st_delete_int(register st_table *table, register long *keyp, char **value) +st_delete_int(st_table *table, long *keyp, char **value) { int hash_val; char *key = (char *) *keyp; - register st_table_entry *ptr, **last; + st_table_entry *ptr, **last; hash_val = do_hash(key, table); @@ -417,7 +417,7 @@ st_delete_int(register st_table *table, register long *keyp, char **value) } int -st_foreach(st_table *table, enum st_retval (*func)(const char *, char *, char *), char *arg) +st_foreach(st_table *table, enum st_retval (*func)(char *, char *, char *), char *arg) { st_table_entry *ptr, **last; enum st_retval retval; @@ -447,8 +447,8 @@ st_foreach(st_table *table, enum st_retval (*func)(const char *, char *, char *) int st_strhash(const char *string, int modulus) { - register int val = 0; - register int c; + int val = 0; + int c; while ((c = *string++) != '\0') { val = val*997 + c; @@ -500,7 +500,7 @@ st_init_gen(st_table *table) int st_gen(st_generator *gen, const char **key_p, char **value_p) { - register int i; + int i; if (gen->entry == NULL) { /* try to find next entry */ @@ -527,7 +527,7 @@ st_gen(st_generator *gen, const char **key_p, char **value_p) int st_gen_int(st_generator *gen, const char **key_p, long *value_p) { - register int i; + int i; if (gen->entry == NULL) { /* try to find next entry */ diff --git a/src/misc/st/st.h b/src/misc/st/st.h index 81bd461e..d16fc4b6 100644 --- a/src/misc/st/st.h +++ b/src/misc/st/st.h @@ -14,17 +14,35 @@ #ifndef ST_INCLUDED #define ST_INCLUDED - #include "abc_global.h" ABC_NAMESPACE_HEADER_START + +/* These are potential duplicates. */ +#ifndef EXTERN +# ifdef __cplusplus +# ifdef ABC_NAMESPACE +# define EXTERN extern +# else +# define EXTERN extern "C" +# endif +# else +# define EXTERN extern +# endif +#endif + +#ifndef ARGS +#define ARGS(protos) protos +#endif + + typedef int (*st_compare_func_type)(const char*, const char*); typedef int (*st_hash_func_type)(const char*, int); typedef struct st_table_entry st_table_entry; struct st_table_entry { - const char *key; + char *key; char *record; st_table_entry *next; }; @@ -53,7 +71,7 @@ struct st_generator { enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; -typedef enum st_retval (*ST_PFSR)(const char *, char *, char *); +typedef enum st_retval (*ST_PFSR)(char *, char *, char *); typedef int (*ST_PFI)(); extern st_table *st_init_table_with_params (st_compare_func_type compare, st_hash_func_type hash, int size, int density, double grow_factor, int reorder_flag); diff --git a/src/misc/st/stmm.c b/src/misc/st/stmm.c index 9aed8b11..1305d5b0 100644 --- a/src/misc/st/stmm.c +++ b/src/misc/st/stmm.c @@ -79,7 +79,7 @@ void stmm_free_table (stmm_table *table) { /* - register stmm_table_entry *ptr, *next; + stmm_table_entry *ptr, *next; int i; for ( i = 0; i < table->num_bins; i++ ) { @@ -95,7 +95,7 @@ stmm_free_table (stmm_table *table) // no need to deallocate entries because they are in the memory manager now // added by alanmi if ( table->pMemMan ) - Extra_MmFixedStop (table->pMemMan); + Extra_MmFixedStop ((Extra_MmFixed_t *)table->pMemMan); ABC_FREE(table->bins); ABC_FREE(table); } @@ -111,7 +111,7 @@ stmm_clean (stmm_table *table) // reset the parameters table->num_entries = 0; // restart the memory manager - Extra_MmFixedRestart (table->pMemMan); + Extra_MmFixedRestart ((Extra_MmFixed_t *)table->pMemMan); } @@ -131,10 +131,10 @@ stmm_clean (stmm_table *table) } int -stmm_lookup (stmm_table *table, register char *key, char **value) +stmm_lookup (stmm_table *table, char *key, char **value) { int hash_val; - register stmm_table_entry *ptr, **last; + stmm_table_entry *ptr, **last; hash_val = do_hash (key, table); @@ -153,10 +153,10 @@ stmm_lookup (stmm_table *table, register char *key, char **value) } int -stmm_lookup_int (stmm_table *table, register char *key, int *value) +stmm_lookup_int (stmm_table *table, char *key, int *value) { int hash_val; - register stmm_table_entry *ptr, **last; + stmm_table_entry *ptr, **last; hash_val = do_hash (key, table); @@ -187,7 +187,7 @@ stmm_lookup_int (stmm_table *table, register char *key, int *value) hash_val = do_hash(key,table);\ }\ \ - new = (stmm_table_entry *)Extra_MmFixedEntryFetch( table->pMemMan );\ + new = (stmm_table_entry *)Extra_MmFixedEntryFetch( (Extra_MmFixed_t *)table->pMemMan );\ \ new->key = key;\ new->record = value;\ @@ -197,11 +197,11 @@ stmm_lookup_int (stmm_table *table, register char *key, int *value) } int -stmm_insert (register stmm_table *table, register char *key, char *value) +stmm_insert (stmm_table *table, char *key, char *value) { int hash_val; stmm_table_entry *newEntry; - register stmm_table_entry *ptr, **last; + stmm_table_entry *ptr, **last; hash_val = do_hash (key, table); @@ -216,7 +216,7 @@ stmm_insert (register stmm_table *table, register char *key, char *value) } // newEntry = ABC_ALLOC( stmm_table_entry, 1 ); - newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); + newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch ((Extra_MmFixed_t *)table->pMemMan); if (newEntry == NULL) { return STMM_OUT_OF_MEM; } @@ -249,7 +249,7 @@ stmm_add_direct (stmm_table *table, char *key, char *value) hash_val = do_hash (key, table); // newEntry = ABC_ALLOC( stmm_table_entry, 1 ); - newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); + newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch ((Extra_MmFixed_t *)table->pMemMan); if (newEntry == NULL) { return STMM_OUT_OF_MEM; } @@ -281,7 +281,7 @@ stmm_find_or_add (stmm_table *table, char *key, char ***slot) } // newEntry = ABC_ALLOC( stmm_table_entry, 1 ); - newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); + newEntry = (stmm_table_entry *) Extra_MmFixedEntryFetch ((Extra_MmFixed_t *)table->pMemMan); if (newEntry == NULL) { return STMM_OUT_OF_MEM; } @@ -325,9 +325,9 @@ stmm_find (stmm_table *table, char *key, char ***slot) } static int -rehash (register stmm_table *table) +rehash (stmm_table *table) { - register stmm_table_entry *ptr, *next, **old_bins; + stmm_table_entry *ptr, *next, **old_bins; int i, old_num_bins, hash_val, old_num_entries; /* save old values */ @@ -390,18 +390,14 @@ stmm_copy (stmm_table *old_table) } // allocate the memory manager for the newEntry table - newEntry_table->pMemMan = - Extra_MmFixedStart (sizeof (stmm_table_entry)); + newEntry_table->pMemMan = Extra_MmFixedStart (sizeof (stmm_table_entry)); for (i = 0; i < num_bins; i++) { newEntry_table->bins[i] = NULL; ptr = old_table->bins[i]; while (ptr != NULL) { // newEntry = ABC_ALLOC( stmm_table_entry, 1 ); - newEntry = - (stmm_table_entry *) Extra_MmFixedEntryFetch (newEntry_table-> - pMemMan); - + newEntry = (stmm_table_entry *)Extra_MmFixedEntryFetch ((Extra_MmFixed_t *)newEntry_table->pMemMan); if (newEntry == NULL) { /* for ( j = 0; j <= i; j++ ) @@ -415,7 +411,7 @@ stmm_copy (stmm_table *old_table) } } */ - Extra_MmFixedStop (newEntry_table->pMemMan); + Extra_MmFixedStop ((Extra_MmFixed_t *)newEntry_table->pMemMan); ABC_FREE(newEntry_table->bins); ABC_FREE(newEntry_table); @@ -431,11 +427,11 @@ stmm_copy (stmm_table *old_table) } int -stmm_delete (register stmm_table *table, register char **keyp, char **value) +stmm_delete (stmm_table *table, char **keyp, char **value) { int hash_val; char *key = *keyp; - register stmm_table_entry *ptr, **last; + stmm_table_entry *ptr, **last; hash_val = do_hash (key, table); @@ -450,18 +446,18 @@ stmm_delete (register stmm_table *table, register char **keyp, char **value) *value = ptr->record; *keyp = ptr->key; // ABC_FREE( ptr ); - Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); + Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr); table->num_entries--; return 1; } int -stmm_delete_int (register stmm_table *table, register long *keyp, char **value) +stmm_delete_int (stmm_table *table, long *keyp, char **value) { int hash_val; char *key = (char *) *keyp; - register stmm_table_entry *ptr, **last; + stmm_table_entry *ptr, **last; hash_val = do_hash (key, table); @@ -476,7 +472,7 @@ stmm_delete_int (register stmm_table *table, register long *keyp, char **value) *value = ptr->record; *keyp = (long) ptr->key; // ABC_FREE( ptr ); - Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); + Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr); table->num_entries--; return 1; @@ -505,7 +501,7 @@ stmm_foreach (stmm_table *table, enum stmm_retval (*func) (char *, char *, char *last = ptr->next; table->num_entries--; /* cstevens@ic */ // ABC_FREE( ptr ); - Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); + Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr); ptr = *last; } @@ -515,10 +511,10 @@ stmm_foreach (stmm_table *table, enum stmm_retval (*func) (char *, char *, char } int -stmm_strhash (register const char *string, int modulus) +stmm_strhash (const char *string, int modulus) { - register int val = 0; - register int c; + int val = 0; + int c; while ((c = *string++) != '\0') { val = val * 997 + c; @@ -570,7 +566,7 @@ stmm_init_gen (stmm_table *table) int stmm_gen (stmm_generator *gen, char **key_p, char **value_p) { - register int i; + int i; if (gen->entry == NULL) { /* try to find next entry */ @@ -597,7 +593,7 @@ stmm_gen (stmm_generator *gen, char **key_p, char **value_p) int stmm_gen_int (stmm_generator *gen, char **key_p, long *value_p) { - register int i; + int i; if (gen->entry == NULL) { /* try to find next entry */ diff --git a/src/misc/st/stmm.h b/src/misc/st/stmm.h index c23c6942..eee90073 100644 --- a/src/misc/st/stmm.h +++ b/src/misc/st/stmm.h @@ -14,12 +14,27 @@ #ifndef STMM_INCLUDED #define STMM_INCLUDED +#include "abc_global.h" -#include "extra.h" +ABC_NAMESPACE_HEADER_START +/* These are potential duplicates. */ +#ifndef EXTERN +# ifdef __cplusplus +# ifdef ABC_NAMESPACE +# define EXTERN extern +# else +# define EXTERN extern "C" +# endif +# else +# define EXTERN extern +# endif +#endif -ABC_NAMESPACE_HEADER_START +#ifndef ARGS +#define ARGS(protos) protos +#endif typedef int (*stmm_compare_func_type)(const char*, const char*); typedef int (*stmm_hash_func_type)(const char*, int); @@ -47,7 +62,7 @@ struct stmm_table stmm_table_entry **bins; // memory manager to improve runtime and prevent memory fragmentation // added by alanmi - January 16, 2003 - Extra_MmFixed_t *pMemMan; + void * pMemMan; }; struct stmm_generator diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h index aca9a509..1321f028 100644 --- a/src/misc/util/abc_global.h +++ b/src/misc/util/abc_global.h @@ -288,18 +288,6 @@ static inline void Abc_PrintMemoryP( int level, const char * pStr, int time, int } -// sequential counter-example -typedef struct Abc_Cex_t_ Abc_Cex_t; -struct Abc_Cex_t_ -{ - int iPo; // the zero-based number of PO, for which verification failed - int iFrame; // the zero-based number of the time-frame, for which verificaiton failed - int nRegs; // the number of registers in the miter - int nPis; // the number of primary inputs in the miter - int nBits; // the number of words of bit data used - unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) -}; - ABC_NAMESPACE_HEADER_END #endif diff --git a/src/misc/util/module.make b/src/misc/util/module.make index c70d582a..776a1705 100644 --- a/src/misc/util/module.make +++ b/src/misc/util/module.make @@ -1 +1,3 @@ -SRC += src/misc/util/utilFile.c src/misc/util/utilSignal.c +SRC += src/misc/util/utilCex.c \ + src/misc/util/utilFile.c \ + src/misc/util/utilSignal.c diff --git a/src/misc/util/utilCex.c b/src/misc/util/utilCex.c new file mode 100644 index 00000000..a4cf5e33 --- /dev/null +++ b/src/misc/util/utilCex.c @@ -0,0 +1,205 @@ +/**CFile**************************************************************** + + FileName [utilCex.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Handling counter-examples.] + + Synopsis [Handling counter-examples.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - Feburary 13, 2011.] + + Revision [$Id: utilCex.c,v 1.00 2011/02/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#include "abc_global.h" +#include "utilCex.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Abc_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } +static inline int Abc_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Abc_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Allocates a counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Abc_CexAlloc( int nRegs, int nRealPis, int nFrames ) +{ + Abc_Cex_t * pCex; + int nWords = Abc_BitWordNum( nRegs + nRealPis * nFrames ); + pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + pCex->nRegs = nRegs; + pCex->nPis = nRealPis; + pCex->nBits = nRegs + nRealPis * nFrames; + return pCex; +} + +/**Function************************************************************* + + Synopsis [Make the trivial counter-example for the trivially asserted output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Abc_CexMakeTriv( int nRegs, int nTruePis, int nTruePos, int iFrameOut ) +{ + Abc_Cex_t * pCex; + int iPo, iFrame; + assert( nRegs > 0 ); + iPo = iFrameOut % nTruePos; + iFrame = iFrameOut / nTruePos; + // allocate the counter example + pCex = Abc_CexAlloc( nRegs, nTruePis, iFrame + 1 ); + pCex->iPo = iPo; + pCex->iFrame = iFrame; + return pCex; +} + +/**Function************************************************************* + + Synopsis [Derives the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Abc_CexCreate( int nRegs, int nPis, int * pArray, int iFrame, int iPo, int fSkipRegs ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Abc_CexAlloc( nRegs, nPis, iFrame+1 ); + pCex->iPo = iPo; + pCex->iFrame = iFrame; + if ( pArray == NULL ) + return pCex; + if ( fSkipRegs ) + { + for ( i = nRegs; i < pCex->nBits; i++ ) + if ( pArray[i-nRegs] ) + Abc_InfoSetBit( pCex->pData, i ); + } + else + { + for ( i = 0; i < pCex->nBits; i++ ) + if ( pArray[i] ) + Abc_InfoSetBit( pCex->pData, i ); + } + return pCex; +} + +/**Function************************************************************* + + Synopsis [Make the trivial counter-example for the trivially asserted output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Abc_CexDup( Abc_Cex_t * p, int nRegsNew ) +{ + Abc_Cex_t * pCex; + int i; + if ( nRegsNew == -1 ) + nRegsNew = p->nRegs; + pCex = Abc_CexAlloc( nRegsNew, p->nPis, p->iFrame+1 ); + pCex->iPo = p->iPo; + pCex->iFrame = p->iFrame; + for ( i = p->nRegs; i < p->nBits; i++ ) + if ( Abc_InfoHasBit(p->pData, i) ) + Abc_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); + return pCex; +} + +/**Function************************************************************* + + Synopsis [Prints out the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_CexPrint( Abc_Cex_t * p ) +{ + int i, f, k; + printf( "Counter-example: iPo = %d iFrame = %d nRegs = %d nPis = %d nBits = %d\n", + p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits ); + printf( "State : " ); + for ( k = 0; k < p->nRegs; k++ ) + printf( "%d", Abc_InfoHasBit(p->pData, k) ); + printf( "\n" ); + for ( f = 0; f <= p->iFrame; f++ ) + { + printf( "Frame %2d : ", f ); + for ( i = 0; i < p->nPis; i++ ) + printf( "%d", Abc_InfoHasBit(p->pData, k++) ); + printf( "\n" ); + } + assert( k == p->nBits ); +} + +/**Function************************************************************* + + Synopsis [Frees the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_CexFree( Abc_Cex_t * p ) +{ + ABC_FREE( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/util/utilCex.h b/src/misc/util/utilCex.h new file mode 100644 index 00000000..f0ee57b1 --- /dev/null +++ b/src/misc/util/utilCex.h @@ -0,0 +1,72 @@ +/**CFile**************************************************************** + + FileName [utilCex.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Handling sequential counter-examples.] + + Synopsis [Handling sequential counter-examples.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - Feburary 13, 2011.] + + Revision [$Id: utilCex.h,v 1.00 2011/02/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __UTIL_CEX_H__ +#define __UTIL_CEX_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// sequential counter-example +typedef struct Abc_Cex_t_ Abc_Cex_t; +struct Abc_Cex_t_ +{ + int iPo; // the zero-based number of PO, for which verification failed + int iFrame; // the zero-based number of the time-frame, for which verificaiton failed + int nRegs; // the number of registers in the miter + int nPis; // the number of primary inputs in the miter + int nBits; // the number of words of bit data used + unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== utilCex.c ===========================================================*/ +extern Abc_Cex_t * Abc_CexAlloc( int nRegs, int nTruePis, int nFrames ); +extern Abc_Cex_t * Abc_CexMakeTriv( int nRegs, int nTruePis, int nTruePos, int iFrameOut ); +extern Abc_Cex_t * Abc_CexCreate( int nRegs, int nTruePis, int * pArray, int iFrame, int iPo, int fSkipRegs ); +extern Abc_Cex_t * Abc_CexDup( Abc_Cex_t * p, int nRegsNew ); +extern void Abc_CexPrint( Abc_Cex_t * p ); +extern void Abc_CexFree( Abc_Cex_t * p ); + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/utilFile.c b/src/misc/util/utilFile.c index 2c40c32c..69d84c29 100644 --- a/src/misc/util/utilFile.c +++ b/src/misc/util/utilFile.c @@ -25,6 +25,14 @@ #include <fcntl.h> #include <sys/stat.h> +#if defined(_MSC_VER) +#include <Windows.h> +#include <process.h> +#include <io.h> +#else +#include <unistd.h> +#endif + #include "abc_global.h" ABC_NAMESPACE_IMPL_START @@ -33,12 +41,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#if defined(_MSC_VER) - -#include <Windows.h> -#include <process.h> -#include <io.h> - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -56,6 +58,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static ABC_UINT64_T realTimeAbs() // -- absolute time in nano-seconds { +#if defined(_MSC_VER) LARGE_INTEGER f, t; double realTime_freq; int ok; @@ -65,20 +68,16 @@ static ABC_UINT64_T realTimeAbs() // -- absolute time in nano-seconds ok = QueryPerformanceCounter(&t); assert(ok); return (ABC_UINT64_T)(__int64)(((__int64)(((ABC_UINT64_T)t.LowPart | ((ABC_UINT64_T)t.HighPart << 32))) * realTime_freq * 1000000000)); -} - #endif - - - -// Opens a temporary file with given prefix and returns file descriptor (-1 on failure) -// and a string containing the name of the file (to be freed by caller). +} /**Function************************************************************* - Synopsis [] + Synopsis [Opens a temporary file.] - Description [] + Description [Opens a temporary file with given prefix and returns file + descriptor (-1 on failure) and a string containing the name of the file + (to be freed by caller).] SideEffects [] @@ -87,9 +86,22 @@ static ABC_UINT64_T realTimeAbs() // -- absolute time in nano-seconds ***********************************************************************/ int tmpFile(const char* prefix, const char* suffix, char** out_name) { -#if !defined(_MSC_VER) +#if defined(_MSC_VER) + int i, fd; + *out_name = (char*)malloc(strlen(prefix) + strlen(suffix) + 27); + for (i = 0; i < 10; i++){ + sprintf(*out_name, "%s%I64X%d%s", prefix, realTimeAbs(), _getpid(), suffix); + fd = _open(*out_name, O_CREAT | O_EXCL | O_BINARY | O_RDWR, _S_IREAD | _S_IWRITE); + if (fd == -1){ + free(*out_name); + *out_name = NULL; + } + return fd; + } + assert(0); // -- could not open temporary file + return 0; +#else int fd; - *out_name = (char*)malloc(strlen(prefix) + strlen(suffix) + 7); assert(*out_name != NULL); sprintf(*out_name, "%sXXXXXX", prefix); @@ -98,7 +110,6 @@ int tmpFile(const char* prefix, const char* suffix, char** out_name) free(*out_name); *out_name = NULL; }else{ - // Kludge: close(fd); unlink(*out_name); @@ -108,35 +119,11 @@ int tmpFile(const char* prefix, const char* suffix, char** out_name) free(*out_name); *out_name = NULL; } - -// assert( 0 ); - // commented out because had problem with g++ saying that - // close() and unlink() are not defined in the namespace - } return fd; - -#else - int i, fd; - *out_name = (char*)malloc(strlen(prefix) + strlen(suffix) + 27); - for (i = 0; i < 10; i++){ - sprintf(*out_name, "%s%I64X%d%s", prefix, realTimeAbs(), _getpid(), suffix); - fd = _open(*out_name, O_CREAT | O_EXCL | O_BINARY | O_RDWR, _S_IREAD | _S_IWRITE); - if (fd == -1){ - free(*out_name); - *out_name = NULL; - } - return fd; - } - assert(0); // -- could not open temporary file - return 0; #endif } - -//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm - - /**Function************************************************************* Synopsis [] @@ -165,8 +152,6 @@ int main(int argc, char** argv) } */ - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/utilSignal.c b/src/misc/util/utilSignal.c index 6a793ce0..2886f69b 100644 --- a/src/misc/util/utilSignal.c +++ b/src/misc/util/utilSignal.c @@ -8,28 +8,26 @@ Synopsis [] - Author [] + Author [Baruch Sterin] Affiliation [UC Berkeley] - Date [] + Date [Ver. 1.0. Started - February 1, 2011.] - Revision [] + Revision [$Id: utilSignal.c,v 1.00 2011/02/01 00:00:00 alanmi Exp $] ***********************************************************************/ -#include <main.h> +#include <stdio.h> #include <stdlib.h> -#include <signal.h> #include "abc_global.h" -#include "hashGen.h" - -#ifndef _MSC_VER +#include "utilSignal.h" +#ifdef _MSC_VER +#define unlink _unlink +#else #include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> +#endif ABC_NAMESPACE_IMPL_START @@ -37,485 +35,36 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Hash_Gen_t* watched_pid_hash = NULL; -static Hash_Gen_t* watched_tmp_files_hash = NULL; - -static sigset_t* old_procmask; - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [Kills all watched child processes and remove all watched termporary files.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalCleanup() -{ - int i; - Hash_Gen_Entry_t* pEntry; - - // kill all watched child processes - Hash_GenForEachEntry(watched_pid_hash, pEntry, i) - { - pid_t pid = (pid_t)pEntry->key; - pid_t ppid = (pid_t)pEntry->data; - - if (getpid() == ppid) - { - kill(pid, SIGINT); - } - } - - // remove watched temporary files - Hash_GenForEachEntry(watched_tmp_files_hash, pEntry, i) - { - int fname = (const char*)pEntry->key; - pid_t ppid = (pid_t)pEntry->data; - - if( getpid() == ppid ) - { - remove(fname); - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Sets up data structures needed for cleanup in signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalStartHandler() -{ - watched_pid_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncInt, Hash_DefaultCmpFuncInt, 0); - watched_tmp_files_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncStr, strcmp, 1); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Frees data structures used for clean up in signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalResetHandler() -{ - int i; - Hash_Gen_Entry_t* pEntry; - - sigset_t procmask, old_procmask; - - sigemptyset(&procmask); - sigaddset(&procmask, SIGINT); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); - - Hash_GenFree(watched_pid_hash); - watched_pid_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncInt, Hash_DefaultCmpFuncInt, 0); - - Hash_GenFree(watched_tmp_files_hash); - watched_tmp_files_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncStr, strcmp, 1); - - sigprocmask(SIG_SETMASK, &old_procmask, NULL); -} - -void Util_SignalStopHandler() -{ - int i; - Hash_Gen_Entry_t* pEntry; - - Hash_GenFree(watched_pid_hash); - watched_pid_hash = NULL; - - Hash_GenFree(watched_tmp_files_hash); - watched_tmp_files_hash = NULL; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [Blocks SIGINT. For use when updating watched processes and temporary files to prevent race conditions with the signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -static int nblocks = 0; - -void Util_SignalBlockSignals() -{ - sigset_t procmask; - - assert(nblocks==0); - nblocks ++ ; - - sigemptyset(&procmask); - sigaddset(&procmask, SIGINT); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Unblocks SIGINT after a call to Util_SignalBlockSignals.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalUnblockSignals() -{ - assert( nblocks==1); - nblocks--; - - sigprocmask(SIG_SETMASK, &old_procmask, NULL); -} - - -static void watch_tmp_file(const char* fname) -{ - if( watched_tmp_files_hash != NULL ) - { - Hash_GenWriteEntry(watched_tmp_files_hash, Extra_UtilStrsav(fname), (void*)getpid() ); - } -} - -static void unwatch_tmp_file(const char* fname) -{ - if ( watched_tmp_files_hash ) - { - assert( Hash_GenExists(watched_tmp_files_hash, fname) ); - Hash_GenRemove(watched_tmp_files_hash, fname); - assert( !Hash_GenExists(watched_tmp_files_hash, fname) ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Adds a process id to the list of processes that should be killed in a signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalAddChildPid(int pid) -{ - if ( watched_pid_hash ) - { - Hash_GenWriteEntry(watched_pid_hash, (void*)pid, (void*)getpid()); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Removes a process id from the list of processes that should be killed in a signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalRemoveChildPid(int pid) -{ - if ( watched_pid_hash ) - { - Hash_GenRemove(watched_pid_hash, (void*)pid); - } -} - -// a dummy signal hanlder to make sure that SIGCHLD and SIGINT will cause sigsuspend() to return -static int null_sig_handler(int signum) -{ - return 0; -} - - -// enusre that sigsuspend() returns when signal signum occurs -- sigsuspend() does not return if a signal is ignored -static void replace_sighandler(int signum, struct sigaction* old_sa, int replace_dfl) -{ - sigaction(signum, NULL, old_sa); - - if( old_sa->sa_handler == SIG_IGN || old_sa->sa_handler==SIG_DFL && replace_dfl) - { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - - sa.sa_handler = null_sig_handler; - - sigaction(signum, &sa, &old_sa); - } -} - -// -static int do_waitpid(pid_t pid, sigset_t* old_procmask) -{ - int status; - - struct sigaction sigint_sa; - struct sigaction sigchld_sa; - sigset_t waitmask; - - // ensure SIGINT and SIGCHLD are not blocked during sigsuspend() - memcpy(&waitmask, old_procmask, sizeof(sigset_t)); - - sigdelset(&waitmask, SIGINT); - sigdelset(&waitmask, SIGCHLD); - - // ensure sigsuspend() returns if SIGINT or SIGCHLD occur, and save the current settings for SIGCHLD and SIGINT - - replace_sighandler(SIGINT, &sigint_sa, 0); - replace_sighandler(SIGCHLD, &sigchld_sa, 1); - - for(;;) - { - int rc; - - // wait for a signal -- returns if SIGINT or SIGCHLD (or any other signal that is unblocked and not ignored) occur - sigsuspend(&waitmask); - - // check if pid has terminated - rc = waitpid(pid, &status, WNOHANG); - - // stop if terminated or some other error occurs - if( rc > 0 || rc == -1 && errno!=EINTR ) - { - break; - } - } - - // process is dead, should no longer be watched - Util_SignalRemoveChildPid(pid); - - // restore original behavior of SIGINT and SIGCHLD - sigaction(SIGINT, &sigint_sa, NULL); - sigaction(SIGCHLD, &sigchld_sa, NULL); - - return status; -} - -static int do_system(const char* cmd, sigset_t* old_procmask) -{ - int pid; - - pid = fork(); - - if (pid == -1) - { - // fork failed - return -1; - } - else if( pid == 0) - { - // child process - sigprocmask(SIG_SETMASK, old_procmask, NULL); - execl("/bin/sh", "sh", "-c", cmd, NULL); - _exit(127); - } - - Util_SignalAddChildPid(pid); - - return do_waitpid(pid, old_procmask); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Replaces system() with a function that allows SIGINT to interrupt.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -int Util_SignalSystem(const char* cmd) -{ - int status; - - sigset_t procmask; - sigset_t old_procmask; - - // if signal handler is not installed, run the original system() - if ( ! watched_pid_hash && ! watched_tmp_files_hash ) - return system(cmd); - - // block SIGINT and SIGCHLD - sigemptyset(&procmask); - - sigaddset(&procmask, SIGINT); - sigaddset(&procmask, SIGCHLD); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); - - // call the actual function - status = do_system(cmd, &old_procmask); - - // restore signal block mask - sigprocmask(SIG_SETMASK, &old_procmask, NULL); - return status; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -#else /* #ifndef _MSC_VER */ - -#include "abc_global.h" - -ABC_NAMESPACE_IMPL_START - -void Util_SignalCleanup() -{ -} - -void Util_SignalStartHandler() -{ -} - -void Util_SignalResetHandler() -{ -} - -void Util_SignalStopHandler() -{ -} - -void Util_SignalBlockSignals() -{ -} - -void Util_SignalUnblockSignals() -{ -} - -void watch_tmp_file(const char* fname) -{ -} - -void unwatch_tmp_file(const char* fname) -{ -} - -void Util_SignalAddChildPid(int pid) -{ -} - -void Util_SignalRemoveChildPid(int pid) -{ -} +#ifndef ABC_PYTHON_EMBED int Util_SignalSystem(const char* cmd) { return system(cmd); } -#endif /* #ifdef _MSC_VER */ - int tmpFile(const char* prefix, const char* suffix, char** out_name); -/**Function************************************************************* - - Synopsis [] - - Description [Create a temporary file and add it to the list of files to be cleaned up in the signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name) { - int fd; - - Util_SignalBlockSignals(); - - fd = tmpFile(prefix, suffix, out_name); - - if ( fd != -1 ) - { - watch_tmp_file( *out_name ); - } - - Util_SignalUnblockSignals(); - - return fd; + return tmpFile(prefix, suffix, out_name); } -/**Function************************************************************* - - Synopsis [] - - Description [Remove a temporary file (and remove it from the watched files list.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - void Util_SignalTmpFileRemove(const char* fname, int fLeave) { - Util_SignalBlockSignals(); - - unwatch_tmp_file(fname); - if (! fLeave) { - remove(fname); + unlink(fname); } - - Util_SignalUnblockSignals(); } +#endif /* ABC_PYTHON_EMBED */ + ABC_NAMESPACE_IMPL_END + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/utilSignal.h b/src/misc/util/utilSignal.h index d9802aa0..0ac87290 100644 --- a/src/misc/util/utilSignal.h +++ b/src/misc/util/utilSignal.h @@ -4,17 +4,17 @@ SystemName [ABC: Logic synthesis and verification system.] - PackageName [] + PackageName [Signal handling utilities.] - Synopsis [] + Synopsis [Signal handling utilities.] - Author [] + Author [Baruch Sterin] Affiliation [UC Berkeley] - Date [] + Date [Ver. 1.0. Started - February 1, 2011.] - Revision [] + Revision [$Id: utilSignal.h,v 1.00 2011/02/01 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -45,22 +45,9 @@ ABC_NAMESPACE_HEADER_START /*=== utilSignal.c ==========================================================*/ -void Util_SignalCleanup(); - -void Util_SignalStartHandler(); -void Util_SignalResetHandler(); -void Util_SignalStopHandler(); - -void Util_SignalBlockSignals(); -void Util_SignalUnblockSignals(); - -void Util_SignalAddChildPid(int pid); -void Util_SignalRemoveChildPid(int pid); - -int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name); -void Util_SignalTmpFileRemove(const char* fname, int fLeave); - -int Util_SignalSystem(const char* cmd); +extern int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name); +extern void Util_SignalTmpFileRemove(const char* fname, int fLeave); +extern int Util_SignalSystem(const char* cmd); ABC_NAMESPACE_HEADER_END diff --git a/src/misc/util/util_hack.h b/src/misc/util/util_hack.h index f7ad89f9..1a734f03 100644 --- a/src/misc/util/util_hack.h +++ b/src/misc/util/util_hack.h @@ -21,7 +21,6 @@ #ifndef __UTIL_HACK_H__ #define __UTIL_HACK_H__ - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -31,50 +30,18 @@ #include "abc_global.h" - ABC_NAMESPACE_HEADER_START +#define NIL(type) ((type *) 0) -#ifndef EXTERN -#define EXTERN extern -#endif -#define NIL(type) ((type *) 0) -#define random rand -#define srandom srand - -#define util_cpu_time Extra_CpuTime -#define getSoftDataLimit Extra_GetSoftDataLimit -#define util_getopt_reset Extra_UtilGetoptReset -#define util_getopt Extra_UtilGetopt -#define util_print_time Extra_UtilPrintTime -#define util_strsav Extra_UtilStrsav -#define util_tilde_expand Extra_UtilTildeExpand -#define util_file_search Extra_UtilFileSearch -#define MMoutOfMemory Extra_UtilMMoutOfMemory - -#define util_optarg globalUtilOptarg -#define util_optind globalUtilOptind - -#ifndef ARGS -#define ARGS(protos) protos -#endif - -extern long Extra_CpuTime(); -extern int Extra_GetSoftDataLimit(); -extern void Extra_UtilGetoptReset(); -extern int Extra_UtilGetopt( int argc, char *argv[], const char *optstring ); -extern char * Extra_UtilPrintTime( long t ); -extern char * Extra_UtilStrsav( char *s ); -extern char * Extra_UtilTildeExpand( char *fname ); -extern char * Extra_UtilFileSearch( char *file, char *path, char *mode ); - -extern char * globalUtilOptarg; -extern int globalUtilOptind; - +#define util_cpu_time Extra_CpuTime +#define getSoftDataLimit Extra_GetSoftDataLimit +#define MMoutOfMemory Extra_UtilMMoutOfMemory +extern long Extra_CpuTime(); +extern int Extra_GetSoftDataLimit(); +extern void (*Extra_UtilMMoutOfMemory)( long size ); ABC_NAMESPACE_HEADER_END - - #endif diff --git a/src/opt/dec/decFactor.c b/src/opt/dec/decFactor.c index aa9d9c8a..8c414915 100644 --- a/src/opt/dec/decFactor.c +++ b/src/opt/dec/decFactor.c @@ -366,11 +366,12 @@ Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ) ***********************************************************************/ int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm ) { - extern DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ); + extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars ); + extern DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ); DdManager * dd = (DdManager *)Abc_FrameReadManDd(); DdNode * bFunc1, * bFunc2; int RetValue; - bFunc1 = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFunc1 ); + bFunc1 = Abc_ConvertSopToBdd( dd, pSop, NULL ); Cudd_Ref( bFunc1 ); bFunc2 = Dec_GraphDeriveBdd( dd, pFForm ); Cudd_Ref( bFunc2 ); //Extra_bddPrint( dd, bFunc1 ); printf("\n"); //Extra_bddPrint( dd, bFunc2 ); printf("\n"); diff --git a/src/opt/dec/decUtil.c b/src/opt/dec/decUtil.c index adf216f6..d2b5631e 100644 --- a/src/opt/dec/decUtil.c +++ b/src/opt/dec/decUtil.c @@ -17,6 +17,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "dec.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h index db855f3b..282b1d2b 100644 --- a/src/opt/fxu/fxu.h +++ b/src/opt/fxu/fxu.h @@ -60,7 +60,7 @@ struct FxuDataStruct Vec_Ptr_t * vSopsNew; // the SOPs for each node in the network after extraction Vec_Ptr_t * vFaninsNew; // the fanins of each node in the network after extraction // the SOP manager - Extra_MmFlex_t * pManSop; + Mem_Flex_t * pManSop; // statistics int nNodesOld; // the old number of nodes int nNodesNew; // the number of divisors actually extracted diff --git a/src/opt/fxu/fxuCreate.c b/src/opt/fxu/fxuCreate.c index 3466b520..76c534e3 100644 --- a/src/opt/fxu/fxuCreate.c +++ b/src/opt/fxu/fxuCreate.c @@ -16,7 +16,6 @@ ***********************************************************************/ -#include "abc.h" #include "fxuInt.h" #include "fxu.h" diff --git a/src/opt/fxu/fxuInt.h b/src/opt/fxu/fxuInt.h index 96bec083..bbceac47 100644 --- a/src/opt/fxu/fxuInt.h +++ b/src/opt/fxu/fxuInt.h @@ -24,8 +24,8 @@ /// INCLUDES /// //////////////////////////////////////////////////////////////////////// +#include "abc.h" #include "extra.h" -#include "vec.h" ABC_NAMESPACE_HEADER_START diff --git a/src/opt/mfs/mfsInt.h b/src/opt/mfs/mfsInt.h index 28a68bd8..650a154a 100644 --- a/src/opt/mfs/mfsInt.h +++ b/src/opt/mfs/mfsInt.h @@ -27,6 +27,7 @@ //////////////////////////////////////////////////////////////////////// #include "abc.h" +#include "extra.h" #include "mfs.h" #include "aig.h" #include "cnf.h" diff --git a/src/opt/res/resSim.c b/src/opt/res/resSim.c index 560acc43..740b7d0a 100644 --- a/src/opt/res/resSim.c +++ b/src/opt/res/resSim.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "resInt.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/res/resStrash.c b/src/opt/res/resStrash.c index 9740af4c..1ee84957 100644 --- a/src/opt/res/resStrash.c +++ b/src/opt/res/resStrash.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "resInt.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/rwr/rwrDec.c b/src/opt/rwr/rwrDec.c index 76d8ac51..a280f5f1 100644 --- a/src/opt/rwr/rwrDec.c +++ b/src/opt/rwr/rwrDec.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" #include "dec.h" diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c index 8f0c1821..4dc6c082 100644 --- a/src/opt/rwr/rwrEva.c +++ b/src/opt/rwr/rwrEva.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" #include "dec.h" #include "ivy.h" diff --git a/src/opt/rwr/rwrExp.c b/src/opt/rwr/rwrExp.c index c4664fbf..fa75f066 100644 --- a/src/opt/rwr/rwrExp.c +++ b/src/opt/rwr/rwrExp.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/rwr/rwrLib.c b/src/opt/rwr/rwrLib.c index 731871d0..a7c01047 100644 --- a/src/opt/rwr/rwrLib.c +++ b/src/opt/rwr/rwrLib.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/rwr/rwrMan.c b/src/opt/rwr/rwrMan.c index ffc5fcae..0f32c0da 100644 --- a/src/opt/rwr/rwrMan.c +++ b/src/opt/rwr/rwrMan.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" #include "main.h" #include "dec.h" diff --git a/src/opt/rwr/rwrPrint.c b/src/opt/rwr/rwrPrint.c index 11a084d3..5574df88 100644 --- a/src/opt/rwr/rwrPrint.c +++ b/src/opt/rwr/rwrPrint.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/rwr/rwrTemp.c b/src/opt/rwr/rwrTemp.c index 6a670c3a..654e37c1 100644 --- a/src/opt/rwr/rwrTemp.c +++ b/src/opt/rwr/rwrTemp.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/rwr/rwrUtil.c b/src/opt/rwr/rwrUtil.c index 7a836d63..7613691a 100644 --- a/src/opt/rwr/rwrUtil.c +++ b/src/opt/rwr/rwrUtil.c @@ -18,6 +18,7 @@ ***********************************************************************/ +#include "extra.h" #include "rwr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simMan.c b/src/opt/sim/simMan.c index 234aa412..f3a9650b 100644 --- a/src/opt/sim/simMan.c +++ b/src/opt/sim/simMan.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSat.c b/src/opt/sim/simSat.c index 29fc6975..5654c493 100644 --- a/src/opt/sim/simSat.c +++ b/src/opt/sim/simSat.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSeq.c b/src/opt/sim/simSeq.c index db05226f..fd75ba8d 100644 --- a/src/opt/sim/simSeq.c +++ b/src/opt/sim/simSeq.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSupp.c b/src/opt/sim/simSupp.c index 563f98ac..67ac5efe 100644 --- a/src/opt/sim/simSupp.c +++ b/src/opt/sim/simSupp.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "fraig.h" #include "sim.h" diff --git a/src/opt/sim/simSwitch.c b/src/opt/sim/simSwitch.c index 4f675082..a9045ca1 100644 --- a/src/opt/sim/simSwitch.c +++ b/src/opt/sim/simSwitch.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSym.c b/src/opt/sim/simSym.c index d8a1eb4f..c6b588ac 100644 --- a/src/opt/sim/simSym.c +++ b/src/opt/sim/simSym.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSymSat.c b/src/opt/sim/simSymSat.c index 4f6690e5..bdc8fbee 100644 --- a/src/opt/sim/simSymSat.c +++ b/src/opt/sim/simSymSat.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" #include "fraig.h" diff --git a/src/opt/sim/simSymSim.c b/src/opt/sim/simSymSim.c index 85ba56fb..af942a19 100644 --- a/src/opt/sim/simSymSim.c +++ b/src/opt/sim/simSymSim.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simSymStr.c b/src/opt/sim/simSymStr.c index e9a25905..4d83dc61 100644 --- a/src/opt/sim/simSymStr.c +++ b/src/opt/sim/simSymStr.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c index 25d4cd44..aa3fc8af 100644 --- a/src/opt/sim/simUtils.c +++ b/src/opt/sim/simUtils.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "abc.h" +#include "extra.h" #include "sim.h" ABC_NAMESPACE_IMPL_START diff --git a/src/python/module.make b/src/python/module.make index ac56208d..3f48bbaf 100644 --- a/src/python/module.make +++ b/src/python/module.make @@ -61,4 +61,21 @@ pyabc.tgz : $(PROG) $(ABC_PYTHON_SRC:_wrap.c=.py) $(ABC_PYTHON_FILES_PREFIX)/abc --out=$@ \ $(ABC_PYTHON_OPTIONS) +PYABC_INSTALL_TARGET ?= $(shell date +%Y-%m-%d_%H-%M.%N_${USER}) +PYABC_INSTALL_TARGET := $(PYABC_INSTALL_TARGET) + +PYABC_INSTALL_DIR ?= /hd/common/pyabc/builds/pyabc_builds/ + +.PHONY: zzz + +pyabc_install_target: pyabc_extension_bdist + mkdir -p "$(PYABC_INSTALL_DIR)/$(PYABC_INSTALL_TARGET)" + tar \ + --directory="$(PYABC_INSTALL_DIR)/$(PYABC_INSTALL_TARGET)" \ + --show-transformed-names \ + --transform='s#^.*/##g' \ + -xvzf "$(ABC_PYTHON_FILES_PREFIX)/dist/pyabc-1.0.linux-x86_64.tar.gz" + find "$(PYABC_INSTALL_DIR)/$(PYABC_INSTALL_TARGET)/"* -type d | xargs rmdir + echo "Installed at $(PYABC_INSTALL_DIR)/$(PYABC_INSTALL_TARGET)" + endif diff --git a/src/python/pyabc.i b/src/python/pyabc.i index 0bf58288..e258575e 100644 --- a/src/python/pyabc.i +++ b/src/python/pyabc.i @@ -23,9 +23,18 @@ %{ #include <main.h> +#include <utilCex.h> + #include <stdlib.h> #include <signal.h> -#include "utilSignal.h" + +#include <sys/prctl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> int n_ands() { @@ -160,6 +169,56 @@ int n_phases() return pNtk ? Abc_NtkPhaseFrameNum(pNtk) : 1; } +Abc_Cex_t* _cex_get() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Cex_t* pCex = Abc_FrameReadCex(pAbc); + + if ( ! pCex ) + { + return NULL; + } + + return Abc_CexDup( pCex, -1 ); +} + +void _cex_put(Abc_Cex_t* pCex) +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + if ( pCex ) + { + pCex = Abc_CexDup(pCex, -1); + } + + Abc_FrameSetCex( Abc_CexDup(pCex, -1) ); +} + +void _cex_free(Abc_Cex_t* pCex) +{ + Abc_CexFree(pCex); +} + +int _cex_n_regs(Abc_Cex_t* pCex) +{ + return pCex->nRegs; +} + +int _cex_n_pis(Abc_Cex_t* pCex) +{ + return pCex->nPis; +} + +int _cex_get_po(Abc_Cex_t* pCex) +{ + return pCex->iPo; +} + +int _cex_get_frame(Abc_Cex_t* pCex) +{ + return pCex->iFrame; +} + static PyObject* pyabc_internal_python_command_callback = 0; void pyabc_internal_set_command_callback( PyObject* callback ) @@ -170,6 +229,8 @@ void pyabc_internal_set_command_callback( PyObject* callback ) pyabc_internal_python_command_callback = callback; } +PyThreadState *_save; + static int pyabc_internal_abc_command_callback(Abc_Frame_t * pAbc, int argc, char ** argv) { int i; @@ -183,6 +244,8 @@ static int pyabc_internal_abc_command_callback(Abc_Frame_t * pAbc, int argc, cha if ( !pyabc_internal_python_command_callback ) return 0; + Py_BLOCK_THREADS + args = PyList_New(argc); for( i=0 ; i<argc ; i++ ) @@ -196,19 +259,30 @@ static int pyabc_internal_abc_command_callback(Abc_Frame_t * pAbc, int argc, cha if ( !res ) { + Py_UNBLOCK_THREADS return -1; } lres = PyInt_AsLong(res); Py_DECREF(res); + Py_UNBLOCK_THREADS + return lres; } int run_command(char* cmd) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); - return Cmd_CommandExecute(pAbc, cmd); + int rc; + + Py_UNBLOCK_THREADS + + rc = Cmd_CommandExecute(pAbc, cmd); + + Py_BLOCK_THREADS + + return rc; } void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges ) @@ -218,45 +292,212 @@ void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges Cmd_CommandAdd( pAbc, sGroup, sName, (void*)pyabc_internal_abc_command_callback, fChanges); } -static void sigint_handler(int signum) +static int sigchld_pipe_fd = -1; + +static void sigchld_handler(int signum) +{ + while( write(sigchld_pipe_fd, "", 1) == -1 && errno==EINTR ) + ; +} + +static void install_sigchld_handler(int sigchld_fd) { - Util_SignalCleanup(); - _exit(1); + sigchld_pipe_fd = sigchld_fd; + signal(SIGCHLD, sigchld_handler); } -void add_child_pid(int pid) +static int sigint_pipe_fd = -1; + +static void sigint_handler(int signum) { - Util_SignalAddChildPid(pid); + unsigned char tmp = (unsigned char)signum; + while( write(sigint_pipe_fd, &tmp, 1) == -1 && errno==EINTR ) + ; } -void remove_child_pid(int pid) +static void install_sigint_handler(int sigint_fd) { - Util_SignalRemoveChildPid(pid); + sigint_pipe_fd = sigint_fd; + + signal(SIGINT, sigint_handler); + + // try to catch other signals that ask the process to terminate + signal(SIGABRT, sigint_handler); + signal(SIGQUIT, sigint_handler); + signal(SIGTERM, sigint_handler); + + // try to ensure cleanup on exceptional conditions + signal(SIGBUS, sigint_handler); + signal(SIGILL, sigint_handler); + signal(SIGSEGV, sigint_handler); + + // try to ensure cleanup before being killed due to resource limit + signal(SIGXCPU, sigint_handler); + signal(SIGXFSZ, sigint_handler); } +sigset_t old_procmask; +static int nblocks = 0; + void block_sigint() { - Util_SignalBlockSignals(); + sigset_t procmask; + + assert(nblocks==0); + nblocks ++ ; + + sigemptyset(&procmask); + sigaddset(&procmask, SIGINT); + + sigprocmask(SIG_BLOCK, &procmask, &old_procmask); } -void restore_sigint_block() +void unblock_sigint() { - Util_SignalUnblockSignals(); + assert( nblocks==1); + nblocks--; + + sigprocmask(SIG_SETMASK, &old_procmask, NULL); } -void reset_sigint_handler() +static PyObject* pyabc_internal_system_callback = 0; +static PyObject* pyabc_internal_tmpfile_callback = 0; +static PyObject* pyabc_internal_tmpfile_remove_callback = 0; + +int Util_SignalSystem(const char* cmd) { - Util_SignalResetHandler(); + PyObject* arglist; + PyObject* res; + + long lres; + + if ( !pyabc_internal_system_callback ) + return -1; + + Py_BLOCK_THREADS + + arglist = Py_BuildValue("(O)", PyString_FromString(cmd)); + Py_INCREF(arglist); + + res = PyEval_CallObject( pyabc_internal_system_callback, arglist ); + Py_DECREF(arglist); + + if ( !res ) + { + Py_UNBLOCK_THREADS + return -1; + } + + lres = PyInt_AsLong(res); + Py_DECREF(res); + + Py_UNBLOCK_THREADS + + return lres; +} + +int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name) +{ + char* str; + Py_ssize_t size; + + PyObject* arglist; + PyObject* res; + + *out_name = NULL; + + if ( !pyabc_internal_tmpfile_callback ) + return 0; + + Py_BLOCK_THREADS + + arglist = Py_BuildValue("(ss)", prefix, suffix); + Py_INCREF(arglist); + + res = PyEval_CallObject( pyabc_internal_tmpfile_callback, arglist ); + Py_DECREF(arglist); + + if ( !res ) + { + Py_UNBLOCK_THREADS + return -1; + } + + PyString_AsStringAndSize(res, &str, &size); + + *out_name = ABC_ALLOC(char, size+1); + strcpy(*out_name, str); + + Py_DECREF(res); + + Py_UNBLOCK_THREADS + + return open(*out_name, O_WRONLY); +} + +void Util_SignalTmpFileRemove(const char* fname, int fLeave) +{ + PyObject* arglist; + PyObject* res; + + if ( !pyabc_internal_tmpfile_remove_callback ) + return; + + Py_BLOCK_THREADS + + arglist = Py_BuildValue("(si)", fname, fLeave); + Py_INCREF(arglist); + + res = PyEval_CallObject( pyabc_internal_tmpfile_remove_callback, arglist ); + Py_DECREF(arglist); + Py_XDECREF(res); + + Py_UNBLOCK_THREADS +} + +void pyabc_internal_set_util_callbacks( PyObject* system_callback, PyObject* tmpfile_callback, PyObject* tmpfile_remove_callback ) +{ + Py_XINCREF(system_callback); + Py_XDECREF(pyabc_internal_system_callback); + + pyabc_internal_system_callback = system_callback; + + Py_XINCREF(tmpfile_callback); + Py_XDECREF(pyabc_internal_tmpfile_callback); + + pyabc_internal_tmpfile_callback = tmpfile_callback; + + Py_XINCREF(tmpfile_remove_callback); + Py_XDECREF(pyabc_internal_tmpfile_remove_callback); + + pyabc_internal_tmpfile_remove_callback = tmpfile_remove_callback; } +PyObject* _wait_no_hang() +{ + int status; + int pid; + + pid = wait3(&status, WNOHANG, NULL); + + return Py_BuildValue("(iii)", pid, status, errno); +} + +int _posix_kill(int pid, int signum) +{ + return kill(pid, signum); +} + +void _set_death_signal() +{ + prctl(PR_SET_PDEATHSIG, SIGINT); +} %} %init %{ Abc_Start(); - Util_SignalStartHandler(); - signal(SIGINT, sigint_handler); %} int n_ands(); @@ -281,18 +522,442 @@ int cex_frame(); int n_phases(); +Abc_Cex_t* _cex_get(); +void _cex_put(Abc_Cex_t* pCex); +void _cex_free(Abc_Cex_t* pCex); +int _cex_n_regs(Abc_Cex_t* pCex); +int _cex_n_pis(Abc_Cex_t* pCex); +int _cex_get_po(Abc_Cex_t* pCex); +int _cex_get_frame(Abc_Cex_t* pCex); + void pyabc_internal_set_command_callback( PyObject* callback ); void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges ); +void install_sigchld_handler(int sigint_fd); +void install_sigint_handler(int sigint_fd); + void block_sigint(); -void restore_sigint_block(); -void add_child_pid(int pid); -void remove_child_pid(int pid); -void reset_sigint_handler(); +void unblock_sigint(); + +void pyabc_internal_set_util_callbacks( PyObject* system_callback, PyObject* tmpfile_callback, PyObject* tmpfile_remove_callback ); + +PyObject* _wait_no_hang(); + +void _set_death_signal(); + +int _posix_kill(int pid, int signum); +void _set_death_signal(); %pythoncode %{ +class _Cex(object): + + def __init__(self, pCex): + self.pCex = pCex + + def __del__(self): + _cex_free(self.pCex) + + def n_regs(self): + return _cex_n_regs(self.pCex) + + def n_pis(self): + return _cex_n_pis(self.pCex) + + def get_po(self): + return _cex_get_po(self.pCex) + + def get_frame(self): + return _cex_get_frame(self.pCex) + +def cex_get(): + + cex = _cex_get() + + if cex is None: + return None + + return _Cex(_cex_get()) + +def cex_put(cex): + + assert cex is not None + assert cex.pCex is not None + + return _cex_put(cex.pCex) + +import threading +import select +import signal +import tempfile +import os +import errno +import sys, traceback +import subprocess + +_active_lock = threading.Lock() +_die_flag = False + +_active_pids = set() +_active_temp_files = set() + +_terminated_pids_cond = threading.Condition(_active_lock) +_terminated_pids = {} + +def add_temp_file(fname): + with _active_lock: + _active_temp_files.add(fname) + +def remove_temp_file(fname): + with _active_lock: + _active_temp_files.remove(fname) + +_old_os_wait3 = os.wait3 +_select_select = select.select + +def _retry_select(fd): + while True: + try: + rrdy,_,_ = _select_select([fd],[],[]) + if fd in rrdy: + return + except select.error as e: + if e[0] == errno.EINTR: + continue + raise + +def _retry_read(fd): + + while True: + try: + return fd.read(1) + except OSError as e: + if e.errno == errno.EINTR: + continue + raise + +def _retry_wait(): + + while True: + + pid, status, e = _wait_no_hang() + + if pid>0: + return pid, status + + elif pid==0: + return 0,0 + + elif pid == -1 and e == errno.ECHILD: + return 0,0 + + elif pid==-1 and e != errno.EINTR: + raise OSError(e, 'unknown error in wait3()') + +def _sigint_wait_thread_func(fd): + + global _die_flag + + while True: + + _retry_select(fd) + _retry_read(fd) + + with _active_lock: + + if _die_flag: + os._exit(-1) + + _die_flag = True + + for pid in _active_pids: + rc = _posix_kill(pid, signal.SIGINT) + + for fname in _active_temp_files: + os.remove(fname) + + os._exit(-1) + +def _child_wait_thread_func(fd): + + while True: + + _retry_select(fd) + rc = _retry_read(fd) + + with _active_lock: + + while True: + + pid, status = _retry_wait() + + if pid==0: + break + + if pid in _active_pids: + _active_pids.remove(pid) + + _terminated_pids[pid] = status + _terminated_pids_cond.notifyAll() + +_sigint_pipe_read_fd = -1 +_sigint_pipe_write_fd = -1 + +_sigchld_pipe_read_fd = -1 +_sigchld_pipe_write_fd = -1 + +def _start_threads(): + + global _sigint_pipe_read_fd, _sigint_pipe_write_fd + + _sigint_pipe_read_fd, _sigint_pipe_write_fd = os.pipe() + sigint_read = os.fdopen(_sigint_pipe_read_fd, "r", 0 ) + + sigint_wait_thread = threading.Thread(target=_sigint_wait_thread_func, name="SIGINT wait thread", args=(sigint_read,)) + sigint_wait_thread.setDaemon(True) + sigint_wait_thread.start() + + install_sigint_handler(_sigint_pipe_write_fd) + + global _sigchld_pipe_read_fd, _sigchld_pipe_write_fd + + _sigchld_pipe_read_fd, _sigchld_pipe_write_fd = os.pipe() + sigchld_read = os.fdopen(_sigchld_pipe_read_fd, "r", 0 ) + + child_wait_thread = threading.Thread(target=_child_wait_thread_func, name="child process wait thread", args=(sigchld_read,)) + child_wait_thread.setDaemon(True) + child_wait_thread.start() + + install_sigchld_handler(_sigchld_pipe_write_fd) + +_close_on_fork = [] + +def close_on_fork(fd): + _close_on_fork.append(fd) + +def after_fork(): + + _set_death_signal() + + global _close_on_fork + + for fd in _close_on_fork: + os.close(fd) + + _close_on_fork = [] + + os.close(_sigint_pipe_read_fd) + os.close(_sigint_pipe_write_fd) + + os.close(_sigchld_pipe_read_fd) + os.close(_sigchld_pipe_write_fd) + + global _active_lock + _active_lock = threading.Lock() + + global _terminated_pids_cond + _terminated_pids_cond = threading.Condition(_active_lock) + + global _terminated_pids + _terminated_pids = {} + + global _active_pids + _active_pids = set() + + global _active_temp_files + _active_temp_files = set() + + _start_threads() + +class _sigint_block_section(object): + def __init__(self): + self.blocked = False + + def __enter__(self): + block_sigint() + self.blocked = True + + def __exit__(self, type, value, traceback): + self.release() + + def release(self): + if self.blocked: + self.blocked = False + unblock_sigint() + +_old_os_fork = os.fork + +def _fork(): + + ppid = os.getpid() + + with _sigint_block_section() as cs: + + with _active_lock: + + if _die_flag: + os._exit(-1) + + pid = _old_os_fork() + + if pid == 0: + after_fork() + + if pid > 0: + _active_pids.add(pid) + + return pid + +def _waitpid(pid, options=0): + + while True: + + with _active_lock: + + if pid in _terminated_pids: + status = _terminated_pids[pid] + del _terminated_pids[pid] + return pid, status + + if options==os.WNOHANG: + return 0, 0 + + _terminated_pids_cond.wait() + +def _wait(options=0): + + while True: + + with _active_lock: + + for pid, status in _terminated_pids.iteritems(): + del _terminated_pids[pid] + return pid, status + + if options==os.WNOHANG: + return 0, 0 + + _terminated_pids_cond.wait() + +_old_os_kill = os.kill + +def _kill(pid, sig): + + with _active_lock: + + if pid in _terminated_pids: + return None + + return _old_os_kill(pid,sig) + +os.kill = _kill +os.fork = _fork +os.wait = _wait +os.waitpid = _waitpid + +def _split_command_line(cmd): + + args = [] + + i=0 + + while i<len(cmd): + + while i<len(cmd) and cmd[i] in [' ','\t','\f']: + i += 1 + + if i >= len(cmd): + break + + arg = [] + + in_quotes = None + + while i<len(cmd): + + if not in_quotes and cmd[i] in ['\'','\"','\'']: + in_quotes = cmd[i] + + elif in_quotes and cmd[i]==in_quotes: + in_quotes = None + + elif cmd[i] == '\\' and i<(len(cmd)+1): + + i += 1 + + if cmd[i]=='\\': + arg.append('\\') + elif cmd[i]=='\'': + arg.append('\'') + elif cmd[i]=='\"': + arg.append('\'') + elif cmd[i]=='\"': + arg.append('\"') + elif cmd[i]=='a': + arg.append('\a') + elif cmd[i]=='b': + arg.append('\b') + elif cmd[i]=='n': + arg.append('\n') + elif cmd[i]=='f': + arg.append('\f') + elif cmd[i]=='r': + arg.append('\r') + elif cmd[i]=='t': + arg.append('\t') + elif cmd[i]=='v': + arg.append('\v') + else: + arg.append(cmd[i]) + + elif not in_quotes and cmd[i] in [' ','\t','\f']: + break + + else: + arg.append(cmd[i]) + + i += 1 + + args.append( "".join(arg) ) + + return args + + +def system(cmd): + + args = _split_command_line(cmd) + + if args[-2] == '>': + + with open(args[-1],'w') as fout: + p = subprocess.Popen(args[:-2], stdout=fout) + rc = p.wait() + return rc + + else: + p = subprocess.Popen(args) + return p.wait() + +def tmpfile(prefix, suffix): + + with _active_lock: + with tempfile.NamedTemporaryFile(delete=False, prefix=prefix, suffix=suffix) as file: + _active_temp_files.add(file.name) + return file.name + +def tmpfile_remove(fname, leave): + + with _active_lock: + os.remove(fname) + _active_temp_files.remove(fname) + +pyabc_internal_set_util_callbacks( system, tmpfile,tmpfile_remove ) + + +_start_threads() + + _registered_commands = {} def _cmd_callback(args): @@ -309,7 +974,8 @@ def _cmd_callback(args): return res except Exception, e: - print "Python error: ", e + import traceback + traceback.print_exc() except SystemExit, se: pass @@ -322,14 +988,11 @@ def add_abc_command(fcmd, group, cmd, change): _registered_commands[ cmd ] = fcmd pyabc_internal_register_command( group, cmd, change) -import sys import optparse -import os.path -import __main__ +xxx = {} def cmd_python(cmd_args): - global __main__ usage = "usage: %prog [options] <Python files>" @@ -345,7 +1008,7 @@ def cmd_python(cmd_args): return 0 if options.cmd: - exec options.cmd in __main__.__dict__ + exec options.cmd in xxx return 0 scripts_dir = os.getenv('ABC_PYTHON_SCRIPTS', ".") @@ -353,12 +1016,12 @@ def cmd_python(cmd_args): for fname in args[1:]: if os.path.isabs(fname): - execfile(fname, __main__.__dict__) + execfile(fname, xxx) else: for d in scripts_dirs: fname = os.path.join(scripts_dir, fname) if os.path.exists(fname): - execfile(fname, __main__.__dict__) + execfile(fname, xxx) break return 0 diff --git a/src/python/pyabc_split.py b/src/python/pyabc_split.py index 431a87a8..b889d857 100644 --- a/src/python/pyabc_split.py +++ b/src/python/pyabc_split.py @@ -15,7 +15,6 @@ Caveats: 1. Global variables in the parent process are not affected by the child processes. 2. The functions can only return simple types, see the pickle module for details -3. Signals are currently not handled correctly Usage: @@ -91,47 +90,6 @@ from contextlib import contextmanager import pyabc -def _waitpid(pid, flags): - while True: - try: - res = os.waitpid(pid, flags) - return res - except OSError as e: - if e.errno != errno.EINTR: - raise - -def _wait(): - while True: - try: - pid,rc = os.wait() - return pid, rc - except OSError as e: - if e.errno != errno.EINTR: - raise - except Exceptions as e: - raise - -class _sigint_critical_section(object): - def __init__(self): - self.blocked = False - - def __enter__(self): - self.acquire() - return self - - def __exit__(self, type, value, traceback): - self.release() - - def acquire(self): - if not self.blocked: - self.blocked = True - pyabc.block_sigint() - - def release(self): - if self.blocked: - self.blocked = False - pyabc.restore_sigint_block() - class _splitter(object): def __init__(self, funcs): @@ -144,18 +102,19 @@ class _splitter(object): return len(self.fds) == 0 def cleanup(self): - # close pipes and kill child processes for pid,(i,fd) in self.fds.iteritems(): os.close(fd) - os.kill( pid, signal.SIGINT ) + try: + os.kill( pid, signal.SIGINT ) + except Exception as e: + print >>sys.stderr, 'exception while trying to kill pid=%d: '%pid, e + raise - with _sigint_critical_section() as cs: # wait for termination and update result - for pid, _ in self.fds.iteritems(): - _waitpid( pid, 0 ) - pyabc.remove_child_pid(pid) - self.results[pid] = None + for pid, _ in self.fds.iteritems(): + os.waitpid( pid, 0 ) + self.results[pid] = None self.fds = {} @@ -179,22 +138,20 @@ class _splitter(object): try: - with _sigint_critical_section() as cs: - # create child process - pid = os.fork() - - if pid == 0: - # child process: - pyabc.reset_sigint_handler() - cs.release() - os.close(pr) - rc = self.child( pw, f) - os._exit(rc) - else: - # parent process: - pyabc.add_child_pid(pid) - os.close(pw) - return (pid, pr) + # create child process + pid = os.fork() + + if pid == 0: + # child process: + os.close(pr) + pyabc.close_on_fork(pw) + + rc = self.child( pw, f) + os._exit(rc) + else: + # parent process: + os.close(pw) + return (pid, pr) finally: if os.getpid() != parentpid: @@ -209,12 +166,9 @@ class _splitter(object): def get_next_result(self): # wait for the next child process to terminate - pid, rc = _wait() + pid, rc = os.wait() assert pid in self.fds - with _sigint_critical_section() as cs: - pyabc.remove_child_pid(pid) - # retrieve the pipe file descriptor1 i, fd = self.fds[pid] del self.fds[pid] diff --git a/src/python/setup.py b/src/python/setup.py index a832f511..3ef006af 100644 --- a/src/python/setup.py +++ b/src/python/setup.py @@ -7,6 +7,7 @@ from distutils import util include_dirs = [ '../aig/hop', '../aig/gia', + '../aig/mem', '../base/abc', '../base/cmd', '../base/io', diff --git a/src/sat/csat/csat_apis.c b/src/sat/csat/csat_apis.c index d49f75c0..78ed2601 100644 --- a/src/sat/csat/csat_apis.c +++ b/src/sat/csat/csat_apis.c @@ -41,7 +41,7 @@ struct ABC_ManagerStruct_t Abc_Ntk_t * pNtk; // the starting ABC network Abc_Ntk_t * pTarget; // the AIG representing the target char * pDumpFileName; // the name of the file to dump the target network - Extra_MmFlex_t * pMmNames; // memory manager for signal names + Mem_Flex_t * pMmNames; // memory manager for signal names // solving parameters int mode; // 0 = resource-aware integration; 1 = brute-force SAT Prove_Params_t Params; // integrated CEC parameters @@ -88,7 +88,7 @@ ABC_Manager ABC_InitManager() mng->pNtk->pName = Extra_UtilStrsav("csat_network"); mng->tName2Node = stmm_init_table(strcmp, stmm_strhash); mng->tNode2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); - mng->pMmNames = Extra_MmFlexStart(); + mng->pMmNames = Mem_FlexStart(); mng->vNodes = Vec_PtrAlloc( 100 ); mng->vValues = Vec_IntAlloc( 100 ); mng->mode = 0; // set "resource-aware integration" as the default mode @@ -116,7 +116,7 @@ void ABC_ReleaseManager( ABC_Manager mng ) ABC_TargetResFree(p_res); if ( mng->tNode2Name ) stmm_free_table( mng->tNode2Name ); if ( mng->tName2Node ) stmm_free_table( mng->tName2Node ); - if ( mng->pMmNames ) Extra_MmFlexStop( mng->pMmNames ); + if ( mng->pMmNames ) Mem_FlexStop( mng->pMmNames, 0 ); if ( mng->pNtk ) Abc_NtkDelete( mng->pNtk ); if ( mng->pTarget ) Abc_NtkDelete( mng->pTarget ); if ( mng->vNodes ) Vec_PtrFree( mng->vNodes ); @@ -181,7 +181,7 @@ int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, cha int i; // save the name in the local memory manager - pNewName = Extra_MmFlexEntryFetch( mng->pMmNames, strlen(name) + 1 ); + pNewName = Mem_FlexEntryFetch( mng->pMmNames, strlen(name) + 1 ); strcpy( pNewName, name ); name = pNewName; @@ -220,51 +220,51 @@ int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, cha case CSAT_CONST: if ( nofi != 0 ) { printf( "ABC_AddGate: The constant gate \"%s\" has fanins.\n", name ); return 0; } - pSop = Abc_SopCreateConst1( (Extra_MmFlex_t *)mng->pNtk->pManFunc ); + pSop = Abc_SopCreateConst1( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; case CSAT_BAND: if ( nofi < 1 ) { printf( "ABC_AddGate: The AND gate \"%s\" no fanins.\n", name ); return 0; } - pSop = Abc_SopCreateAnd( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi, NULL ); + pSop = Abc_SopCreateAnd( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL ); break; case CSAT_BNAND: if ( nofi < 1 ) { printf( "ABC_AddGate: The NAND gate \"%s\" no fanins.\n", name ); return 0; } - pSop = Abc_SopCreateNand( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi ); + pSop = Abc_SopCreateNand( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The OR gate \"%s\" no fanins.\n", name ); return 0; } - pSop = Abc_SopCreateOr( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi, NULL ); + pSop = Abc_SopCreateOr( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL ); break; case CSAT_BNOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The NOR gate \"%s\" no fanins.\n", name ); return 0; } - pSop = Abc_SopCreateNor( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi ); + pSop = Abc_SopCreateNor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BXOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The XOR gate \"%s\" no fanins.\n", name ); return 0; } if ( nofi > 2 ) { printf( "ABC_AddGate: The XOR gate \"%s\" has more than two fanins.\n", name ); return 0; } - pSop = Abc_SopCreateXor( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi ); + pSop = Abc_SopCreateXor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BXNOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The XNOR gate \"%s\" no fanins.\n", name ); return 0; } if ( nofi > 2 ) { printf( "ABC_AddGate: The XNOR gate \"%s\" has more than two fanins.\n", name ); return 0; } - pSop = Abc_SopCreateNxor( (Extra_MmFlex_t *)mng->pNtk->pManFunc, nofi ); + pSop = Abc_SopCreateNxor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BINV: if ( nofi != 1 ) { printf( "ABC_AddGate: The inverter gate \"%s\" does not have exactly one fanin.\n", name ); return 0; } - pSop = Abc_SopCreateInv( (Extra_MmFlex_t *)mng->pNtk->pManFunc ); + pSop = Abc_SopCreateInv( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; case CSAT_BBUF: if ( nofi != 1 ) { printf( "ABC_AddGate: The buffer gate \"%s\" does not have exactly one fanin.\n", name ); return 0; } - pSop = Abc_SopCreateBuf( (Extra_MmFlex_t *)mng->pNtk->pManFunc ); + pSop = Abc_SopCreateBuf( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; default : break; diff --git a/src/sat/pdr/pdrInv.c b/src/sat/pdr/pdrInv.c index 184b6c4f..5eb32790 100644 --- a/src/sat/pdr/pdrInv.c +++ b/src/sat/pdr/pdrInv.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "pdrInt.h" +#include "extra.h" ABC_NAMESPACE_IMPL_START @@ -44,7 +45,6 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, int Time ) { - extern int Extra_Base10Log( unsigned int Num ); static int PastSize; Vec_Ptr_t * vVec; int i, ThisSize, Length, LengthStart; diff --git a/src/sat/pdr/pdrMan.c b/src/sat/pdr/pdrMan.c index f33f6586..97f0992b 100644 --- a/src/sat/pdr/pdrMan.c +++ b/src/sat/pdr/pdrMan.c @@ -157,7 +157,6 @@ void Pdr_ManStop( Pdr_Man_t * p ) ***********************************************************************/ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) { - extern Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); Abc_Cex_t * pCex; Pdr_Obl_t * pObl; int i, f, Lit, nFrames = 0; @@ -165,7 +164,7 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) for ( pObl = p->pQueue; pObl; pObl = pObl->pNext ) nFrames++; // create the counter-example - pCex = Gia_ManAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames ); + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames ); pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput; pCex->iFrame = nFrames-1; for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) |