summaryrefslogtreecommitdiffstats
path: root/src/proof/cec
diff options
context:
space:
mode:
Diffstat (limited to 'src/proof/cec')
-rw-r--r--src/proof/cec/cec.c53
-rw-r--r--src/proof/cec/cec.h233
-rw-r--r--src/proof/cec/cecCec.c373
-rw-r--r--src/proof/cec/cecChoice.c409
-rw-r--r--src/proof/cec/cecClass.c931
-rw-r--r--src/proof/cec/cecCore.c542
-rw-r--r--src/proof/cec/cecCorr.c1137
-rw-r--r--src/proof/cec/cecCorr_updated.c1027
-rw-r--r--src/proof/cec/cecInt.h225
-rw-r--r--src/proof/cec/cecIso.c375
-rw-r--r--src/proof/cec/cecMan.c297
-rw-r--r--src/proof/cec/cecPat.c569
-rw-r--r--src/proof/cec/cecSeq.c448
-rw-r--r--src/proof/cec/cecSim.c53
-rw-r--r--src/proof/cec/cecSolve.c1023
-rw-r--r--src/proof/cec/cecSweep.c299
-rw-r--r--src/proof/cec/cecSynth.c380
-rw-r--r--src/proof/cec/module.make13
18 files changed, 8387 insertions, 0 deletions
diff --git a/src/proof/cec/cec.c b/src/proof/cec/cec.c
new file mode 100644
index 00000000..6968a599
--- /dev/null
+++ b/src/proof/cec/cec.c
@@ -0,0 +1,53 @@
+/**CFile****************************************************************
+
+ FileName [cec.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h
new file mode 100644
index 00000000..10b06c28
--- /dev/null
+++ b/src/proof/cec/cec.h
@@ -0,0 +1,233 @@
+/**CFile****************************************************************
+
+ FileName [cec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__aig__cec__cec_h
+#define ABC__aig__cec__cec_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// dynamic SAT parameters
+typedef struct Cec_ParSat_t_ Cec_ParSat_t;
+struct Cec_ParSat_t_
+{
+ int nBTLimit; // conflict limit at a node
+ int nSatVarMax; // the max number of SAT variables
+ int nCallsRecycle; // calls to perform before recycling SAT solver
+ int fNonChrono; // use non-chronological backtracling (for circuit SAT only)
+ int fPolarFlip; // flops polarity of variables
+ int fCheckMiter; // the circuit is the miter
+// int fFirstStop; // stop on the first sat output
+ int fLearnCls; // perform clause learning
+ int fVerbose; // verbose stats
+};
+
+// simulation parameters
+typedef struct Cec_ParSim_t_ Cec_ParSim_t;
+struct Cec_ParSim_t_
+{
+ int nWords; // the number of simulation words
+ int nFrames; // the number of simulation frames
+ int nRounds; // the number of simulation rounds
+ int nNonRefines; // the max number of rounds without refinement
+ int TimeLimit; // the runtime limit in seconds
+ int fDualOut; // miter with separate outputs
+ int fCheckMiter; // the circuit is the miter
+// int fFirstStop; // stop on the first sat output
+ int fSeqSimulate; // performs sequential simulation
+ int fLatchCorr; // consider only latch outputs
+ int fConstCorr; // consider only constants
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
+// semiformal parameters
+typedef struct Cec_ParSmf_t_ Cec_ParSmf_t;
+struct Cec_ParSmf_t_
+{
+ int nWords; // the number of simulation words
+ int nRounds; // the number of simulation rounds
+ int nFrames; // the max number of time frames
+ int nNonRefines; // the max number of rounds without refinement
+ int nMinOutputs; // the min outputs to accumulate
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+ int fDualOut; // miter with separate outputs
+ int fCheckMiter; // the circuit is the miter
+// int fFirstStop; // stop on the first sat output
+ int fVerbose; // verbose stats
+};
+
+// combinational SAT sweeping parameters
+typedef struct Cec_ParFra_t_ Cec_ParFra_t;
+struct Cec_ParFra_t_
+{
+ int nWords; // the number of simulation words
+ int nRounds; // the number of simulation rounds
+ int nItersMax; // the maximum number of iterations of SAT sweeping
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+ int nLevelMax; // restriction on the level nodes to be swept
+ int nDepthMax; // the depth in terms of steps of speculative reduction
+ int fRewriting; // enables AIG rewriting
+ int fCheckMiter; // the circuit is the miter
+// int fFirstStop; // stop on the first sat output
+ int fDualOut; // miter with separate outputs
+ int fColorDiff; // miter with separate outputs
+ int fSatSweeping; // enable SAT sweeping
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+ int iOutFail; // the failed output
+};
+
+// combinational equivalence checking parameters
+typedef struct Cec_ParCec_t_ Cec_ParCec_t;
+struct Cec_ParCec_t_
+{
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+// int fFirstStop; // stop on the first sat output
+ int fUseSmartCnf; // use smart CNF computation
+ int fRewriting; // enables AIG rewriting
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+ int iOutFail; // the number of failed output
+};
+
+// sequential register correspodence parameters
+typedef struct Cec_ParCor_t_ Cec_ParCor_t;
+struct Cec_ParCor_t_
+{
+ int nWords; // the number of simulation words
+ int nRounds; // the number of simulation rounds
+ int nFrames; // the number of time frames
+ int nPrefix; // the number of time frames in the prefix
+ int nBTLimit; // conflict limit at a node
+ int nLevelMax; // (scorr only) the max number of levels
+ int nStepsMax; // (scorr only) the max number of induction steps
+ int fLatchCorr; // consider only latch outputs
+ int fConstCorr; // consider only constants
+ int fUseRings; // use rings
+ int fMakeChoices; // use equilvaences as choices
+ int fUseCSat; // use circuit-based solver
+// int fFirstStop; // stop on the first sat output
+ int fUseSmartCnf; // use smart CNF computation
+ int fVerboseFlops; // verbose stats
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+ // callback
+ void * pData;
+ void * pFunc;
+};
+
+// sequential register correspodence parameters
+typedef struct Cec_ParChc_t_ Cec_ParChc_t;
+struct Cec_ParChc_t_
+{
+ int nWords; // the number of simulation words
+ int nRounds; // the number of simulation rounds
+ int nBTLimit; // conflict limit at a node
+ int fUseRings; // use rings
+ int fUseCSat; // use circuit-based solver
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
+// sequential synthesis parameters
+typedef struct Cec_ParSeq_t_ Cec_ParSeq_t;
+struct Cec_ParSeq_t_
+{
+ int fUseLcorr; // enables latch correspondence
+ int fUseScorr; // enables signal correspondence
+ int nBTLimit; // (scorr/lcorr) conflict limit at a node
+ int nFrames; // (scorr/lcorr) the number of timeframes
+ int nLevelMax; // (scorr only) the max number of levels
+ int fConsts; // (scl only) merging constants
+ int fEquivs; // (scl only) merging equivalences
+ int fUseMiniSat; // enables MiniSat in lcorr/scorr
+ int nMinDomSize; // the size of minimum clock domain
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cecCec.c ==========================================================*/
+extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars );
+extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
+/*=== cecChoice.c ==========================================================*/
+extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars );
+/*=== cecCorr.c ==========================================================*/
+extern int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars );
+extern Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars );
+/*=== cecCore.c ==========================================================*/
+extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p );
+extern void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p );
+extern void Cec_ManSmfSetDefaultParams( Cec_ParSmf_t * p );
+extern void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p );
+extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p );
+extern void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p );
+extern void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p );
+extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars );
+extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars );
+extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars );
+/*=== cecSeq.c ==========================================================*/
+extern int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex );
+extern int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars );
+extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig );
+/*=== cecSynth.c ==========================================================*/
+extern int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p );
+extern int Cec_SeqReadVerbose( Cec_ParSeq_t * p );
+extern void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * pPars );
+extern int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars );
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
new file mode 100644
index 00000000..1460ba91
--- /dev/null
+++ b/src/proof/cec/cecCec.c
@@ -0,0 +1,373 @@
+/**CFile****************************************************************
+
+ FileName [cecCec.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Integrated combinatinal equivalence checker.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+#include "src/proof/fra/fra.h"
+#include "src/aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Saves the input pattern with the given number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues )
+{
+ int i;
+ assert( p->pCexComb == NULL );
+ p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char,
+ sizeof(Abc_Cex_t) + sizeof(unsigned) * Abc_BitWordNum(Gia_ManCiNum(p)) );
+ p->pCexComb->iPo = iOut;
+ p->pCexComb->nPis = Gia_ManCiNum(p);
+ p->pCexComb->nBits = Gia_ManCiNum(p);
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ if ( pValues[i] )
+ Abc_InfoSetBit( p->pCexComb->pData, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interface to the old CEC engine]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail )
+{
+// extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose );
+ extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs );
+ Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter );
+ Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp, 0 );
+ int RetValue, iOut, nOuts, clkTotal = clock();
+ if ( piOutFail )
+ *piOutFail = -1;
+ Gia_ManStop( pTemp );
+ // run CEC on this miter
+ RetValue = Fra_FraigCec( &pMiterCec, 10000000, fVerbose );
+ // report the miter
+ if ( RetValue == 1 )
+ {
+ Abc_Print( 1, "Networks are equivalent. " );
+Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ else if ( RetValue == 0 )
+ {
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ if ( pMiterCec->pData == NULL )
+ Abc_Print( 1, "Counter-example is not available.\n" );
+ else
+ {
+ iOut = Ssw_SecCexResimulate( pMiterCec, (int *)pMiterCec->pData, &nOuts );
+ if ( iOut == -1 )
+ Abc_Print( 1, "Counter-example verification has failed.\n" );
+ else
+ {
+// Aig_Obj_t * pObj = Aig_ManPo(pMiterCec, iOut);
+// Aig_Obj_t * pFan = Aig_ObjFanin0(pObj);
+ Abc_Print( 1, "Primary output %d has failed", iOut );
+ if ( nOuts-1 >= 0 )
+ Abc_Print( 1, ", along with other %d incorrect outputs", nOuts-1 );
+ Abc_Print( 1, ".\n" );
+ if ( piOutFail )
+ *piOutFail = iOut;
+ }
+ Cec_ManTransformPattern( pMiter, iOut, (int *)pMiterCec->pData );
+ }
+ }
+ else
+ {
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ fflush( stdout );
+ Aig_ManStop( pMiterCec );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars )
+{
+ int fDumpUndecided = 0;
+ Cec_ParFra_t ParsFra, * pParsFra = &ParsFra;
+ Gia_Man_t * p, * pNew;
+ int RetValue, clk = clock();
+ double clkTotal = clock();
+ // preprocess
+ p = Gia_ManDup( pInit );
+ Gia_ManEquivFixOutputPairs( p );
+ p = Gia_ManCleanup( pNew = p );
+ Gia_ManStop( pNew );
+ // sweep for equivalences
+ Cec_ManFraSetDefaultParams( pParsFra );
+ pParsFra->nItersMax = 1000;
+ pParsFra->nBTLimit = pPars->nBTLimit;
+ pParsFra->TimeLimit = pPars->TimeLimit;
+ pParsFra->fVerbose = pPars->fVerbose;
+ pParsFra->fCheckMiter = 1;
+ pParsFra->fDualOut = 1;
+ pNew = Cec_ManSatSweeping( p, pParsFra );
+ pPars->iOutFail = pParsFra->iOutFail;
+ // update
+ pInit->pCexComb = p->pCexComb; p->pCexComb = NULL;
+ Gia_ManStop( p );
+ p = pInit;
+ // continue
+ if ( pNew == NULL )
+ {
+ if ( p->pCexComb != NULL )
+ {
+ 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 );
+ return 0;
+ }
+ p = Gia_ManDup( pInit );
+ Gia_ManEquivFixOutputPairs( p );
+ p = Gia_ManCleanup( pNew = p );
+ Gia_ManStop( pNew );
+ pNew = p;
+ }
+ if ( Gia_ManAndNum(pNew) == 0 )
+ {
+ Gia_Obj_t * pObj1, * pObj2;
+ int i;
+ Gia_ManForEachPo( pNew, pObj1, i )
+ {
+ pObj2 = Gia_ManPo( pNew, ++i );
+ if ( Gia_ObjChild0(pObj1) != Gia_ObjChild0(pObj2) )
+ {
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. Outputs %d trivially differ. ", i/2 );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ Gia_ManStop( pNew );
+ pPars->iOutFail = i/2;
+ return 0;
+ }
+ }
+ Abc_Print( 1, "Networks are equivalent. " );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ Gia_ManStop( pNew );
+ return 1;
+ }
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "Networks are UNDECIDED after the new CEC engine. " );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ if ( fDumpUndecided )
+ {
+ ABC_FREE( pNew->pReprs );
+ ABC_FREE( pNew->pNexts );
+ Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 );
+ Abc_Print( 1, "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" );
+ }
+ if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit )
+ {
+ Gia_ManStop( pNew );
+ return -1;
+ }
+ // call other solver
+ if ( pPars->fVerbose )
+ Abc_Print( 1, "Calling the old CEC engine.\n" );
+ fflush( stdout );
+ RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose, &pPars->iOutFail );
+ p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL;
+ if ( p->pCexComb && !Gia_ManVerifyCex( p, p->pCexComb, 1 ) )
+ Abc_Print( 1, "Counter-example simulation has failed.\n" );
+ Gia_ManStop( pNew );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine applied to two circuits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ Gia_Man_t * pMiter;
+ int RetValue;
+ Cec_ManCecSetDefaultParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pMiter = Gia_ManMiter( p0, p1, 1, 0, pPars->fVerbose );
+ if ( pMiter == NULL )
+ return -1;
+ RetValue = Cec_ManVerify( pMiter, pPars );
+ p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL;
+ Gia_ManStop( pMiter );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [New CEC engine applied to two circuits.]
+
+ Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided.
+ Counter-example is returned in the first manager as pAig0->pSeqModel.
+ The format is given in Abc_Cex_t (file "abc\src\aig\gia\gia.h").]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose )
+{
+ Gia_Man_t * p0, * p1, * pTemp;
+ int RetValue;
+
+ p0 = Gia_ManFromAig( pAig0 );
+ p0 = Gia_ManCleanup( pTemp = p0 );
+ Gia_ManStop( pTemp );
+
+ p1 = Gia_ManFromAig( pAig1 );
+ p1 = Gia_ManCleanup( pTemp = p1 );
+ Gia_ManStop( pTemp );
+
+ RetValue = Cec_ManVerifyTwo( p0, p1, fVerbose );
+ pAig0->pSeqModel = p0->pCexComb; p0->pCexComb = NULL;
+ Gia_ManStop( p0 );
+ Gia_ManStop( p1 );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implementation of new signal correspodence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Cec_LatchCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat )
+{
+ Gia_Man_t * pGia;
+ Cec_ParCor_t CorPars, * pCorPars = &CorPars;
+ Cec_ManCorSetDefaultParams( pCorPars );
+ pCorPars->fLatchCorr = 1;
+ pCorPars->fUseCSat = fUseCSat;
+ pCorPars->nBTLimit = nConfs;
+ pGia = Gia_ManFromAigSimple( pAig );
+ Cec_ManLSCorrespondenceClasses( pGia, pCorPars );
+ Gia_ManReprToAigRepr( pAig, pGia );
+ Gia_ManStop( pGia );
+ return Aig_ManDupSimple( pAig );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implementation of new signal correspodence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Cec_SignalCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat )
+{
+ Gia_Man_t * pGia;
+ Cec_ParCor_t CorPars, * pCorPars = &CorPars;
+ Cec_ManCorSetDefaultParams( pCorPars );
+ pCorPars->fUseCSat = fUseCSat;
+ pCorPars->nBTLimit = nConfs;
+ pGia = Gia_ManFromAigSimple( pAig );
+ Cec_ManLSCorrespondenceClasses( pGia, pCorPars );
+ Gia_ManReprToAigRepr( pAig, pGia );
+ Gia_ManStop( pGia );
+ return Aig_ManDupSimple( pAig );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implementation of fraiging.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Cec_FraigCombinational( Aig_Man_t * pAig, int nConfs, int fVerbose )
+{
+ Gia_Man_t * pGia;
+ Cec_ParFra_t FraPars, * pFraPars = &FraPars;
+ Cec_ManFraSetDefaultParams( pFraPars );
+ pFraPars->fSatSweeping = 1;
+ pFraPars->nBTLimit = nConfs;
+ pFraPars->nItersMax = 20;
+ pFraPars->fVerbose = fVerbose;
+ pGia = Gia_ManFromAigSimple( pAig );
+ Cec_ManSatSweeping( pGia, pFraPars );
+ Gia_ManReprToAigRepr( pAig, pGia );
+ Gia_ManStop( pGia );
+ return Aig_ManDupSimple( pAig );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecChoice.c b/src/proof/cec/cecChoice.c
new file mode 100644
index 00000000..3ddb975e
--- /dev/null
+++ b/src/proof/cec/cecChoice.c
@@ -0,0 +1,409 @@
+/**CFile****************************************************************
+
+ FileName [cecChoice.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Computation of structural choices.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecChoice.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+#include "src/aig/gia/giaAig.h"
+#include "src/proof/dch/dch.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Cec_ManCombSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj );
+
+extern int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore );
+extern int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes the real value of the literal w/o spec reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cec_ManCombSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec_ManCombSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Cec_ManCombSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively performs speculative reduction for the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManCombSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr;
+ if ( ~pObj->Value )
+ return;
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Cec_ManCombSpecReduce_rec( pNew, p, pRepr );
+ pObj->Value = Abc_LitNotCond( pRepr->Value, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ return;
+ }
+ pObj->Value = Cec_ManCombSpecReal( pNew, p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives SRM for signal correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManCombSpecReduce( Gia_Man_t * p, Vec_Int_t ** pvOutputs, int fRings )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int i, iPrev, iObj, iPrevNew, iObjNew;
+ assert( p->pReprs != NULL );
+ Gia_ManSetPhase( p );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ *pvOutputs = Vec_IntAlloc( 1000 );
+ vXorLits = Vec_IntAlloc( 1000 );
+ if ( fRings )
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsConst( p, i ) )
+ {
+ iObjNew = Cec_ManCombSpecReal( pNew, p, pObj );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) );
+ if ( iObjNew != 0 )
+ {
+ Vec_IntPush( *pvOutputs, 0 );
+ Vec_IntPush( *pvOutputs, i );
+ Vec_IntPush( vXorLits, iObjNew );
+ }
+ }
+ else if ( Gia_ObjIsHead( p, i ) )
+ {
+ iPrev = i;
+ Gia_ClassForEachObj1( p, i, iObj )
+ {
+ iPrevNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iPrev) );
+ iObjNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iObj) );
+ iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Abc_LitNot(iObjNew)) );
+ }
+ iPrev = iObj;
+ }
+ iObj = i;
+ iPrevNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iPrev) );
+ iObjNew = Cec_ManCombSpecReal( pNew, p, Gia_ManObj(p, iObj) );
+ iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Abc_LitNot(iObjNew)) );
+ }
+ }
+ }
+ }
+ else
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iPrevNew = Gia_ObjIsConst(p, i)? 0 : Cec_ManCombSpecReal( pNew, p, pRepr );
+ iObjNew = Cec_ManCombSpecReal( pNew, p, pObj );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ if ( iPrevNew != iObjNew )
+ {
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) );
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) );
+ }
+ }
+ }
+ Vec_IntForEachEntry( vXorLits, iObjNew, i )
+ Gia_ManAppendCo( pNew, iObjNew );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars )
+{
+ int nItersMax = 1000;
+ Vec_Str_t * vStatus;
+ Vec_Int_t * vOutputs;
+ Vec_Int_t * vCexStore;
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Cec_ManSim_t * pSim;
+ Gia_Man_t * pSrm;
+ int r, RetValue;
+ int clkSat = 0, clkSim = 0, clkSrm = 0, clkTotal = clock();
+ int clk2, clk = clock();
+ ABC_FREE( pAig->pReprs );
+ ABC_FREE( pAig->pNexts );
+ Gia_ManRandom( 1 );
+ // prepare simulation manager
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nFrames = pPars->nRounds;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pParsSim->fLatchCorr = 0;
+ pParsSim->fSeqSimulate = 0;
+ // create equivalence classes of registers
+ pSim = Cec_ManSimStart( pAig, pParsSim );
+ Cec_ManSimClassesPrepare( pSim, -1 );
+ Cec_ManSimClassesRefine( pSim );
+ // prepare SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVerbose;
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Ring = %d. CSat = %d.\n",
+ Gia_ManObjNum(pAig), Gia_ManAndNum(pAig), pPars->nBTLimit, pPars->fUseRings, pPars->fUseCSat );
+ Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk );
+ }
+ // perform refinement of equivalence classes
+ for ( r = 0; r < nItersMax; r++ )
+ {
+ clk = clock();
+ // perform speculative reduction
+ clk2 = clock();
+ pSrm = Cec_ManCombSpecReduce( pAig, &vOutputs, pPars->fUseRings );
+ assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManCiNum(pSrm) == Gia_ManCiNum(pAig) );
+ clkSrm += clock() - clk2;
+ if ( Gia_ManCoNum(pSrm) == 0 )
+ {
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk );
+ Vec_IntFree( vOutputs );
+ Gia_ManStop( pSrm );
+ break;
+ }
+//Gia_DumpAiger( pSrm, "choicesrm", r, 2 );
+ // found counter-examples to speculation
+ clk2 = clock();
+ if ( pPars->fUseCSat )
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ else
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ Gia_ManStop( pSrm );
+ clkSat += clock() - clk2;
+ if ( Vec_IntSize(vCexStore) == 0 )
+ {
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk );
+ Vec_IntFree( vCexStore );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+ break;
+ }
+ // refine classes with these counter-examples
+ clk2 = clock();
+ RetValue = Cec_ManResimulateCounterExamplesComb( pSim, vCexStore );
+ Vec_IntFree( vCexStore );
+ clkSim += clock() - clk2;
+ Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+//Gia_ManEquivPrintClasses( pAig, 1, 0 );
+ }
+ // check the overflow
+ if ( r == nItersMax )
+ Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" );
+ Cec_ManSimStop( pSim );
+ clkTotal = clock() - clkTotal;
+ // report the results
+ if ( pPars->fVerbose )
+ {
+ Abc_PrintTimeP( 1, "Srm ", clkSrm, clkTotal );
+ Abc_PrintTimeP( 1, "Sat ", clkSat, clkTotal );
+ Abc_PrintTimeP( 1, "Sim ", clkSim, clkTotal );
+ Abc_PrintTimeP( 1, "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal );
+ Abc_PrintTime( 1, "TOTAL", clkTotal );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes choices for the vector of AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManChoiceComputationVec( Gia_Man_t * pGia, int nGias, Cec_ParChc_t * pPars )
+{
+ Gia_Man_t * pNew;
+ int RetValue;
+ // compute equivalences of the miter
+// pMiter = Gia_ManChoiceMiter( vGias );
+// Gia_ManSetRegNum( pMiter, 0 );
+ RetValue = Cec_ManChoiceComputation_int( pGia, pPars );
+ // derive AIG with choices
+ pNew = Gia_ManEquivToChoices( pGia, nGias );
+ Gia_ManHasChoices( pNew );
+// Gia_ManStop( pMiter );
+ // report the results
+ if ( pPars->fVerbose )
+ {
+// Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+// Gia_ManAndNum(pAig), Gia_ManAndNum(pNew),
+// 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1),
+// Gia_ManRegNum(pAig), Gia_ManRegNum(pNew),
+// 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) );
+ }
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes choices for one AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pParsChc )
+{
+// extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars );
+ Dch_Pars_t Pars, * pPars = &Pars;
+ Aig_Man_t * pMan, * pManNew;
+ Gia_Man_t * pGia;
+ if ( 0 )
+ {
+ pGia = Cec_ManChoiceComputationVec( pAig, 3, pParsChc );
+ }
+ else
+ {
+ pMan = Gia_ManToAig( pAig, 0 );
+ Dch_ManSetDefaultParams( pPars );
+ pPars->fUseGia = 1;
+ pPars->nBTLimit = pParsChc->nBTLimit;
+ pPars->fUseCSat = pParsChc->fUseCSat;
+ pPars->fVerbose = pParsChc->fVerbose;
+ pManNew = Dar_ManChoiceNew( pMan, pPars );
+ pGia = Gia_ManFromAig( pManNew );
+ Aig_ManStop( pManNew );
+// Aig_ManStop( pMan );
+ }
+ return pGia;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of AIGs with choices.]
+
+ Description [Takes several AIGs and performs choicing.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars )
+{
+ Cec_ParChc_t ParsChc, * pParsChc = &ParsChc;
+ Aig_Man_t * pAig;
+ if ( pPars->fVerbose )
+ Abc_PrintTime( 1, "Synthesis time", pPars->timeSynth );
+ Cec_ManChcSetDefaultParams( pParsChc );
+ pParsChc->nBTLimit = pPars->nBTLimit;
+ pParsChc->fUseCSat = pPars->fUseCSat;
+ if ( pParsChc->fUseCSat && pParsChc->nBTLimit > 100 )
+ pParsChc->nBTLimit = 100;
+ pParsChc->fVerbose = pPars->fVerbose;
+ pGia = Cec_ManChoiceComputationVec( pGia, 3, pParsChc );
+ Gia_ManSetRegNum( pGia, Gia_ManRegNum(pGia) );
+ pAig = Gia_ManToAig( pGia, 1 );
+ Gia_ManStop( pGia );
+ return pAig;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecClass.c b/src/proof/cec/cecClass.c
new file mode 100644
index 00000000..46e585a9
--- /dev/null
+++ b/src/proof/cec/cecClass.c
@@ -0,0 +1,931 @@
+/**CFile****************************************************************
+
+ FileName [cecClass.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Equivalence class refinement.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; }
+static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; }
+
+static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of one node with constant 0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimCompareConst( unsigned * p, int nWords )
+{
+ int w;
+ if ( p[0] & 1 )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != ~0 )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != 0 )
+ return 0;
+ return 1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords )
+{
+ int w;
+ if ( (p0[0] & 1) == (p1[0] & 1) )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != p1[w] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != ~p1[w] )
+ return 0;
+ return 1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of the first non-equal bit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords )
+{
+ int w;
+ if ( p[0] & 1 )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != ~0 )
+ return 32*w + Gia_WordFindFirstBit( ~p[w] );
+ return -1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != 0 )
+ return 32*w + Gia_WordFindFirstBit( p[w] );
+ return -1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords )
+{
+ int w;
+ if ( (p0[0] & 1) == (p1[0] & 1) )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != p1[w] )
+ return 32*w + Gia_WordFindFirstBit( p0[w] ^ p1[w] );
+ return -1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != ~p1[w] )
+ return 32*w + Gia_WordFindFirstBit( p0[w] ^ ~p1[w] );
+ return -1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of the first non-equal bit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimCompareConstScore( unsigned * p, int nWords, int * pScores )
+{
+ int w, b;
+ if ( p[0] & 1 )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != ~0 )
+ for ( b = 0; b < 32; b++ )
+ if ( ((~p[w]) >> b ) & 1 )
+ pScores[32*w + b]++;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p[w] != 0 )
+ for ( b = 0; b < 32; b++ )
+ if ( ((p[w]) >> b ) & 1 )
+ pScores[32*w + b]++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimCompareEqualScore( unsigned * p0, unsigned * p1, int nWords, int * pScores )
+{
+ int w, b;
+ if ( (p0[0] & 1) == (p1[0] & 1) )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != p1[w] )
+ for ( b = 0; b < 32; b++ )
+ if ( ((p0[w] ^ p1[w]) >> b ) & 1 )
+ pScores[32*w + b]++;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( p0[w] != ~p1[w] )
+ for ( b = 0; b < 32; b++ )
+ if ( ((p0[w] ^ ~p1[w]) >> b ) & 1 )
+ pScores[32*w + b]++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass )
+{
+ int Repr = GIA_VOID, EntPrev = -1, Ent, i;
+ assert( Vec_IntSize(vClass) > 0 );
+ Vec_IntForEachEntry( vClass, Ent, i )
+ {
+ if ( i == 0 )
+ {
+ Repr = Ent;
+ Gia_ObjSetRepr( p, Ent, GIA_VOID );
+ EntPrev = Ent;
+ }
+ else
+ {
+ assert( Repr < Ent );
+ Gia_ObjSetRepr( p, Ent, Repr );
+ Gia_ObjSetNext( p, EntPrev, Ent );
+ EntPrev = Ent;
+ }
+ }
+ Gia_ObjSetNext( p, EntPrev, 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i )
+{
+ unsigned * pSim0, * pSim1;
+ int Ent;
+ Vec_IntClear( p->vClassOld );
+ Vec_IntClear( p->vClassNew );
+ Vec_IntPush( p->vClassOld, i );
+ pSim0 = Cec_ObjSim(p, i);
+ Gia_ClassForEachObj1( p->pAig, i, Ent )
+ {
+ pSim1 = Cec_ObjSim(p, Ent);
+ if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) )
+ Vec_IntPush( p->vClassOld, Ent );
+ else
+ {
+ Vec_IntPush( p->vClassNew, Ent );
+ if ( p->pBestState )
+ Cec_ManSimCompareEqualScore( pSim0, pSim1, p->nWords, p->pScores );
+ }
+ }
+ if ( Vec_IntSize( p->vClassNew ) == 0 )
+ return 0;
+ Cec_ManSimClassCreate( p->pAig, p->vClassOld );
+ Cec_ManSimClassCreate( p->pAig, p->vClassNew );
+ if ( Vec_IntSize(p->vClassNew) > 1 )
+ return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i )
+{
+ int iRepr, Ent;
+ if ( Gia_ObjIsConst(p->pAig, i) )
+ {
+ Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
+ return 1;
+ }
+ if ( !Gia_ObjIsClass(p->pAig, i) )
+ return 0;
+ assert( Gia_ObjIsClass(p->pAig, i) );
+ iRepr = Gia_ObjRepr( p->pAig, i );
+ if ( iRepr == GIA_VOID )
+ iRepr = i;
+ // collect nodes
+ Vec_IntClear( p->vClassOld );
+ Vec_IntClear( p->vClassNew );
+ Gia_ClassForEachObj( p->pAig, iRepr, Ent )
+ {
+ if ( Ent == i )
+ Vec_IntPush( p->vClassNew, Ent );
+ else
+ Vec_IntPush( p->vClassOld, Ent );
+ }
+ assert( Vec_IntSize( p->vClassNew ) == 1 );
+ Cec_ManSimClassCreate( p->pAig, p->vClassOld );
+ Cec_ManSimClassCreate( p->pAig, p->vClassNew );
+ assert( !Gia_ObjIsClass(p->pAig, i) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash key of the simuation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned uHash = 0;
+ int i;
+ if ( pSim[0] & 1 )
+ for ( i = 0; i < nWords; i++ )
+ uHash ^= ~pSim[i] * s_Primes[i & 0xf];
+ else
+ for ( i = 0; i < nWords; i++ )
+ uHash ^= pSim[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resets pointers to the simulation memory.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimMemRelink( Cec_ManSim_t * p )
+{
+ unsigned * pPlace, Ent;
+ pPlace = (unsigned *)&p->MemFree;
+ for ( Ent = p->nMems * (p->nWords + 1);
+ Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc;
+ Ent += p->nWords + 1 )
+ {
+ *pPlace = Ent;
+ pPlace = p->pMems + Ent;
+ }
+ *pPlace = 0;
+ p->nWordsOld = p->nWords;
+}
+
+/**Function*************************************************************
+
+ Synopsis [References simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i )
+{
+ unsigned * pSim;
+ assert( p->pSimInfo[i] == 0 );
+ if ( p->MemFree == 0 )
+ {
+ if ( p->nWordsAlloc == 0 )
+ {
+ assert( p->pMems == NULL );
+ p->nWordsAlloc = (1<<17); // -> 1Mb
+ p->nMems = 1;
+ }
+ p->nWordsAlloc *= 2;
+ p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc );
+ Cec_ManSimMemRelink( p );
+ }
+ p->pSimInfo[i] = p->MemFree;
+ pSim = p->pMems + p->MemFree;
+ p->MemFree = pSim[0];
+ pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) );
+ p->nMems++;
+ if ( p->nMemsMax < p->nMems )
+ p->nMemsMax = p->nMems;
+ return pSim;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dereferences simulaton info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i )
+{
+ unsigned * pSim;
+ assert( p->pSimInfo[i] > 0 );
+ pSim = p->pMems + p->pSimInfo[i];
+ if ( --pSim[0] == 0 )
+ {
+ pSim[0] = p->MemFree;
+ p->MemFree = p->pSimInfo[i];
+ p->pSimInfo[i] = 0;
+ p->nMems--;
+ }
+ return pSim;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines nodes belonging to candidate constant class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined )
+{
+ unsigned * pSim;
+ int * pTable, nTableSize, i, k, Key;
+ if ( Vec_IntSize(vRefined) == 0 )
+ return;
+ nTableSize = Abc_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 );
+ pTable = ABC_CALLOC( int, nTableSize );
+ Vec_IntForEachEntry( vRefined, i, k )
+ {
+ pSim = Cec_ObjSim( p, i );
+ assert( !Cec_ManSimCompareConst( pSim, p->nWords ) );
+ Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize );
+ if ( pTable[Key] == 0 )
+ {
+ assert( Gia_ObjRepr(p->pAig, i) == 0 );
+ assert( Gia_ObjNext(p->pAig, i) == 0 );
+ Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
+ }
+ else
+ {
+ Gia_ObjSetNext( p->pAig, pTable[Key], i );
+ Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) );
+ if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID )
+ Gia_ObjSetRepr( p->pAig, i, pTable[Key] );
+ assert( Gia_ObjRepr(p->pAig, i) > 0 );
+ }
+ pTable[Key] = i;
+ }
+ Vec_IntForEachEntry( vRefined, i, k )
+ {
+ if ( Gia_ObjIsHead( p->pAig, i ) )
+ Cec_ManSimClassRefineOne( p, i );
+ }
+ Vec_IntForEachEntry( vRefined, i, k )
+ Cec_ManSimSimDeref( p, i );
+ ABC_FREE( pTable );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Saves the input pattern with the given number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat )
+{
+ unsigned * pInfo;
+ int i;
+ assert( p->pCexComb == NULL );
+ assert( iPat >= 0 && iPat < 32 * p->nWords );
+ p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char,
+ sizeof(Abc_Cex_t) + sizeof(unsigned) * Abc_BitWordNum(Gia_ManCiNum(p->pAig)) );
+ p->pCexComb->iPo = p->iOut;
+ p->pCexComb->nPis = Gia_ManCiNum(p->pAig);
+ p->pCexComb->nBits = Gia_ManCiNum(p->pAig);
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i );
+ if ( Abc_InfoHasBit( pInfo, iPat ) )
+ Abc_InfoSetBit( p->pCexComb->pData, i );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the best pattern using the scores.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimFindBestPattern( Cec_ManSim_t * p )
+{
+ unsigned * pInfo;
+ int i, ScoreBest = 0, iPatBest = 1; // set the first pattern
+ // find the best pattern
+ for ( i = 0; i < 32 * p->nWords; i++ )
+ if ( ScoreBest < p->pScores[i] )
+ {
+ ScoreBest = p->pScores[i];
+ iPatBest = i;
+ }
+ // compare this with the available patterns - and save
+ if ( p->pBestState->iPo <= ScoreBest )
+ {
+ assert( p->pBestState->nRegs == Gia_ManRegNum(p->pAig) );
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i );
+ if ( Abc_InfoHasBit(p->pBestState->pData, i) != Abc_InfoHasBit(pInfo, iPatBest) )
+ Abc_InfoXorBit( p->pBestState->pData, i );
+ }
+ p->pBestState->iPo = ScoreBest;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if computation should stop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p )
+{
+ unsigned * pInfo, * pInfo2;
+ int i;
+ if ( !p->pPars->fCheckMiter )
+ return 0;
+ assert( p->vCoSimInfo != NULL );
+ // compare outputs with 0
+ if ( p->pPars->fDualOut )
+ {
+ assert( (Gia_ManPoNum(p->pAig) & 1) == 0 );
+ for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i );
+ pInfo2 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, ++i );
+ if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) )
+ {
+ if ( p->iOut == -1 )
+ {
+ p->iOut = i/2;
+ Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) );
+ }
+ if ( p->pCexes == NULL )
+ p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig)/2 );
+ if ( p->pCexes[i/2] == NULL )
+ {
+ p->nOuts++;
+ p->pCexes[i/2] = (void *)1;
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i );
+ if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) )
+ {
+ if ( p->iOut == -1 )
+ {
+ p->iOut = i;
+ Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) );
+ }
+ if ( p->pCexes == NULL )
+ p->pCexes = ABC_CALLOC( void *, Gia_ManPoNum(p->pAig) );
+ if ( p->pCexes[i] == NULL )
+ {
+ p->nOuts++;
+ p->pCexes[i] = (void *)1;
+ }
+ }
+ }
+ }
+ return p->pCexes != NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one round.]
+
+ Description [Returns the number of PO entry if failed; 0 otherwise.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
+{
+ Gia_Obj_t * pObj;
+ unsigned * pRes0, * pRes1, * pRes;
+ int i, k, w, Ent, iCiId = 0, iCoId = 0;
+ // prepare internal storage
+ if ( p->nWordsOld != p->nWords )
+ Cec_ManSimMemRelink( p );
+ p->nMemsMax = 0;
+ // allocate score counters
+ ABC_FREE( p->pScores );
+ if ( p->pBestState )
+ p->pScores = ABC_CALLOC( int, 32 * p->nWords );
+ // simulate nodes
+ Vec_IntClear( p->vRefinedC );
+ if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) )
+ {
+ pRes = Cec_ManSimSimRef( p, 0 );
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = 0;
+ }
+ Gia_ManForEachObj1( p->pAig, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ if ( Gia_ObjValue(pObj) == 0 )
+ {
+ iCiId++;
+ continue;
+ }
+ pRes = Cec_ManSimSimRef( p, i );
+ if ( vInfoCis )
+ {
+ pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, iCiId++ );
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = pRes0[w-1];
+ }
+ else
+ {
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = Gia_ManRandom( 0 );
+ }
+ // make sure the first pattern is always zero
+ pRes[1] ^= (pRes[1] & 1);
+ goto references;
+ }
+ if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin
+ {
+ pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
+ if ( vInfoCos )
+ {
+ pRes = (unsigned *)Vec_PtrEntry( vInfoCos, iCoId++ );
+ if ( Gia_ObjFaninC0(pObj) )
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w-1] = ~pRes0[w];
+ else
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w-1] = pRes0[w];
+ }
+ continue;
+ }
+ assert( Gia_ObjValue(pObj) );
+ pRes = Cec_ManSimSimRef( p, i );
+ pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
+ pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) );
+
+// Abc_Print( 1, "%d,%d ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) );
+
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = ~(pRes0[w] | pRes1[w]);
+ else
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = ~pRes0[w] & pRes1[w];
+ }
+ else
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = pRes0[w] & ~pRes1[w];
+ else
+ for ( w = 1; w <= p->nWords; w++ )
+ pRes[w] = pRes0[w] & pRes1[w];
+ }
+
+references:
+ // if this node is candidate constant, collect it
+ if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) )
+ {
+ pRes[0]++;
+ Vec_IntPush( p->vRefinedC, i );
+ if ( p->pBestState )
+ Cec_ManSimCompareConstScore( pRes + 1, p->nWords, p->pScores );
+ }
+ // if the node belongs to a class, save it
+ if ( Gia_ObjIsClass(p->pAig, i) )
+ pRes[0]++;
+ // if this is the last node of the class, process it
+ if ( Gia_ObjIsTail(p->pAig, i) )
+ {
+ Vec_IntClear( p->vClassTemp );
+ Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent )
+ Vec_IntPush( p->vClassTemp, Ent );
+ Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) );
+ Vec_IntForEachEntry( p->vClassTemp, Ent, k )
+ Cec_ManSimSimDeref( p, Ent );
+ }
+ }
+
+ if ( p->pPars->fConstCorr )
+ {
+ Vec_IntForEachEntry( p->vRefinedC, i, k )
+ {
+ Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
+ Cec_ManSimSimDeref( p, i );
+ }
+ Vec_IntClear( p->vRefinedC );
+ }
+
+ if ( Vec_IntSize(p->vRefinedC) > 0 )
+ Cec_ManSimProcessRefined( p, p->vRefinedC );
+ assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) );
+ assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) );
+ assert( p->nMems == 1 );
+ if ( p->nMems != 1 )
+ Abc_Print( 1, "Cec_ManSimSimulateRound(): Memory management error!\n" );
+ if ( p->pPars->fVeryVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ if ( p->pBestState )
+ Cec_ManSimFindBestPattern( p );
+/*
+ if ( p->nMems > 1 ) {
+ for ( i = 1; i < p->nObjs; i++ )
+ if ( p->pSims[i] ) {
+ int x = 0;
+ }
+ }
+*/
+ return Cec_ManSimAnalyzeOutputs( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates simulation info for this round.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
+{
+ unsigned * pRes0, * pRes1;
+ int i, w;
+ if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 )
+ {
+ assert( vInfoCis && vInfoCos );
+ for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
+ {
+ pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = Gia_ManRandom( 0 );
+ }
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i );
+ pRes1 = (unsigned *)Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = pRes1[w];
+ }
+ }
+ else
+ {
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i );
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = Gia_ManRandom( 0 );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the bug is found.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pAig->pReprs == NULL );
+ // allocate representation
+ p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) );
+ p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
+ // create references
+ Gia_ManSetRefs( p->pAig );
+ // set starting representative of internal nodes to be constant 0
+ if ( p->pPars->fLatchCorr )
+ Gia_ManForEachObj( p->pAig, pObj, i )
+ Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
+ else if ( LevelMax == -1 )
+ Gia_ManForEachObj( p->pAig, pObj, i )
+ Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID );
+ else
+ {
+ Gia_ManLevelNum( p->pAig );
+ Gia_ManForEachObj( p->pAig, pObj, i )
+ Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) && Gia_ObjLevel(p->pAig,pObj) <= LevelMax) ? 0 : GIA_VOID );
+ Vec_IntFreeP( &p->pAig->vLevels );
+ }
+ // if sequential simulation, set starting representative of ROs to be constant 0
+ if ( p->pPars->fSeqSimulate )
+ Gia_ManForEachRo( p->pAig, pObj, i )
+ if ( pObj->Value )
+ Gia_ObjSetRepr( p->pAig, Gia_ObjId(p->pAig, pObj), 0 );
+ // perform simulation
+ p->nWords = 1;
+ do {
+ if ( p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ for ( i = 0; i < 4; i++ )
+ {
+ Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
+ }
+ p->nWords = 2 * p->nWords + 1;
+ }
+ while ( p->nWords <= p->pPars->nWords );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the bug is found.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimClassesRefine( Cec_ManSim_t * p )
+{
+ int i;
+ Gia_ManSetRefs( p->pAig );
+ p->nWords = p->pPars->nWords;
+ for ( i = 0; i < p->pPars->nRounds; i++ )
+ {
+ if ( (i % (p->pPars->nRounds / 5)) == 0 && p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
+ }
+ if ( p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecCore.c b/src/proof/cec/cecCore.c
new file mode 100644
index 00000000..bf41304b
--- /dev/null
+++ b/src/proof/cec/cecCore.c
@@ -0,0 +1,542 @@
+/**CFile****************************************************************
+
+ FileName [cecCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParSat_t) );
+ p->nBTLimit = 100; // conflict limit at a node
+ p->nSatVarMax = 2000; // the max number of SAT variables
+ p->nCallsRecycle = 200; // calls to perform before recycling SAT solver
+ p->fNonChrono = 0; // use non-chronological backtracling (for circuit SAT only)
+ p->fPolarFlip = 1; // flops polarity of variables
+ p->fCheckMiter = 0; // the circuit is the miter
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fLearnCls = 0; // perform clause learning
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function************ *************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimSetDefaultParams( Cec_ParSim_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParSim_t) );
+ p->nWords = 31; // the number of simulation words
+ p->nFrames = 100; // the number of simulation frames
+ p->nRounds = 20; // the max number of simulation rounds
+ p->nNonRefines = 3; // the max number of rounds without refinement
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fCheckMiter = 0; // the circuit is the miter
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fDualOut = 0; // miter with separate outputs
+ p->fConstCorr = 0; // consider only constants
+ p->fSeqSimulate = 0; // performs sequential simulation
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function************ *************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSmfSetDefaultParams( Cec_ParSmf_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParSmf_t) );
+ p->nWords = 31; // the number of simulation words
+ p->nRounds = 200; // the number of simulation rounds
+ p->nFrames = 200; // the max number of time frames
+ p->nNonRefines = 3; // the max number of rounds without refinement
+ p->nMinOutputs = 0; // the min outputs to accumulate
+ p->nBTLimit = 100; // conflict limit at a node
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fDualOut = 0; // miter with separate outputs
+ p->fCheckMiter = 0; // the circuit is the miter
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function************ *************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParFra_t) );
+ p->nWords = 15; // the number of simulation words
+ p->nRounds = 15; // the number of simulation rounds
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->nItersMax = 10; // the maximum number of iterations of SAT sweeping
+ p->nBTLimit = 100; // conflict limit at a node
+ p->nLevelMax = 0; // restriction on the level of nodes to be swept
+ p->nDepthMax = 1; // the depth in terms of steps of speculative reduction
+ p->fRewriting = 0; // enables AIG rewriting
+ p->fCheckMiter = 0; // the circuit is the miter
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fDualOut = 0; // miter with separate outputs
+ p->fColorDiff = 0; // miter with separate outputs
+ p->fSatSweeping = 0; // enable SAT sweeping
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+ p->iOutFail = -1; // the failed output
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParCec_t) );
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->TimeLimit = 0; // the runtime limit in seconds
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fUseSmartCnf = 0; // use smart CNF computation
+ p->fRewriting = 0; // enables AIG rewriting
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+ p->iOutFail = -1; // the number of failed output
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParCor_t) );
+ p->nWords = 15; // the number of simulation words
+ p->nRounds = 15; // the number of simulation rounds
+ p->nFrames = 1; // the number of time frames
+ p->nBTLimit = 100; // conflict limit at a node
+ p->nLevelMax = -1; // (scorr only) the max number of levels
+ p->nStepsMax = -1; // (scorr only) the max number of induction steps
+ p->fLatchCorr = 0; // consider only latch outputs
+ p->fConstCorr = 0; // consider only constants
+ p->fUseRings = 1; // combine classes into rings
+ p->fUseCSat = 1; // use circuit-based solver
+// p->fFirstStop = 0; // stop on the first sat output
+ p->fUseSmartCnf = 0; // use smart CNF computation
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParChc_t) );
+ p->nWords = 15; // the number of simulation words
+ p->nRounds = 15; // the number of simulation rounds
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->fUseRings = 1; // use rings
+ p->fUseCSat = 0; // use circuit-based solver
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function*************************************************************
+
+ Synopsis [Core procedure for SAT sweeping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
+{
+ Gia_Man_t * pNew;
+ Cec_ManPat_t * pPat;
+ pPat = Cec_ManPatStart();
+ Cec_ManSatSolve( pPat, pAig, pPars );
+// pNew = Gia_ManDupDfsSkip( pAig );
+ pNew = Gia_ManDup( pAig );
+ Cec_ManPatStop( pPat );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Core procedure for simulation.]
+
+ Description [Returns 1 if refinement has happened.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSimulationOne( Gia_Man_t * pAig, Cec_ParSim_t * pPars )
+{
+ Cec_ManSim_t * pSim;
+ int RetValue = 0, clkTotal = clock();
+ pSim = Cec_ManSimStart( pAig, pPars );
+ if ( (pAig->pReprs == NULL && (RetValue = Cec_ManSimClassesPrepare( pSim, -1 ))) ||
+ (RetValue == 0 && (RetValue = Cec_ManSimClassesRefine( pSim ))) )
+ Abc_Print( 1, "The number of failed outputs of the miter = %6d. (Words = %4d. Frames = %4d.)\n",
+ pSim->nOuts, pPars->nWords, pPars->nFrames );
+ if ( pPars->fVerbose )
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ Cec_ManSimStop( pSim );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Core procedure for simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars )
+{
+ int r, nLitsOld, nLitsNew, nCountNoRef = 0, fStop = 0;
+ Gia_ManRandom( 1 );
+ if ( pPars->fSeqSimulate )
+ Abc_Print( 1, "Performing rounds of random simulation of %d frames with %d words.\n",
+ pPars->nRounds, pPars->nFrames, pPars->nWords );
+ nLitsOld = Gia_ManEquivCountLits( pAig );
+ for ( r = 0; r < pPars->nRounds; r++ )
+ {
+ if ( Cec_ManSimulationOne( pAig, pPars ) )
+ {
+ fStop = 1;
+ break;
+ }
+ // decide when to stop
+ nLitsNew = Gia_ManEquivCountLits( pAig );
+ if ( nLitsOld == 0 || nLitsOld > nLitsNew )
+ {
+ nLitsOld = nLitsNew;
+ nCountNoRef = 0;
+ }
+ else if ( ++nCountNoRef == pPars->nNonRefines )
+ {
+ r++;
+ break;
+ }
+ assert( nLitsOld == nLitsNew );
+ }
+// if ( pPars->fVerbose )
+ if ( r == pPars->nRounds || fStop )
+ Abc_Print( 1, "Random simulation is stopped after %d rounds.\n", r );
+ else
+ Abc_Print( 1, "Random simulation saturated after %d rounds.\n", r );
+ if ( pPars->fCheckMiter )
+ {
+ int nNonConsts = Cec_ManCountNonConstOutputs( pAig );
+ if ( nNonConsts )
+ Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Core procedure for SAT sweeping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
+{
+ int fOutputResult = 0;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Gia_Man_t * pIni, * pSrm, * pTemp;
+ Cec_ManFra_t * p;
+ Cec_ManSim_t * pSim;
+ Cec_ManPat_t * pPat;
+ int i, fTimeOut = 0, nMatches = 0, clk, clk2;
+ double clkTotal = clock();
+
+ // duplicate AIG and transfer equivalence classes
+ Gia_ManRandom( 1 );
+ pIni = Gia_ManDup(pAig);
+ pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL;
+ pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL;
+
+ // prepare the managers
+ // SAT sweeping
+ p = Cec_ManFraStart( pIni, pPars );
+ if ( pPars->fDualOut )
+ pPars->fColorDiff = 1;
+ // simulation
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nFrames = pPars->nRounds;
+ pParsSim->fCheckMiter = pPars->fCheckMiter;
+ pParsSim->fDualOut = pPars->fDualOut;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pSim = Cec_ManSimStart( p->pAig, pParsSim );
+ // SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVeryVerbose;
+ // simulation patterns
+ pPat = Cec_ManPatStart();
+ pPat->fVerbose = pPars->fVeryVerbose;
+
+ // start equivalence classes
+clk = clock();
+ if ( p->pAig->pReprs == NULL )
+ {
+ if ( Cec_ManSimClassesPrepare(pSim, -1) || Cec_ManSimClassesRefine(pSim) )
+ {
+ Gia_ManStop( p->pAig );
+ p->pAig = NULL;
+ goto finalize;
+ }
+ }
+p->timeSim += clock() - clk;
+ // perform solving
+ for ( i = 1; i <= pPars->nItersMax; i++ )
+ {
+ clk2 = clock();
+ nMatches = 0;
+ if ( pPars->fDualOut )
+ {
+ nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose );
+// p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig );
+// Gia_ManEquivTransform( p->pAig, 1 );
+ }
+ pSrm = Cec_ManFraSpecReduction( p );
+
+// Gia_WriteAiger( pSrm, "gia_srm.aig", 0, 0 );
+
+ if ( pPars->fVeryVerbose )
+ Gia_ManPrintStats( pSrm, 0 );
+ if ( Gia_ManCoNum(pSrm) == 0 )
+ {
+ Gia_ManStop( pSrm );
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Considered all available candidate equivalences.\n" );
+ if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) > 0 )
+ {
+ if ( pPars->fColorDiff )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Switching into reduced mode.\n" );
+ pPars->fColorDiff = 0;
+ }
+ else
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Switching into normal mode.\n" );
+ pPars->fDualOut = 0;
+ }
+ continue;
+ }
+ break;
+ }
+clk = clock();
+ Cec_ManSatSolve( pPat, pSrm, pParsSat );
+p->timeSat += clock() - clk;
+ if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) )
+ {
+ Gia_ManStop( pSrm );
+ Gia_ManStop( p->pAig );
+ p->pAig = NULL;
+ goto finalize;
+ }
+ Gia_ManStop( pSrm );
+
+ // update the manager
+ pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDualOut );
+ 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. ",
+ i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) );
+ Abc_PrintTime( 1, "Time", clock() - clk2 );
+ }
+ if ( Gia_ManAndNum(p->pAig) == 0 )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Network after reduction is empty.\n" );
+ break;
+ }
+ // check resource limits
+ if ( p->pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit )
+ {
+ fTimeOut = 1;
+ break;
+ }
+// if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved )
+ if ( p->nAllFailed > p->nAllProved + p->nAllDisproved )
+ {
+ if ( pParsSat->nBTLimit >= 10001 )
+ break;
+ if ( pPars->fSatSweeping )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Exceeded the limit on the number of conflicts (%d).\n", pParsSat->nBTLimit );
+ break;
+ }
+ pParsSat->nBTLimit *= 10;
+ if ( p->pPars->fVerbose )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Increasing conflict limit to %d.\n", pParsSat->nBTLimit );
+ if ( fOutputResult )
+ {
+ Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 );
+ Abc_Print( 1,"The result is written into file \"%s\".\n", "gia_cec_temp.aig" );
+ }
+ }
+ }
+ if ( pPars->fDualOut && pPars->fColorDiff && (Gia_ManAndNum(p->pAig) < 100000 || p->nAllProved + p->nAllDisproved < 10) )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Switching into reduced mode.\n" );
+ pPars->fColorDiff = 0;
+ }
+// if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) < 20000 )
+ else if ( pPars->fDualOut && (Gia_ManAndNum(p->pAig) < 20000 || p->nAllProved + p->nAllDisproved < 10) )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Switching into normal mode.\n" );
+ pPars->fColorDiff = 0;
+ pPars->fDualOut = 0;
+ }
+ }
+finalize:
+ if ( p->pPars->fVerbose && p->pAig )
+ {
+ Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ Gia_ManAndNum(pAig), Gia_ManAndNum(p->pAig),
+ 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(p->pAig))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1),
+ Gia_ManRegNum(pAig), Gia_ManRegNum(p->pAig),
+ 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(p->pAig))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) );
+ Abc_PrintTimeP( 1, "Sim ", p->timeSim, clock() - (int)clkTotal );
+ Abc_PrintTimeP( 1, "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal );
+ Abc_PrintTimeP( 1, "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal );
+ Abc_PrintTime( 1, "Time", (int)(clock() - clkTotal) );
+ }
+
+ pTemp = p->pAig; p->pAig = NULL;
+ if ( pTemp == NULL && pSim->iOut >= 0 )
+ {
+ Abc_Print( 1, "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut );
+ pPars->iOutFail = pSim->iOut;
+ }
+ else if ( pSim->pCexes )
+ Abc_Print( 1, "Disproved %d outputs of the miter.\n", pSim->nOuts );
+ if ( fTimeOut )
+ Abc_Print( 1, "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC );
+
+ pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL;
+ Cec_ManSimStop( pSim );
+ Cec_ManPatStop( pPat );
+ Cec_ManFraStop( p );
+ return pTemp;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c
new file mode 100644
index 00000000..6f3ce785
--- /dev/null
+++ b/src/proof/cec/cecCorr.c
@@ -0,0 +1,1137 @@
+/**CFile****************************************************************
+
+ FileName [cecCorr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Latch/signal correspondence computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecCorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes the real value of the literal w/o spec reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
+{
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f, nPrefix );
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f, nPrefix );
+ return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) );
+ }
+ if ( f == 0 )
+ {
+ assert( Gia_ObjIsRo(p, pObj) );
+ return Gia_ObjCopyF(p, f, pObj);
+ }
+ assert( f && Gia_ObjIsRo(p, pObj) );
+ pObj = Gia_ObjRoToRi( p, pObj );
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1, nPrefix );
+ return Gia_ObjFanin0CopyF( p, f-1, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively performs speculative reduction for the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
+{
+ Gia_Obj_t * pRepr;
+ int iLitNew;
+ if ( ~Gia_ObjCopyF(p, f, pObj) )
+ return;
+ if ( f >= nPrefix && (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f, nPrefix );
+ iLitNew = Abc_LitNotCond( Gia_ObjCopyF(p, f, pRepr), Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ Gia_ObjSetCopyF( p, f, pObj, iLitNew );
+ return;
+ }
+ assert( Gia_ObjIsCand(pObj) );
+ iLitNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix );
+ Gia_ObjSetCopyF( p, f, pObj, iLitNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives SRM for signal correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int f, i, iPrev, iObj, iPrevNew, iObjNew;
+ assert( nFrames > 0 );
+ assert( Gia_ManRegNum(p) > 0 );
+ assert( p->pReprs != NULL );
+ p->pCopies = ABC_FALLOC( int, (nFrames+fScorr)*Gia_ManObjNum(p) );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ObjSetCopyF( p, 0, Gia_ManConst0(p), 0 );
+ Gia_ManForEachRo( p, pObj, i )
+ Gia_ObjSetCopyF( p, 0, pObj, Gia_ManAppendCi(pNew) );
+ Gia_ManForEachRo( p, pObj, i )
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ Gia_ObjSetCopyF( p, 0, pObj, Gia_ObjCopyF(p, 0, pRepr) );
+ for ( f = 0; f < nFrames+fScorr; f++ )
+ {
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
+ }
+ *pvOutputs = Vec_IntAlloc( 1000 );
+ vXorLits = Vec_IntAlloc( 1000 );
+ if ( fRings )
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsConst( p, i ) )
+ {
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) );
+ if ( iObjNew != 0 )
+ {
+ Vec_IntPush( *pvOutputs, 0 );
+ Vec_IntPush( *pvOutputs, i );
+ Vec_IntPush( vXorLits, iObjNew );
+ }
+ }
+ else if ( Gia_ObjIsHead( p, i ) )
+ {
+ iPrev = i;
+ Gia_ClassForEachObj1( p, i, iObj )
+ {
+ iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
+ iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Abc_LitNot(iObjNew)) );
+ }
+ iPrev = iObj;
+ }
+ iObj = i;
+ iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
+ iPrevNew = Abc_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Abc_LitNot(iObjNew)) );
+ }
+ }
+ }
+ }
+ else
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ if ( iPrevNew != iObjNew )
+ {
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) );
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) );
+ }
+ }
+ }
+ Vec_IntForEachEntry( vXorLits, iObjNew, i )
+ Gia_ManAppendCo( pNew, iObjNew );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+ ABC_FREE( p->pCopies );
+//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives SRM for signal correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int fRings )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int f, i, iPrevNew, iObjNew;
+ assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix );
+ assert( Gia_ManRegNum(p) > 0 );
+ assert( p->pReprs != NULL );
+ p->pCopies = ABC_FALLOC( int, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p) );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( (nFrames+nPrefix) * Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Gia_ManAppendCi(pNew);
+ Gia_ObjSetCopyF( p, 0, pObj, 0 );
+ }
+ for ( f = 0; f < nFrames+nPrefix+fScorr; f++ )
+ {
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
+ }
+ *pvOutputs = Vec_IntAlloc( 1000 );
+ vXorLits = Vec_IntAlloc( 1000 );
+ for ( f = nPrefix; f < nFrames+nPrefix; f++ )
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, f, nPrefix );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix );
+ iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ if ( iPrevNew != iObjNew )
+ {
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) );
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) );
+ }
+ }
+ }
+ Vec_IntForEachEntry( vXorLits, iObjNew, i )
+ Gia_ManAppendCo( pNew, iObjNew );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+ ABC_FREE( p->pCopies );
+//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Initializes simulation info for lcorr/scorr counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops )
+{
+ unsigned * pInfo;
+ int k, w, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ assert( nFlops <= Vec_PtrSize(vInfo) );
+ for ( k = 0; k < nFlops; k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = 0;
+ }
+ for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Gia_ManRandom( 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remaps simulation info from SRM to the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrRemapSimInfo( Gia_Man_t * p, Vec_Ptr_t * vInfo )
+{
+ Gia_Obj_t * pObj, * pRepr;
+ unsigned * pInfoObj, * pInfoRepr;
+ int i, w, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ // skip ROs without representatives
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) )
+ continue;
+ pInfoObj = (unsigned *)Vec_PtrEntry( vInfo, i );
+ for ( w = 0; w < nWords; w++ )
+ assert( pInfoObj[w] == 0 );
+ // skip ROs with constant representatives
+ if ( Gia_ObjIsConst0(pRepr) )
+ continue;
+ assert( Gia_ObjIsRo(p, pRepr) );
+// Abc_Print( 1, "%d -> %d ", i, Gia_ObjId(p, pRepr) );
+ // transfer info from the representative
+ pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) );
+ for ( w = 0; w < nWords; w++ )
+ pInfoObj[w] = pInfoRepr[w];
+ }
+// Abc_Print( 1, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects information about remapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p )
+{
+ Vec_Int_t * vPairs;
+ Gia_Obj_t * pObj, * pRepr;
+ int i;
+ vPairs = Vec_IntAlloc( 100 );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ // skip ROs without representatives
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) )
+// if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) )
+ continue;
+ assert( Gia_ObjIsRo(p, pRepr) );
+// Abc_Print( 1, "%d -> %d ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) );
+ // remember the pair
+ Vec_IntPush( vPairs, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) );
+ Vec_IntPush( vPairs, i );
+ }
+ return vPairs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remaps simulation info from SRM to the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo )
+{
+ unsigned * pInfoObj, * pInfoRepr;
+ int w, i, iObj, iRepr, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ Vec_IntForEachEntry( vPairs, iRepr, i )
+ {
+ iObj = Vec_IntEntry( vPairs, ++i );
+ pInfoObj = (unsigned *)Vec_PtrEntry( vInfo, iObj );
+ pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, iRepr );
+ for ( w = 0; w < nWords; w++ )
+ {
+ assert( pInfoObj[w] == 0 );
+ pInfoObj[w] = pInfoRepr[w];
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs one counter-examples into the array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+int Cec_ManLoadCounterExamplesTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits )
+{
+ unsigned * pInfo, * pPres;
+ int i;
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
+ pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
+ if ( Abc_InfoHasBit( pPres, iBit ) &&
+ Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
+ return 0;
+ }
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
+ pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
+ Abc_InfoSetBit( pPres, iBit );
+ if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
+ Abc_InfoXorBit( pInfo, iBit );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs bitpacking of counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart )
+{
+ Vec_Int_t * vPat;
+ Vec_Ptr_t * vPres;
+ int nWords = Vec_PtrReadWordsSimInfo(vInfo);
+ int nBits = 32 * nWords;
+ int k, nSize, iBit = 1, kMax = 0;
+ vPat = Vec_IntAlloc( 100 );
+ vPres = Vec_PtrAllocSimInfo( Vec_PtrSize(vInfo), nWords );
+ Vec_PtrCleanSimInfo( vPres, 0, nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ // skip the output number
+ iStart++;
+ // get the number of items
+ nSize = Vec_IntEntry( vCexStore, iStart++ );
+ if ( nSize <= 0 )
+ continue;
+ // extract pattern
+ Vec_IntClear( vPat );
+ for ( k = 0; k < nSize; k++ )
+ Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) );
+ // add pattern to storage
+ for ( k = 1; k < nBits; k++ )
+ if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
+ break;
+ kMax = Abc_MaxInt( kMax, k );
+ if ( k == nBits-1 )
+ break;
+ }
+ Vec_PtrFree( vPres );
+ Vec_IntFree( vPat );
+ return iStart;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs bitpacking of counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart )
+{
+ unsigned * pInfo;
+ int nBits = 32 * Vec_PtrReadWordsSimInfo(vInfo);
+ int k, iLit, nLits, Out, iBit = 1;
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ // skip the output number
+// iStart++;
+ Out = Vec_IntEntry( vCexStore, iStart++ );
+// Abc_Print( 1, "iBit = %d. Out = %d.\n", iBit, Out );
+ // get the number of items
+ nLits = Vec_IntEntry( vCexStore, iStart++ );
+ if ( nLits <= 0 )
+ continue;
+ // add pattern to storage
+ for ( k = 0; k < nLits; k++ )
+ {
+ iLit = Vec_IntEntry( vCexStore, iStart++ );
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, Abc_Lit2Var(iLit) );
+ if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(iLit) )
+ Abc_InfoXorBit( pInfo, iBit );
+ }
+ if ( ++iBit == nBits )
+ break;
+ }
+// Abc_Print( 1, "added %d bits\n", iBit-1 );
+ return iStart;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates counter-examples derived by the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames )
+{
+ Vec_Int_t * vPairs;
+ Vec_Ptr_t * vSimInfo;
+ int RetValue = 0, iStart = 0;
+ vPairs = Gia_ManCorrCreateRemapping( pSim->pAig );
+ Gia_ManSetRefs( pSim->pAig );
+// pSim->pPars->nWords = 63;
+ pSim->pPars->nFrames = nFrames;
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig) );
+ iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
+// iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart );
+// Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo );
+ Gia_ManCorrPerformRemapping( vPairs, vSimInfo );
+ RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
+// Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL );
+ }
+//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 );
+ assert( iStart == Vec_IntSize(vCexStore) );
+ Vec_PtrFree( vSimInfo );
+ Vec_IntFree( vPairs );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates counter-examples derived by the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore )
+{
+ Vec_Ptr_t * vSimInfo;
+ int RetValue = 0, iStart = 0;
+ Gia_ManSetRefs( pSim->pAig );
+ pSim->pPars->nFrames = 1;
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(pSim->pAig), pSim->pPars->nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ Cec_ManStartSimInfo( vSimInfo, 0 );
+ iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
+ RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
+ }
+ assert( iStart == Vec_IntSize(vCexStore) );
+ Vec_PtrFree( vSimInfo );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates equivalence classes by marking those that timed out.]
+
+ Description [Returns 1 if all ndoes are proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings )
+{
+ int i, status, iRepr, iObj;
+ int Counter = 0;
+ assert( 2 * Vec_StrSize(vStatus) == Vec_IntSize(vOutputs) );
+ Vec_StrForEachEntry( vStatus, status, i )
+ {
+ iRepr = Vec_IntEntry( vOutputs, 2*i );
+ iObj = Vec_IntEntry( vOutputs, 2*i+1 );
+ if ( status == 1 )
+ continue;
+ if ( status == 0 )
+ {
+ if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+ Counter++;
+// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+// Abc_Print( 1, "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj );
+// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+// Cec_ManSimClassRemoveOne( pSim, iObj );
+ continue;
+ }
+ if ( status == -1 )
+ {
+// if ( !Gia_ObjFailed( p, iObj ) )
+// Abc_Print( 1, "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" );
+// Gia_ObjSetFailed( p, iRepr );
+// Gia_ObjSetFailed( p, iObj );
+// if ( fRings )
+// Cec_ManSimClassRemoveOne( pSim, iRepr );
+ Cec_ManSimClassRemoveOne( pSim, iObj );
+ continue;
+ }
+ }
+// if ( Counter )
+// Abc_Print( 1, "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr;
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Gia_ManCorrReduce_rec( pNew, p, pRepr );
+ pObj->Value = Abc_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrReduce( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics during solving.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time )
+{
+ int nLits, CounterX = 0, Counter0 = 0, Counter = 0;
+ int i, Entry, nProve = 0, nDispr = 0, nFail = 0;
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter0++;
+ else if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ }
+ CounterX -= Gia_ManCoNum(p);
+ nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
+ if ( iIter == -1 )
+ Abc_Print( 1, "BMC : " );
+ else
+ Abc_Print( 1, "%3d : ", iIter );
+ Abc_Print( 1, "c =%8d cl =%7d lit =%8d ", Counter0, Counter, nLits );
+ if ( vStatus )
+ Vec_StrForEachEntry( vStatus, Entry, i )
+ {
+ if ( Entry == 1 )
+ nProve++;
+ else if ( Entry == 0 )
+ nDispr++;
+ else if ( Entry == -1 )
+ nFail++;
+ }
+ Abc_Print( 1, "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail );
+ Abc_PrintTime( 1, "T", Time );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs BMC for the equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPrefs )
+{
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Vec_Str_t * vStatus;
+ Vec_Int_t * vOutputs;
+ Vec_Int_t * vCexStore;
+ Cec_ManSim_t * pSim;
+ Gia_Man_t * pSrm;
+ int fChanges, RetValue;
+ // prepare simulation manager
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nFrames = pPars->nRounds;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pParsSim->fLatchCorr = pPars->fLatchCorr;
+ pParsSim->fSeqSimulate = 1;
+ pSim = Cec_ManSimStart( pAig, pParsSim );
+ // prepare SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVerbose;
+ fChanges = 1;
+ while ( fChanges )
+ {
+ int clkBmc = clock();
+ fChanges = 0;
+ pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
+ if ( Gia_ManPoNum(pSrm) == 0 )
+ {
+ Gia_ManStop( pSrm );
+ Vec_IntFree( vOutputs );
+ break;
+ }
+ pParsSat->nBTLimit *= 10;
+ if ( pPars->fUseCSat )
+ vCexStore = Tas_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ else
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ // refine classes with these counter-examples
+ if ( Vec_IntSize(vCexStore) )
+ {
+ RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nPrefs );
+ Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
+ fChanges = 1;
+ }
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, -1, clock() - clkBmc );
+ // recycle
+ Vec_IntFree( vCexStore );
+ Vec_StrFree( vStatus );
+ Gia_ManStop( pSrm );
+ Vec_IntFree( vOutputs );
+ }
+ Cec_ManSimStop( pSim );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Internal procedure for register correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
+{
+ int nIterMax = 100000;
+ int nAddFrames = 1; // additional timeframes to simulate
+ int fRunBmcFirst = 1;
+ Vec_Str_t * vStatus;
+ Vec_Int_t * vOutputs;
+ Vec_Int_t * vCexStore;
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Cec_ManSim_t * pSim;
+ Gia_Man_t * pSrm;
+ int r, RetValue, clkTotal = clock();
+ int clkSat = 0, clkSim = 0, clkSrm = 0;
+ int clk2, clk = clock();
+ if ( Gia_ManRegNum(pAig) == 0 )
+ {
+ Abc_Print( 1, "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" );
+ return 0;
+ }
+ Gia_ManRandom( 1 );
+ // prepare simulation manager
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nFrames = pPars->nFrames;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pParsSim->fLatchCorr = pPars->fLatchCorr;
+ pParsSim->fConstCorr = pPars->fConstCorr;
+ pParsSim->fSeqSimulate = 1;
+ // create equivalence classes of registers
+ pSim = Cec_ManSimStart( pAig, pParsSim );
+ if ( pAig->pReprs == NULL )
+ {
+ Cec_ManSimClassesPrepare( pSim, pPars->nLevelMax );
+ Cec_ManSimClassesRefine( pSim );
+ }
+ // prepare SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVerbose;
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n",
+ Gia_ManObjNum(pAig), Gia_ManAndNum(pAig),
+ pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat );
+ Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk );
+ }
+ // check the base case
+ if ( fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) )
+ Cec_ManLSCorrespondenceBmc( pAig, pPars, 0 );
+ if ( pPars->pFunc )
+ {
+ ((int (*)(void *))pPars->pFunc)( pPars->pData );
+ ((int (*)(void *))pPars->pFunc)( pPars->pData );
+ }
+ if ( pPars->nStepsMax == 0 )
+ {
+ Abc_Print( 1, "Stopped signal correspondence after BMC.\n" );
+ Cec_ManSimStop( pSim );
+ return 1;
+ }
+ // perform refinement of equivalence classes
+ for ( r = 0; r < nIterMax; r++ )
+ {
+ if ( pPars->nStepsMax == r )
+ {
+ Cec_ManSimStop( pSim );
+ Abc_Print( 1, "Stopped signal correspondence after %d refiment iterations.\n", r );
+ return 1;
+ }
+ clk = clock();
+ // perform speculative reduction
+ clk2 = clock();
+ pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
+ assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig) );
+ clkSrm += clock() - clk2;
+ if ( Gia_ManCoNum(pSrm) == 0 )
+ {
+ Vec_IntFree( vOutputs );
+ Gia_ManStop( pSrm );
+ break;
+ }
+//Gia_DumpAiger( pSrm, "corrsrm", r, 2 );
+ // found counter-examples to speculation
+ clk2 = clock();
+ if ( pPars->fUseCSat )
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ else
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ Gia_ManStop( pSrm );
+ clkSat += clock() - clk2;
+ if ( Vec_IntSize(vCexStore) == 0 )
+ {
+ Vec_IntFree( vCexStore );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+ break;
+ }
+ // refine classes with these counter-examples
+ clk2 = clock();
+ RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames );
+ Vec_IntFree( vCexStore );
+ clkSim += clock() - clk2;
+ Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+//Gia_ManEquivPrintClasses( pAig, 1, 0 );
+ if ( pPars->pFunc )
+ ((int (*)(void *))pPars->pFunc)( pPars->pData );
+ }
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk );
+ // check the overflow
+ if ( r == nIterMax )
+ Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" );
+ Cec_ManSimStop( pSim );
+ // check the base case
+ if ( !fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) )
+ Cec_ManLSCorrespondenceBmc( pAig, pPars, 0 );
+ clkTotal = clock() - clkTotal;
+ // report the results
+ if ( pPars->fVerbose )
+ {
+ ABC_PRTP( "Srm ", clkSrm, clkTotal );
+ ABC_PRTP( "Sat ", clkSat, clkTotal );
+ ABC_PRTP( "Sim ", clkSim, clkTotal );
+ ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal );
+ Abc_PrintTime( 1, "TOTAL", clkTotal );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes new initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames )
+{
+ Gia_Obj_t * pObj, * pObjRo, * pObjRi;
+ unsigned * pInitState;
+ int i, f;
+ Gia_ManRandom( 1 );
+// Abc_Print( 1, "Simulating %d timeframes.\n", nFrames );
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark1 = 0;
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Gia_ManConst0(pAig)->fMark1 = 0;
+ Gia_ManForEachPi( pAig, pObj, i )
+ pObj->fMark1 = Gia_ManRandom(0) & 1;
+ Gia_ManForEachAnd( pAig, pObj, i )
+ pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachRi( pAig, pObj, i )
+ pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj));
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, i )
+ pObjRo->fMark1 = pObjRi->fMark1;
+ }
+ pInitState = ABC_CALLOC( unsigned, Abc_BitWordNum(Gia_ManRegNum(pAig)) );
+ Gia_ManForEachRo( pAig, pObj, i )
+ {
+ if ( pObj->fMark1 )
+ Abc_InfoSetBit( pInitState, i );
+// Abc_Print( 1, "%d", pObj->fMark1 );
+ }
+// Abc_Print( 1, "\n" );
+ Gia_ManCleanMark1( pAig );
+ return pInitState;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints flop equivalences.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPrintFlopEquivs( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pRepr;
+ int i;
+ assert( p->vNamesIn != NULL );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Gia_ObjIsConst(p, Gia_ObjId(p, pObj)) )
+ Abc_Print( 1, "Original flop %s is proved equivalent to constant.\n", Vec_PtrEntry(p->vNamesIn, Gia_ObjCioId(pObj)) );
+ else if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ if ( Gia_ObjIsCi(pRepr) )
+ Abc_Print( 1, "Original flop %s is proved equivalent to flop %s.\n",
+ Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ),
+ Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pRepr) ) );
+ else
+ Abc_Print( 1, "Original flop %s is proved equivalent to internal node %d.\n",
+ Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ), Gia_ObjId(p, pRepr) );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Top-level procedure for register correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
+{
+ Gia_Man_t * pNew, * pTemp;
+ unsigned * pInitState;
+ int RetValue;
+ ABC_FREE( pAig->pReprs );
+ ABC_FREE( pAig->pNexts );
+ if ( pPars->nPrefix == 0 )
+ RetValue = Cec_ManLSCorrespondenceClasses( pAig, pPars );
+ else
+ {
+ // compute the cycles AIG
+ pInitState = Cec_ManComputeInitState( pAig, pPars->nPrefix );
+ pTemp = Gia_ManDupFlip( pAig, (int *)pInitState );
+ ABC_FREE( pInitState );
+ // compute classes of this AIG
+ RetValue = Cec_ManLSCorrespondenceClasses( pTemp, pPars );
+ // transfer the class info
+ pAig->pReprs = pTemp->pReprs; pTemp->pReprs = NULL;
+ pAig->pNexts = pTemp->pNexts; pTemp->pNexts = NULL;
+ // perform additional BMC
+ pPars->fUseCSat = 0;
+ pPars->nBTLimit = Abc_MaxInt( pPars->nBTLimit, 1000 );
+ Cec_ManLSCorrespondenceBmc( pAig, pPars, pPars->nPrefix );
+/*
+ // transfer the class info back
+ pTemp->pReprs = pAig->pReprs; pAig->pReprs = NULL;
+ pTemp->pNexts = pAig->pNexts; pAig->pNexts = NULL;
+ // continue refining
+ RetValue = Cec_ManLSCorrespondenceClasses( pTemp, pPars );
+ // transfer the class info
+ pAig->pReprs = pTemp->pReprs; pTemp->pReprs = NULL;
+ pAig->pNexts = pTemp->pNexts; pTemp->pNexts = NULL;
+*/
+ Gia_ManStop( pTemp );
+ }
+ // derive reduced AIG
+ if ( pPars->fMakeChoices )
+ {
+ pNew = Gia_ManEquivToChoices( pAig, 1 );
+ Gia_ManHasChoices( pNew );
+ }
+ else
+ {
+// Gia_ManEquivImprove( pAig );
+ pNew = Gia_ManCorrReduce( pAig );
+ pNew = Gia_ManSeqCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ //Gia_WriteAiger( pNew, "reduced.aig", 0, 0 );
+ }
+ // report the results
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ Gia_ManAndNum(pAig), Gia_ManAndNum(pNew),
+ 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1),
+ Gia_ManRegNum(pAig), Gia_ManRegNum(pNew),
+ 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) );
+ }
+ if ( pPars->nPrefix && (Gia_ManAndNum(pNew) < Gia_ManAndNum(pAig) || Gia_ManRegNum(pNew) < Gia_ManRegNum(pAig)) )
+ Abc_Print( 1, "The reduced AIG was produced using %d-th invariants and will not verify.\n", pPars->nPrefix );
+ // print verbose info about equivalences
+ if ( pPars->fVerboseFlops )
+ {
+ if ( pAig->vNamesIn == NULL )
+ Abc_Print( 1, "Flop output names are not available. Use command \"&get -n\".\n" );
+ else
+ Cec_ManPrintFlopEquivs( pAig );
+ }
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecCorr_updated.c b/src/proof/cec/cecCorr_updated.c
new file mode 100644
index 00000000..1db30705
--- /dev/null
+++ b/src/proof/cec/cecCorr_updated.c
@@ -0,0 +1,1027 @@
+/**CFile****************************************************************
+
+ FileName [cecCorr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Latch/signal correspondence computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecCorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes the real value of the literal w/o spec reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
+{
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f, nPrefix );
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f, nPrefix );
+ return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) );
+ }
+ if ( f == 0 )
+ {
+ assert( Gia_ObjIsRo(p, pObj) );
+ return Gia_ObjCopyF(p, f, pObj);
+ }
+ assert( f && Gia_ObjIsRo(p, pObj) );
+ pObj = Gia_ObjRoToRi( p, pObj );
+ Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1, nPrefix );
+ return Gia_ObjFanin0CopyF( p, f-1, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively performs speculative reduction for the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
+{
+ Gia_Obj_t * pRepr;
+ int iLitNew;
+ if ( ~Gia_ObjCopyF(p, f, pObj) )
+ return;
+ if ( f >= nPrefix && (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f, nPrefix );
+ iLitNew = Gia_LitNotCond( Gia_ObjCopyF(p, f, pRepr), Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ Gia_ObjSetCopyF( p, f, pObj, iLitNew );
+ return;
+ }
+ assert( Gia_ObjIsCand(pObj) );
+ iLitNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix );
+ Gia_ObjSetCopyF( p, f, pObj, iLitNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives SRM for signal correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int f, i, iPrev, iObj, iPrevNew, iObjNew;
+ assert( nFrames > 0 );
+ assert( Gia_ManRegNum(p) > 0 );
+ assert( p->pReprs != NULL );
+ p->pCopies = ABC_FALLOC( int, (nFrames+fScorr)*Gia_ManObjNum(p) );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ObjSetCopyF( p, 0, Gia_ManConst0(p), 0 );
+ Gia_ManForEachRo( p, pObj, i )
+ Gia_ObjSetCopyF( p, 0, pObj, Gia_ManAppendCi(pNew) );
+ Gia_ManForEachRo( p, pObj, i )
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ Gia_ObjSetCopyF( p, 0, pObj, Gia_ObjCopyF(p, 0, pRepr) );
+ for ( f = 0; f < nFrames+fScorr; f++ )
+ {
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
+ }
+ *pvOutputs = Vec_IntAlloc( 1000 );
+ vXorLits = Vec_IntAlloc( 1000 );
+ if ( fRings )
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsConst( p, i ) )
+ {
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
+ iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) );
+ if ( iObjNew != 0 )
+ {
+ Vec_IntPush( *pvOutputs, 0 );
+ Vec_IntPush( *pvOutputs, i );
+ Vec_IntPush( vXorLits, iObjNew );
+ }
+ }
+ else if ( Gia_ObjIsHead( p, i ) )
+ {
+ iPrev = i;
+ Gia_ClassForEachObj1( p, i, iObj )
+ {
+ iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
+ iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) );
+ }
+ iPrev = iObj;
+ }
+ iObj = i;
+ iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
+ iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
+ iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
+ if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
+ {
+ Vec_IntPush( *pvOutputs, iPrev );
+ Vec_IntPush( *pvOutputs, iObj );
+ Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) );
+ }
+ }
+ }
+ }
+ else
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames, 0 );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
+ iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ if ( iPrevNew != iObjNew )
+ {
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) );
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) );
+ }
+ }
+ }
+ Vec_IntForEachEntry( vXorLits, iObjNew, i )
+ Gia_ManAppendCo( pNew, iObjNew );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+ ABC_FREE( p->pCopies );
+//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives SRM for signal correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int fRings )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ Vec_Int_t * vXorLits;
+ int f, i, iPrevNew, iObjNew;
+ assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix );
+ assert( Gia_ManRegNum(p) > 0 );
+ assert( p->pReprs != NULL );
+ p->pCopies = ABC_FALLOC( int, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p) );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( (nFrames+nPrefix) * Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Gia_ManAppendCi(pNew);
+ Gia_ObjSetCopyF( p, 0, pObj, 0 );
+ }
+ for ( f = 0; f < nFrames+nPrefix+fScorr; f++ )
+ {
+ Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) );
+ }
+ *pvOutputs = Vec_IntAlloc( 1000 );
+ vXorLits = Vec_IntAlloc( 1000 );
+ for ( f = nPrefix; f < nFrames+nPrefix; f++ )
+ {
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL )
+ continue;
+ iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, f, nPrefix );
+ iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix );
+ iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
+ if ( iPrevNew != iObjNew )
+ {
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) );
+ Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) );
+ }
+ }
+ }
+ Vec_IntForEachEntry( vXorLits, iObjNew, i )
+ Gia_ManAppendCo( pNew, iObjNew );
+ Vec_IntFree( vXorLits );
+ Gia_ManHashStop( pNew );
+ ABC_FREE( p->pCopies );
+//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Initializes simulation info for lcorr/scorr counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops, int * pInitState )
+{
+ unsigned * pInfo;
+ int k, w, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ assert( nFlops <= Vec_PtrSize(vInfo) );
+ for ( k = 0; k < nFlops; k++ )
+ {
+ pInfo = Vec_PtrEntry( vInfo, k );
+ if ( pInitState && Gia_InfoHasBit(pInitState, k) )
+ {
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = ~0;
+// pInfo[0] <<= 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = 0;
+ }
+ }
+ for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ )
+ {
+ pInfo = Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Gia_ManRandom( 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remaps simulation info from SRM to the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrRemapSimInfo( Gia_Man_t * p, Vec_Ptr_t * vInfo )
+{
+ Gia_Obj_t * pObj, * pRepr;
+ unsigned * pInfoObj, * pInfoRepr;
+ int i, w, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ // skip ROs without representatives
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) )
+ continue;
+ pInfoObj = Vec_PtrEntry( vInfo, i );
+ for ( w = 0; w < nWords; w++ )
+ assert( pInfoObj[w] == 0 );
+ // skip ROs with constant representatives
+ if ( Gia_ObjIsConst0(pRepr) )
+ continue;
+ assert( Gia_ObjIsRo(p, pRepr) );
+// printf( "%d -> %d ", i, Gia_ObjId(p, pRepr) );
+ // transfer info from the representative
+ pInfoRepr = Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) );
+ for ( w = 0; w < nWords; w++ )
+ pInfoObj[w] = pInfoRepr[w];
+ }
+// printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects information about remapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p )
+{
+ Vec_Int_t * vPairs;
+ Gia_Obj_t * pObj, * pRepr;
+ int i;
+ vPairs = Vec_IntAlloc( 100 );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ // skip ROs without representatives
+ pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) );
+ if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) )
+// if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) )
+ continue;
+ assert( Gia_ObjIsRo(p, pRepr) );
+// printf( "%d -> %d ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) );
+ // remember the pair
+ Vec_IntPush( vPairs, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) );
+ Vec_IntPush( vPairs, i );
+ }
+ return vPairs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remaps simulation info from SRM to the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo, int * pInitState )
+{
+ unsigned * pInfoObj, * pInfoRepr;
+ int w, i, iObj, iRepr, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ Vec_IntForEachEntry( vPairs, iRepr, i )
+ {
+ iObj = Vec_IntEntry( vPairs, ++i );
+ pInfoObj = Vec_PtrEntry( vInfo, iObj );
+ pInfoRepr = Vec_PtrEntry( vInfo, iRepr );
+ for ( w = 0; w < nWords; w++ )
+ {
+ assert( pInitState || pInfoObj[w] == 0 );
+ pInfoObj[w] = pInfoRepr[w];
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs one counter-examples into the array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+int Cec_ManLoadCounterExamplesTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits )
+{
+ unsigned * pInfo, * pPres;
+ int i;
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i]));
+ pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i]));
+ if ( Gia_InfoHasBit( pPres, iBit ) &&
+ Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) )
+ return 0;
+ }
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i]));
+ pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i]));
+ Gia_InfoSetBit( pPres, iBit );
+ if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) )
+ Gia_InfoXorBit( pInfo, iBit );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs bitpacking of counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart )
+{
+ Vec_Int_t * vPat;
+ Vec_Ptr_t * vPres;
+ int nWords = Vec_PtrReadWordsSimInfo(vInfo);
+ int nBits = 32 * nWords;
+ int k, nSize, iBit = 1, kMax = 0;
+ vPat = Vec_IntAlloc( 100 );
+ vPres = Vec_PtrAllocSimInfo( Vec_PtrSize(vInfo), nWords );
+ Vec_PtrCleanSimInfo( vPres, 0, nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ // skip the output number
+ iStart++;
+ // get the number of items
+ nSize = Vec_IntEntry( vCexStore, iStart++ );
+ if ( nSize <= 0 )
+ continue;
+ // extract pattern
+ Vec_IntClear( vPat );
+ for ( k = 0; k < nSize; k++ )
+ Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) );
+ // add pattern to storage
+ for ( k = 1; k < nBits; k++ )
+ if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
+ break;
+ kMax = Abc_MaxInt( kMax, k );
+ if ( k == nBits-1 )
+ break;
+ }
+ Vec_PtrFree( vPres );
+ Vec_IntFree( vPat );
+ return iStart;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs bitpacking of counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart )
+{
+ unsigned * pInfo;
+ int nBits = 32 * Vec_PtrReadWordsSimInfo(vInfo);
+ int k, iLit, nLits, Out, iBit = 1;
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ // skip the output number
+// iStart++;
+ Out = Vec_IntEntry( vCexStore, iStart++ );
+// printf( "iBit = %d. Out = %d.\n", iBit, Out );
+ // get the number of items
+ nLits = Vec_IntEntry( vCexStore, iStart++ );
+ if ( nLits <= 0 )
+ continue;
+ // add pattern to storage
+ for ( k = 0; k < nLits; k++ )
+ {
+ iLit = Vec_IntEntry( vCexStore, iStart++ );
+ pInfo = Vec_PtrEntry( vInfo, Gia_Lit2Var(iLit) );
+ if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(iLit) )
+ Gia_InfoXorBit( pInfo, iBit );
+ }
+ if ( ++iBit == nBits )
+ break;
+ }
+// printf( "added %d bits\n", iBit-1 );
+ return iStart;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates counter-examples derived by the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames, int * pInitState )
+{
+ Vec_Int_t * vPairs;
+ Vec_Ptr_t * vSimInfo;
+ int RetValue = 0, iStart = 0;
+ vPairs = Gia_ManCorrCreateRemapping( pSim->pAig );
+ Gia_ManSetRefs( pSim->pAig );
+// pSim->pPars->nWords = 63;
+ pSim->pPars->nRounds = nFrames;
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig), pInitState );
+ iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
+// iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart );
+// Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo );
+ Gia_ManCorrPerformRemapping( vPairs, vSimInfo, pInitState );
+ RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
+// Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL );
+ }
+//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 );
+ assert( iStart == Vec_IntSize(vCexStore) );
+ Vec_PtrFree( vSimInfo );
+ Vec_IntFree( vPairs );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates counter-examples derived by the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore )
+{
+ Vec_Ptr_t * vSimInfo;
+ int RetValue = 0, iStart = 0;
+ Gia_ManSetRefs( pSim->pAig );
+ pSim->pPars->nRounds = 1;
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(pSim->pAig), pSim->pPars->nWords );
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ Cec_ManStartSimInfo( vSimInfo, 0, NULL );
+ iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
+ RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
+ }
+ assert( iStart == Vec_IntSize(vCexStore) );
+ Vec_PtrFree( vSimInfo );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates equivalence classes by marking those that timed out.]
+
+ Description [Returns 1 if all ndoes are proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings )
+{
+ int i, status, iRepr, iObj;
+ int Counter = 0;
+ assert( 2 * Vec_StrSize(vStatus) == Vec_IntSize(vOutputs) );
+ Vec_StrForEachEntry( vStatus, status, i )
+ {
+ iRepr = Vec_IntEntry( vOutputs, 2*i );
+ iObj = Vec_IntEntry( vOutputs, 2*i+1 );
+ if ( status == 1 )
+ continue;
+ if ( status == 0 )
+ {
+ if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+ Counter++;
+// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+// printf( "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj );
+// if ( Gia_ObjHasSameRepr(p, iRepr, iObj) )
+// Cec_ManSimClassRemoveOne( pSim, iObj );
+ continue;
+ }
+ if ( status == -1 )
+ {
+// if ( !Gia_ObjFailed( p, iObj ) )
+// printf( "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" );
+// Gia_ObjSetFailed( p, iRepr );
+// Gia_ObjSetFailed( p, iObj );
+// if ( fRings )
+// Cec_ManSimClassRemoveOne( pSim, iRepr );
+ Cec_ManSimClassRemoveOne( pSim, iObj );
+ continue;
+ }
+ }
+// if ( Counter )
+// printf( "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCorrReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr;
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Gia_ManCorrReduce_rec( pNew, p, pRepr );
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCorrReduce( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManCorrReduce_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics during solving.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time )
+{
+ int nLits, CounterX = 0, Counter0 = 0, Counter = 0;
+ int i, Entry, nProve = 0, nDispr = 0, nFail = 0;
+ for ( i = 1; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter0++;
+ else if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ }
+ CounterX -= Gia_ManCoNum(p);
+ nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
+ if ( iIter == -1 )
+ printf( "BMC : " );
+ else
+ printf( "%3d : ", iIter );
+ printf( "c =%8d cl =%7d lit =%8d ", Counter0, Counter, nLits );
+ if ( vStatus )
+ Vec_StrForEachEntry( vStatus, Entry, i )
+ {
+ if ( Entry == 1 )
+ nProve++;
+ else if ( Entry == 0 )
+ nDispr++;
+ else if ( Entry == -1 )
+ nFail++;
+ }
+ printf( "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail );
+ ABC_PRT( "T", Time );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes new initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames )
+{
+ Gia_Obj_t * pObj, * pObjRo, * pObjRi;
+ unsigned * pInitState;
+ int i, f;
+ printf( "Simulating %d timeframes.\n", nFrames );
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark1 = 0;
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Gia_ManConst0(pAig)->fMark1 = 0;
+ Gia_ManForEachPi( pAig, pObj, i )
+ pObj->fMark1 = Gia_ManRandom(0) & 1;
+// pObj->fMark1 = 1;
+ Gia_ManForEachAnd( pAig, pObj, i )
+ pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachRi( pAig, pObj, i )
+ pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj));
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, i )
+ pObjRo->fMark1 = pObjRi->fMark1;
+ }
+ pInitState = ABC_CALLOC( unsigned, Gia_BitWordNum(Gia_ManRegNum(pAig)) );
+ Gia_ManForEachRo( pAig, pObj, i )
+ {
+ if ( pObj->fMark1 )
+ Gia_InfoSetBit( pInitState, i );
+// printf( "%d", pObj->fMark1 );
+ }
+// printf( "\n" );
+ Gia_ManCleanMark1( pAig );
+ return pInitState;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Internal procedure for register correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
+{
+ int nIterMax = 100000;
+ int nAddFrames = 1; // additional timeframes to simulate
+ Vec_Str_t * vStatus;
+ Vec_Int_t * vOutputs;
+ Vec_Int_t * vCexStore;
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Cec_ManSim_t * pSim;
+ Gia_Man_t * pSrm;
+ unsigned * pInitState = NULL;
+ int r, RetValue, clkTotal = clock();
+ int clkSat = 0, clkSim = 0, clkSrm = 0;
+ int clk2, clk = clock();
+ ABC_FREE( pAig->pReprs );
+ ABC_FREE( pAig->pNexts );
+ if ( Gia_ManRegNum(pAig) == 0 )
+ {
+ printf( "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" );
+ return 0;
+ }
+ Gia_ManRandom( 1 );
+ // derive initial state for resimulation
+ if ( pPars->nPrefix )
+// pInitState = Cec_ManComputeInitState( pAig, 5+(1<<20)/Gia_ManAndNum(pAig) );
+ pInitState = Cec_ManComputeInitState( pAig, 100 );
+ // prepare simulation manager
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nWords = pPars->nWords;
+ pParsSim->nRounds = pPars->nRounds;
+ pParsSim->fVerbose = pPars->fVerbose;
+ pParsSim->fLatchCorr = pPars->fLatchCorr;
+ pParsSim->fSeqSimulate = 1;
+ // create equivalence classes of registers
+ pSim = Cec_ManSimStart( pAig, pParsSim, pInitState );
+ Cec_ManSimClassesPrepare( pSim );
+ Cec_ManSimClassesRefine( pSim );
+ // prepare SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVerbose;
+ if ( pPars->fVerbose )
+ {
+ printf( "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n",
+ Gia_ManObjNum(pAig), Gia_ManAndNum(pAig),
+ pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat );
+ Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk );
+ }
+ // perform refinement of equivalence classes
+ for ( r = 0; r < nIterMax; r++ )
+ {
+ clk = clock();
+ // perform speculative reduction
+ clk2 = clock();
+ pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
+ assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig) );
+ clkSrm += clock() - clk2;
+ if ( Gia_ManCoNum(pSrm) == 0 )
+ {
+ Vec_IntFree( vOutputs );
+ Gia_ManStop( pSrm );
+ break;
+ }
+//Gia_DumpAiger( pSrm, "corrsrm", r, 2 );
+ // found counter-examples to speculation
+ clk2 = clock();
+ if ( pPars->fUseCSat )
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ else
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ Gia_ManStop( pSrm );
+ clkSat += clock() - clk2;
+ if ( Vec_IntSize(vCexStore) == 0 )
+ {
+ Vec_IntFree( vCexStore );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+ break;
+ }
+ // refine classes with these counter-examples
+ clk2 = clock();
+ RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames, pInitState );
+ Vec_IntFree( vCexStore );
+ clkSim += clock() - clk2;
+ Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, clock() - clk );
+ Vec_StrFree( vStatus );
+ Vec_IntFree( vOutputs );
+//Gia_ManEquivPrintClasses( pAig, 1, 0 );
+ }
+ ABC_FREE( pInitState );
+ // check the base case
+ if ( (!pPars->fLatchCorr || pPars->nFrames > 1) || pPars->nPrefix )
+ {
+ int fChanges = 1;
+ while ( fChanges )
+ {
+ int clkBmc = clock();
+ fChanges = 0;
+ pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, pPars->nPrefix, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
+ if ( Gia_ManPoNum(pSrm) == 0 )
+ {
+ Gia_ManStop( pSrm );
+ Vec_IntFree( vOutputs );
+ break;
+ }
+ pParsSat->nBTLimit *= 10;
+ if ( pPars->nPrefix )
+ {
+ pParsSat->nBTLimit = 10000;
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ }
+ else if ( pPars->fUseCSat )
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ else
+ vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
+ // refine classes with these counter-examples
+ if ( Vec_IntSize(vCexStore) )
+ {
+ clk2 = clock();
+ RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames + pPars->nPrefix, NULL );
+ clkSim += clock() - clk2;
+ Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
+ fChanges = 1;
+ }
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, vStatus, -1, clock() - clkBmc );
+ // recycle
+ Vec_IntFree( vCexStore );
+ Vec_StrFree( vStatus );
+ Gia_ManStop( pSrm );
+ Vec_IntFree( vOutputs );
+ }
+ }
+ else
+ {
+ if ( pPars->fVerbose )
+ Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk );
+ }
+ // check the overflow
+ if ( r == nIterMax )
+ printf( "The refinement was not finished. The result may be incorrect.\n" );
+ Cec_ManSimStop( pSim );
+ clkTotal = clock() - clkTotal;
+ // report the results
+ if ( pPars->fVerbose )
+ {
+ ABC_PRTP( "Srm ", clkSrm, clkTotal );
+ ABC_PRTP( "Sat ", clkSat, clkTotal );
+ ABC_PRTP( "Sim ", clkSim, clkTotal );
+ ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal );
+ ABC_PRT( "TOTAL", clkTotal );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top-level procedure for register correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int RetValue;
+ RetValue = Cec_ManLSCorrespondenceClasses( pAig, pPars );
+ // derive reduced AIG
+ if ( pPars->fMakeChoices )
+ {
+ pNew = Gia_ManEquivToChoices( pAig, 1 );
+ Gia_ManHasChoices( pNew );
+ }
+ else
+ {
+ Gia_ManEquivImprove( pAig );
+ pNew = Gia_ManCorrReduce( pAig );
+ pNew = Gia_ManSeqCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ //Gia_WriteAiger( pNew, "reduced.aig", 0, 0 );
+ }
+ // report the results
+ if ( pPars->fVerbose )
+ {
+ printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ Gia_ManAndNum(pAig), Gia_ManAndNum(pNew),
+ 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1),
+ Gia_ManRegNum(pAig), Gia_ManRegNum(pNew),
+ 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) );
+ }
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecInt.h b/src/proof/cec/cecInt.h
new file mode 100644
index 00000000..371dedda
--- /dev/null
+++ b/src/proof/cec/cecInt.h
@@ -0,0 +1,225 @@
+/**CFile****************************************************************
+
+ FileName [cecInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__aig__cec__cecInt_h
+#define ABC__aig__cec__cecInt_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "src/sat/bsat/satSolver.h"
+#include "src/misc/bar/bar.h"
+#include "src/aig/gia/gia.h"
+#include "cec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// simulation pattern manager
+typedef struct Cec_ManPat_t_ Cec_ManPat_t;
+struct Cec_ManPat_t_
+{
+ Vec_Int_t * vPattern1; // pattern in terms of primary inputs
+ Vec_Int_t * vPattern2; // pattern in terms of primary inputs
+ Vec_Str_t * vStorage; // storage for compressed patterns
+ int iStart; // position in the array where recent patterns begin
+ int nPats; // total number of recent patterns
+ int nPatsAll; // total number of all patterns
+ int nPatLits; // total number of literals in recent patterns
+ int nPatLitsAll; // total number of literals in all patterns
+ int nPatLitsMin; // total number of literals in minimized recent patterns
+ int nPatLitsMinAll; // total number of literals in minimized all patterns
+ int nSeries; // simulation series
+ int fVerbose; // verbose stats
+ // runtime statistics
+ int timeFind; // detecting the pattern
+ int timeShrink; // minimizing the pattern
+ int timeVerify; // verifying the result of minimisation
+ int timeSort; // sorting literals
+ int timePack; // packing into sim info structures
+ int timeTotal; // total runtime
+ int timeTotalSave; // total runtime for saving
+};
+
+// SAT solving manager
+typedef struct Cec_ManSat_t_ Cec_ManSat_t;
+struct Cec_ManSat_t_
+{
+ // parameters
+ Cec_ParSat_t * pPars;
+ // AIGs used in the package
+ Gia_Man_t * pAig; // the AIG whose outputs are considered
+ Vec_Int_t * vStatus; // status for each output
+ // SAT solving
+ sat_solver * pSat; // recyclable SAT solver
+ int nSatVars; // the counter of SAT variables
+ int * pSatVars; // mapping of each node into its SAT var
+ Vec_Ptr_t * vUsedNodes; // nodes whose SAT vars are assigned
+ int nRecycles; // the number of times SAT solver was recycled
+ int nCallsSince; // the number of calls since the last recycle
+ Vec_Ptr_t * vFanins; // fanins of the CNF node
+ // counter-examples
+ Vec_Int_t * vCex; // the latest counter-example
+ Vec_Int_t * vVisits; // temporary array for visited nodes
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ int nCexLits;
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ // runtime stats
+ int timeSatUnsat; // unsat
+ int timeSatSat; // sat
+ int timeSatUndec; // undecided
+ int timeTotal; // total runtime
+};
+
+// combinational simulation manager
+typedef struct Cec_ManSim_t_ Cec_ManSim_t;
+struct Cec_ManSim_t_
+{
+ // parameters
+ Gia_Man_t * pAig; // the AIG to be used for simulation
+ Cec_ParSim_t * pPars; // simulation parameters
+ int nWords; // the number of simulation words
+ // recycable memory
+ int * pSimInfo; // simulation information offsets
+ unsigned * pMems; // allocated simulaton memory
+ int nWordsAlloc; // the number of allocated entries
+ int nMems; // the number of used entries
+ int nMemsMax; // the max number of used entries
+ int MemFree; // next free entry
+ int nWordsOld; // the number of simulation words after previous relink
+ // internal simulation info
+ Vec_Ptr_t * vCiSimInfo; // CI simulation info
+ Vec_Ptr_t * vCoSimInfo; // CO simulation info
+ // counter examples
+ void ** pCexes; // counter-examples for each output
+ int iOut; // first failed output
+ int nOuts; // the number of failed outputs
+ Abc_Cex_t * pCexComb; // counter-example for the first failed output
+ Abc_Cex_t * pBestState; // the state that led to most of the refinements
+ // scoring simulation patterns
+ int * pScores; // counters of refinement for each pattern
+ // temporaries
+ Vec_Int_t * vClassOld; // old class numbers
+ Vec_Int_t * vClassNew; // new class numbers
+ Vec_Int_t * vClassTemp; // temporary storage
+ Vec_Int_t * vRefinedC; // refined const reprs
+};
+
+// combinational simulation manager
+typedef struct Cec_ManFra_t_ Cec_ManFra_t;
+struct Cec_ManFra_t_
+{
+ // parameters
+ Gia_Man_t * pAig; // the AIG to be used for simulation
+ Cec_ParFra_t * pPars; // SAT sweeping parameters
+ // simulation patterns
+ Vec_Int_t * vXorNodes; // nodes used in speculative reduction
+ int nAllProved; // total number of proved nodes
+ int nAllDisproved; // total number of disproved nodes
+ int nAllFailed; // total number of failed nodes
+ // runtime stats
+ int timeSim; // unsat
+ int timePat; // unsat
+ int timeSat; // sat
+ int timeTotal; // total runtime
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cecCorr.c ============================================================*/
+extern void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time );
+/*=== cecClass.c ============================================================*/
+extern int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i );
+extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax );
+extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p );
+extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos );
+/*=== cecIso.c ============================================================*/
+extern int * Cec_ManDetectIsomorphism( Gia_Man_t * p );
+/*=== cecMan.c ============================================================*/
+extern Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars );
+extern void Cec_ManSatPrintStats( Cec_ManSat_t * p );
+extern void Cec_ManSatStop( Cec_ManSat_t * p );
+extern Cec_ManPat_t * Cec_ManPatStart();
+extern void Cec_ManPatPrintStats( Cec_ManPat_t * p );
+extern void Cec_ManPatStop( Cec_ManPat_t * p );
+extern Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars );
+extern void Cec_ManSimStop( Cec_ManSim_t * p );
+extern Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars );
+extern void Cec_ManFraStop( Cec_ManFra_t * p );
+/*=== cecPat.c ============================================================*/
+extern void Cec_ManPatSavePattern( Cec_ManPat_t * pPat, Cec_ManSat_t * p, Gia_Obj_t * pObj );
+extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWords );
+extern Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit );
+/*=== cecSeq.c ============================================================*/
+extern int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo );
+extern int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Abc_Cex_t * pBestState, int fCheckMiter );
+extern void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex );
+extern int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig );
+extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig );
+/*=== cecSolve.c ============================================================*/
+extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj );
+extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars );
+extern Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats );
+extern Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus );
+extern int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj );
+extern int Cec_ManSatCheckNodeTwo( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 );
+extern void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 );
+extern Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * p );
+/*=== ceFraeep.c ============================================================*/
+extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p );
+extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew );
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/cec/cecIso.c b/src/proof/cec/cecIso.c
new file mode 100644
index 00000000..f1ca2ff7
--- /dev/null
+++ b/src/proof/cec/cecIso.c
@@ -0,0 +1,375 @@
+/**CFile****************************************************************
+
+ FileName [cecIso.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Detection of structural isomorphism.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecIso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline unsigned * Cec_ManIsoInfo( unsigned * pStore, int nWords, int Id ) { return pStore + nWords * Id; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes simulation info for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoSimulate( Gia_Obj_t * pObj, int Id, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo = Cec_ManIsoInfo( pStore, nWords, Id );
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId0(pObj, Id) );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Gia_ObjFaninId1(pObj, Id) );
+ int w;
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = ~(pInfo0[w] | pInfo1[w]);
+ else
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = ~pInfo0[w] & pInfo1[w];
+ }
+ else
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = pInfo0[w] & ~pInfo1[w];
+ else
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = pInfo0[w] & pInfo1[w];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copies simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoCopy( int IdDest, int IdSour, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, IdDest );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, IdSour );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pInfo0[w] = pInfo1[w];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares simulation info of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoEqual( int Id0, int Id1, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id0 );
+ unsigned * pInfo1 = Cec_ManIsoInfo( pStore, nWords, Id1 );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( pInfo0[w] != pInfo1[w] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates random simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoRandom( int Id, unsigned * pStore, int nWords )
+{
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id );
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pInfo0[w] = Gia_ManRandom( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash key of the simuation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoHashKey( int Id, unsigned * pStore, int nWords, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned * pInfo0 = Cec_ManIsoInfo( pStore, nWords, Id );
+ unsigned uHash = 0;
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ uHash ^= pInfo0[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds node to the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoTableAdd( Gia_Man_t * p, int Id, unsigned * pStore, int nWords, int * pTable, int nTableSize )
+{
+ Gia_Obj_t * pTemp;
+ int Key, Ent, Counter = 0, Color = Gia_ObjColors( p, Id );
+ assert( Color == 1 || Color == 2 );
+ Key = Gia_ManIsoHashKey( Id, pStore, nWords, nTableSize );
+ for ( Ent = pTable[Key], pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp;
+ Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) )
+ {
+ if ( Gia_ObjColors( p, Ent ) != Color )
+ continue;
+ if ( !Gia_ManIsoEqual( Id, Ent, pStore, nWords ) )
+ continue;
+ // found node with the same color and signature - mark it and do not add new node
+ pTemp->fMark0 = 1;
+ return;
+ }
+ // did not find the node with the same color and signature - add new node
+ pTemp = Gia_ManObj( p, Id );
+ assert( pTemp->Value == 0 );
+ assert( pTemp->fMark0 == 0 );
+ pTemp->Value = pTable[Key];
+ pTable[Key] = Id;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts equivalence class candidates from one bin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManIsoExtractClasses( Gia_Man_t * p, int Bin, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB )
+{
+ Gia_Obj_t * pTemp;
+ int Ent;
+ Vec_IntClear( vNodesA );
+ Vec_IntClear( vNodesB );
+ for ( Ent = Bin, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL); pTemp;
+ Ent = pTemp->Value, pTemp = (Ent ? Gia_ManObj(p, Ent) : NULL) )
+ {
+ if ( pTemp->fMark0 )
+ {
+ pTemp->fMark0 = 0;
+ continue;
+ }
+ if ( Gia_ObjColors( p, Ent ) == 1 )
+ Vec_IntPush( vNodesA, Ent );
+ else
+ Vec_IntPush( vNodesB, Ent );
+ }
+ return Vec_IntSize(vNodesA) > 0 && Vec_IntSize(vNodesB) > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Matches nodes in the extacted classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManIsoMatchNodes( int * pIso, unsigned * pStore, int nWords, Vec_Int_t * vNodesA, Vec_Int_t * vNodesB )
+{
+ int k0, k1, IdA, IdB;
+ Vec_IntForEachEntry( vNodesA, IdA, k0 )
+ Vec_IntForEachEntry( vNodesB, IdB, k1 )
+ {
+ if ( Gia_ManIsoEqual( IdA, IdB, pStore, nWords ) )
+ {
+ assert( pIso[IdA] == 0 );
+ assert( pIso[IdB] == 0 );
+ assert( IdA != IdB );
+ pIso[IdA] = IdB;
+ pIso[IdB] = IdA;
+ continue;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms iso into equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManTransformClasses( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pReprs && p->pNexts && p->pIso );
+ memset( p->pReprs, 0, sizeof(int) * Gia_ManObjNum(p) );
+ memset( p->pNexts, 0, sizeof(int) * Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( p->pIso[i] && p->pIso[i] < i )
+ {
+ p->pReprs[i].iRepr = p->pIso[i];
+ p->pNexts[p->pIso[i]] = i;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds node correspondences in the miter.]
+
+ Description [Assumes that the colors are assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Cec_ManDetectIsomorphism( Gia_Man_t * p )
+{
+ int nWords = 2;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vNodesA, * vNodesB;
+ unsigned * pStore, Counter;
+ int i, * pIso, * pTable, nTableSize;
+ // start equivalence classes
+ pIso = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ assert( Gia_ObjColors(p, i) == 0 );
+ continue;
+ }
+ assert( Gia_ObjColors(p, i) );
+ if ( Gia_ObjColors(p, i) == 3 )
+ pIso[i] = i;
+ }
+ // start simulation info
+ pStore = ABC_ALLOC( unsigned, Gia_ManObjNum(p) * nWords );
+ // simulate and create table
+ nTableSize = Abc_PrimeCudd( 100 + Gia_ManObjNum(p)/2 );
+ pTable = ABC_CALLOC( int, nTableSize );
+ Gia_ManCleanValue( p );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ if ( pIso[i] == 0 ) // simulate
+ Gia_ManIsoSimulate( pObj, i, pStore, nWords );
+ else if ( pIso[i] < i ) // copy
+ Gia_ManIsoCopy( i, pIso[i], pStore, nWords );
+ else // generate
+ Gia_ManIsoRandom( i, pStore, nWords );
+ if ( pIso[i] == 0 )
+ Gia_ManIsoTableAdd( p, i, pStore, nWords, pTable, nTableSize );
+ }
+ // create equivalence classes
+ vNodesA = Vec_IntAlloc( 100 );
+ vNodesB = Vec_IntAlloc( 100 );
+ for ( i = 0; i < nTableSize; i++ )
+ if ( Gia_ManIsoExtractClasses( p, pTable[i], pStore, nWords, vNodesA, vNodesB ) )
+ Gia_ManIsoMatchNodes( pIso, pStore, nWords, vNodesA, vNodesB );
+ Vec_IntFree( vNodesA );
+ Vec_IntFree( vNodesB );
+ // collect info
+ Counter = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ Counter += (pIso[i] && pIso[i] < i);
+/*
+ if ( pIso[i] && pIso[i] < i )
+ {
+ if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) ||
+ (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) )
+ Abc_Print( 1, "1" );
+ else
+ Abc_Print( 1, "0" );
+ }
+*/
+ }
+ Abc_Print( 1, "Computed %d pairs of structurally equivalent nodes.\n", Counter );
+// p->pIso = pIso;
+// Cec_ManTransformClasses( p );
+
+ ABC_FREE( pTable );
+ ABC_FREE( pStore );
+ return pIso;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecMan.c b/src/proof/cec/cecMan.c
new file mode 100644
index 00000000..f03ec701
--- /dev/null
+++ b/src/proof/cec/cecMan.c
@@ -0,0 +1,297 @@
+/**CFile****************************************************************
+
+ FileName [cecMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Manager procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
+{
+ Cec_ManSat_t * p;
+ // create interpolation manager
+ p = ABC_ALLOC( Cec_ManSat_t, 1 );
+ memset( p, 0, sizeof(Cec_ManSat_t) );
+ p->pPars = pPars;
+ p->pAig = pAig;
+ // SAT solving
+ p->nSatVars = 1;
+ p->pSatVars = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
+ p->vUsedNodes = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vCex = Vec_IntAlloc( 100 );
+ p->vVisits = Vec_IntAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatPrintStats( Cec_ManSat_t * p )
+{
+ Abc_Print( 1, "CO = %8d ", Gia_ManCoNum(p->pAig) );
+ Abc_Print( 1, "AND = %8d ", Gia_ManAndNum(p->pAig) );
+ Abc_Print( 1, "Conf = %5d ", p->pPars->nBTLimit );
+ Abc_Print( 1, "MinVar = %5d ", p->pPars->nSatVarMax );
+ Abc_Print( 1, "MinCalls = %5d\n", p->pPars->nCallsRecycle );
+ Abc_Print( 1, "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal : 0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ Abc_PrintTimeP( 1, "Time", p->timeSatUnsat, p->timeTotal );
+ Abc_Print( 1, "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal : 0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ Abc_PrintTimeP( 1, "Time", p->timeSatSat, p->timeTotal );
+ Abc_Print( 1, "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal : 0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ Abc_PrintTimeP( 1, "Time", p->timeSatUndec, p->timeTotal );
+ Abc_PrintTime( 1, "Total time", p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatStop( Cec_ManSat_t * p )
+{
+ if ( p->pSat )
+ sat_solver_delete( p->pSat );
+ Vec_IntFree( p->vCex );
+ Vec_IntFree( p->vVisits );
+ Vec_PtrFree( p->vUsedNodes );
+ Vec_PtrFree( p->vFanins );
+ ABC_FREE( p->pSatVars );
+ ABC_FREE( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec_ManPat_t * Cec_ManPatStart()
+{
+ Cec_ManPat_t * p;
+ p = ABC_CALLOC( Cec_ManPat_t, 1 );
+ p->vStorage = Vec_StrAlloc( 1<<20 );
+ p->vPattern1 = Vec_IntAlloc( 1000 );
+ p->vPattern2 = Vec_IntAlloc( 1000 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatPrintStats( Cec_ManPat_t * p )
+{
+ Abc_Print( 1, "Latest: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n",
+ p->nPats, p->nPatLits, p->nPatLitsMin, 1.0 * p->nPatLitsMin/p->nPats,
+ 1.0*(Vec_StrSize(p->vStorage)-p->iStart)/(1<<20) );
+ Abc_Print( 1, "Total: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n",
+ p->nPatsAll, p->nPatLitsAll, p->nPatLitsMinAll, 1.0 * p->nPatLitsMinAll/p->nPatsAll,
+ 1.0*Vec_StrSize(p->vStorage)/(1<<20) );
+ Abc_PrintTimeP( 1, "Finding ", p->timeFind, p->timeTotal );
+ Abc_PrintTimeP( 1, "Shrinking", p->timeShrink, p->timeTotal );
+ Abc_PrintTimeP( 1, "Verifying", p->timeVerify, p->timeTotal );
+ Abc_PrintTimeP( 1, "Sorting ", p->timeSort, p->timeTotal );
+ Abc_PrintTimeP( 1, "Packing ", p->timePack, p->timeTotal );
+ Abc_PrintTime( 1, "TOTAL ", p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatStop( Cec_ManPat_t * p )
+{
+ Vec_StrFree( p->vStorage );
+ Vec_IntFree( p->vPattern1 );
+ Vec_IntFree( p->vPattern2 );
+ ABC_FREE( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars )
+{
+ Cec_ManSim_t * p;
+ p = ABC_ALLOC( Cec_ManSim_t, 1 );
+ memset( p, 0, sizeof(Cec_ManSim_t) );
+ p->pAig = pAig;
+ p->pPars = pPars;
+ p->nWords = pPars->nWords;
+ p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
+ p->vClassOld = Vec_IntAlloc( 1000 );
+ p->vClassNew = Vec_IntAlloc( 1000 );
+ p->vClassTemp = Vec_IntAlloc( 1000 );
+ p->vRefinedC = Vec_IntAlloc( 10000 );
+ p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords );
+ if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) )
+ {
+ p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords );
+ Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords );
+ }
+ p->iOut = -1;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSimStop( Cec_ManSim_t * p )
+{
+ Vec_IntFree( p->vClassOld );
+ Vec_IntFree( p->vClassNew );
+ Vec_IntFree( p->vClassTemp );
+ Vec_IntFree( p->vRefinedC );
+ if ( p->vCiSimInfo )
+ Vec_PtrFree( p->vCiSimInfo );
+ if ( p->vCoSimInfo )
+ Vec_PtrFree( p->vCoSimInfo );
+ ABC_FREE( p->pScores );
+ ABC_FREE( p->pCexComb );
+ ABC_FREE( p->pCexes );
+ ABC_FREE( p->pMems );
+ ABC_FREE( p->pSimInfo );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec_ManFra_t * Cec_ManFraStart( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
+{
+ Cec_ManFra_t * p;
+ p = ABC_ALLOC( Cec_ManFra_t, 1 );
+ memset( p, 0, sizeof(Cec_ManFra_t) );
+ p->pAig = pAig;
+ p->pPars = pPars;
+ p->vXorNodes = Vec_IntAlloc( 1000 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManFraStop( Cec_ManFra_t * p )
+{
+ Vec_IntFree( p->vXorNodes );
+ ABC_FREE( p );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecPat.c b/src/proof/cec/cecPat.c
new file mode 100644
index 00000000..cb1dae46
--- /dev/null
+++ b/src/proof/cec/cecPat.c
@@ -0,0 +1,569 @@
+/**CFile****************************************************************
+
+ FileName [cecPat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Simulation pattern manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cec_ManPatStoreNum( Cec_ManPat_t * p, int Num )
+{
+ unsigned x = (unsigned)Num;
+ assert( Num >= 0 );
+ while ( x & ~0x7f )
+ {
+ Vec_StrPush( p->vStorage, (char)((x & 0x7f) | 0x80) );
+ x >>= 7;
+ }
+ Vec_StrPush( p->vStorage, (char)x );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cec_ManPatRestoreNum( Cec_ManPat_t * p )
+{
+ int ch, i, x = 0;
+ for ( i = 0; (ch = Vec_StrEntry(p->vStorage, p->iStart++)) & 0x80; i++ )
+ x |= (ch & 0x7f) << (7 * i);
+ return x | (ch << (7 * i));
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cec_ManPatStore( Cec_ManPat_t * p, Vec_Int_t * vPat )
+{
+ int i, Number, NumberPrev;
+ assert( Vec_IntSize(vPat) > 0 );
+ Cec_ManPatStoreNum( p, Vec_IntSize(vPat) );
+ NumberPrev = Vec_IntEntry( vPat, 0 );
+ Cec_ManPatStoreNum( p, NumberPrev );
+ Vec_IntForEachEntryStart( vPat, Number, i, 1 )
+ {
+ assert( NumberPrev < Number );
+ Cec_ManPatStoreNum( p, Number - NumberPrev );
+ NumberPrev = Number;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cec_ManPatRestore( Cec_ManPat_t * p, Vec_Int_t * vPat )
+{
+ int i, Size, Number;
+ Vec_IntClear( vPat );
+ Size = Cec_ManPatRestoreNum( p );
+ Number = Cec_ManPatRestoreNum( p );
+ Vec_IntPush( vPat, Number );
+ for ( i = 1; i < Size; i++ )
+ {
+ Number += Cec_ManPatRestoreNum( p );
+ Vec_IntPush( vPat, Number );
+ }
+ assert( Vec_IntSize(vPat) == Size );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManPatComputePattern_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Counter = 0;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pObj->fMark1 = Cec_ObjSatVarValue( pSat, pObj );
+ return 1;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin0(pObj) );
+ Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin1(pObj) );
+ pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj));
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatComputePattern1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( pObj->fMark1 == 1 )
+ {
+ Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat );
+ Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat );
+ }
+ else
+ {
+ assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ||
+ (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 );
+ if ( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 )
+ Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat );
+ else
+ Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatComputePattern2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( pObj->fMark1 == 1 )
+ {
+ Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat );
+ Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat );
+ }
+ else
+ {
+ assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ||
+ (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 );
+ if ( (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 )
+ Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat );
+ else
+ Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManPatComputePattern3_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Value0, Value1, Value;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return (pObj->fMark1 << 1) | pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pObj->fMark0 = 1;
+ pObj->fMark1 = 1;
+ return GIA_UND;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) );
+ Value1 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin1(pObj) );
+ Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) );
+ pObj->fMark0 = (Value & 1);
+ pObj->fMark1 = ((Value >> 1) & 1);
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
+{
+ Gia_Obj_t * pTemp;
+ int i, Value;
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vPat, Value, i )
+ {
+ pTemp = Gia_ManCi( p, Abc_Lit2Var(Value) );
+// assert( Abc_LitIsCompl(Value) != (int)pTemp->fMark1 );
+ if ( pTemp->fMark1 )
+ {
+ pTemp->fMark0 = 0;
+ pTemp->fMark1 = 1;
+ }
+ else
+ {
+ pTemp->fMark0 = 1;
+ pTemp->fMark1 = 0;
+ }
+ Gia_ObjSetTravIdCurrent( p, pTemp );
+ }
+ Value = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) );
+ Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) );
+ if ( Value != GIA_ONE )
+ Abc_Print( 1, "Cec_ManPatVerifyPattern(): Verification failed.\n" );
+ assert( Value == GIA_ONE );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatComputePattern4_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ pObj->fMark0 = 0;
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) );
+ Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ assert( Gia_ObjIsCo(pObj) );
+ Gia_ManIncrementTravId( p );
+ Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManPatSavePattern( Cec_ManPat_t * pMan, Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ Vec_Int_t * vPat;
+ int nPatLits, clk, clkTotal = clock();
+ assert( Gia_ObjIsCo(pObj) );
+ pMan->nPats++;
+ pMan->nPatsAll++;
+ // compute values in the cone of influence
+clk = clock();
+ Gia_ManIncrementTravId( p->pAig );
+ nPatLits = Cec_ManPatComputePattern_rec( p, p->pAig, Gia_ObjFanin0(pObj) );
+ assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 1 );
+ pMan->nPatLits += nPatLits;
+ pMan->nPatLitsAll += nPatLits;
+pMan->timeFind += clock() - clk;
+ // compute sensitizing path
+clk = clock();
+ Vec_IntClear( pMan->vPattern1 );
+ Gia_ManIncrementTravId( p->pAig );
+ Cec_ManPatComputePattern1_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern1 );
+ // compute sensitizing path
+ Vec_IntClear( pMan->vPattern2 );
+ Gia_ManIncrementTravId( p->pAig );
+ Cec_ManPatComputePattern2_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern2 );
+ // compare patterns
+ vPat = Vec_IntSize(pMan->vPattern1) < Vec_IntSize(pMan->vPattern2) ? pMan->vPattern1 : pMan->vPattern2;
+ pMan->nPatLitsMin += Vec_IntSize(vPat);
+ pMan->nPatLitsMinAll += Vec_IntSize(vPat);
+pMan->timeShrink += clock() - clk;
+ // verify pattern using ternary simulation
+clk = clock();
+ Cec_ManPatVerifyPattern( p->pAig, pObj, vPat );
+pMan->timeVerify += clock() - clk;
+ // sort pattern
+clk = clock();
+ Vec_IntSort( vPat, 0 );
+pMan->timeSort += clock() - clk;
+ // save pattern
+ Cec_ManPatStore( pMan, vPat );
+ pMan->timeTotal += clock() - clkTotal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+int Cec_ManPatCollectTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits )
+{
+ unsigned * pInfo, * pPres;
+ int i;
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
+ pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
+ if ( Abc_InfoHasBit( pPres, iBit ) &&
+ Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
+ return 0;
+ }
+ for ( i = 0; i < nLits; i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
+ pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
+ Abc_InfoSetBit( pPres, iBit );
+ if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
+ Abc_InfoXorBit( pInfo, iBit );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWordsInit )
+{
+ Vec_Int_t * vPat = pMan->vPattern1;
+ Vec_Ptr_t * vInfo, * vPres;
+ int k, kMax = -1, nPatterns = 0;
+ int iStartOld = pMan->iStart;
+ int nWords = nWordsInit;
+ int nBits = 32 * nWords;
+ int clk = clock();
+ vInfo = Vec_PtrAllocSimInfo( nInputs, nWords );
+ Gia_ManRandomInfo( vInfo, 0, 0, nWords );
+ vPres = Vec_PtrAllocSimInfo( nInputs, nWords );
+ Vec_PtrCleanSimInfo( vPres, 0, nWords );
+ while ( pMan->iStart < Vec_StrSize(pMan->vStorage) )
+ {
+ nPatterns++;
+ Cec_ManPatRestore( pMan, vPat );
+ for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) )
+ if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
+ break;
+ kMax = Abc_MaxInt( kMax, k );
+ if ( k == nBits-1 )
+ {
+ Vec_PtrReallocSimInfo( vInfo );
+ Gia_ManRandomInfo( vInfo, 0, nWords, 2*nWords );
+ Vec_PtrReallocSimInfo( vPres );
+ Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords );
+ nWords *= 2;
+ nBits *= 2;
+ }
+ }
+ Vec_PtrFree( vPres );
+ pMan->nSeries = Vec_PtrReadWordsSimInfo(vInfo) / nWordsInit;
+ pMan->timePack += clock() - clk;
+ pMan->timeTotal += clock() - clk;
+ pMan->iStart = iStartOld;
+ if ( pMan->fVerbose )
+ {
+ Abc_Print( 1, "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ",
+ nPatterns, kMax, nWordsInit*32, pMan->nSeries );
+ ABC_PRT( "Time", clock() - clk );
+ Cec_ManPatPrintStats( pMan );
+ }
+ return vInfo;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Packs patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit )
+{
+ Vec_Int_t * vPat;
+ Vec_Ptr_t * vInfo, * vPres;
+ int k, nSize, iStart, kMax = 0, nPatterns = 0;
+ int nWords = nWordsInit;
+ int nBits = 32 * nWords;
+// int RetValue;
+ assert( nRegs <= nInputs );
+ vPat = Vec_IntAlloc( 100 );
+
+ vInfo = Vec_PtrAllocSimInfo( nInputs, nWords );
+ Vec_PtrCleanSimInfo( vInfo, 0, nWords );
+ Gia_ManRandomInfo( vInfo, nRegs, 0, nWords );
+
+ vPres = Vec_PtrAllocSimInfo( nInputs, nWords );
+ Vec_PtrCleanSimInfo( vPres, 0, nWords );
+ iStart = 0;
+ while ( iStart < Vec_IntSize(vCexStore) )
+ {
+ nPatterns++;
+ // skip the output number
+ iStart++;
+ // get the number of items
+ nSize = Vec_IntEntry( vCexStore, iStart++ );
+ if ( nSize <= 0 )
+ continue;
+ // extract pattern
+ Vec_IntClear( vPat );
+ for ( k = 0; k < nSize; k++ )
+ Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) );
+ // add pattern to storage
+ for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) )
+ if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
+ break;
+
+// k = kMax + 1;
+// RetValue = Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) );
+// assert( RetValue == 1 );
+
+ kMax = Abc_MaxInt( kMax, k );
+ if ( k == nBits-1 )
+ {
+ Vec_PtrReallocSimInfo( vInfo );
+ Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords );
+ Gia_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords );
+
+ Vec_PtrReallocSimInfo( vPres );
+ Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords );
+ nWords *= 2;
+ nBits *= 2;
+ }
+ }
+// Abc_Print( 1, "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits );
+ Vec_PtrFree( vPres );
+ Vec_IntFree( vPat );
+ return vInfo;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSeq.c b/src/proof/cec/cecSeq.c
new file mode 100644
index 00000000..21ed8656
--- /dev/null
+++ b/src/proof/cec/cecSeq.c
@@ -0,0 +1,448 @@
+/**CFile****************************************************************
+
+ FileName [cecSeq.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Refinement of sequential equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets register values from the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex )
+{
+ unsigned * pInfo;
+ int k, i, w, nWords;
+ assert( pCex->nBits == pCex->nRegs + pCex->nPis * (pCex->iFrame + 1) );
+ assert( pCex->nBits - pCex->nRegs + Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) );
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+/*
+ // user register values
+ assert( pCex->nRegs == Gia_ManRegNum(pAig) );
+ for ( k = 0; k < pCex->nRegs; k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Abc_InfoHasBit( pCex->pData, k )? ~0 : 0;
+ }
+*/
+ // print warning about register values
+ for ( k = 0; k < pCex->nRegs; k++ )
+ if ( Abc_InfoHasBit( pCex->pData, k ) )
+ break;
+ if ( k < pCex->nRegs )
+ Abc_Print( 0, "The CEX has flop values different from 0, but they are currently not used by \"resim\".\n" );
+
+ // assign zero register values
+ for ( k = 0; k < Gia_ManRegNum(pAig); k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = 0;
+ }
+ for ( i = pCex->nRegs; i < pCex->nBits; i++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k++ );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Gia_ManRandom(0);
+ // set simulation pattern and make sure it is second (first will be erased during simulation)
+ pInfo[0] = (pInfo[0] << 1) | Abc_InfoHasBit( pCex->pData, i );
+ pInfo[0] <<= 1;
+ }
+ for ( ; k < Vec_PtrSize(vInfo); k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Gia_ManRandom(0);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets register values from the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex )
+{
+ unsigned * pInfo;
+ int k, w, nWords;
+ nWords = Vec_PtrReadWordsSimInfo( vInfo );
+ assert( pCex == NULL || Gia_ManRegNum(pAig) == pCex->nRegs );
+ assert( Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) );
+ for ( k = 0; k < Gia_ManRegNum(pAig); k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = (pCex && Abc_InfoHasBit(pCex->pData, k))? ~0 : 0;
+ }
+
+ for ( ; k < Vec_PtrSize(vInfo); k++ )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( vInfo, k );
+ for ( w = 0; w < nWords; w++ )
+ pInfo[w] = Gia_ManRandom( 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the classes using sequential simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo )
+{
+ unsigned * pInfo0, * pInfo1;
+ int f, i, k, w;
+// assert( Gia_ManRegNum(p->pAig) > 0 );
+ assert( Vec_PtrSize(vInfo) == Gia_ManRegNum(p->pAig) + Gia_ManPiNum(p->pAig) * p->pPars->nFrames );
+ for ( k = 0; k < Gia_ManRegNum(p->pAig); k++ )
+ {
+ pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k );
+ pInfo1 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + k );
+ for ( w = 0; w < p->nWords; w++ )
+ pInfo1[w] = pInfo0[w];
+ }
+ for ( f = 0; f < p->pPars->nFrames; f++ )
+ {
+ for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
+ {
+ pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k++ );
+ pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i );
+ for ( w = 0; w < p->nWords; w++ )
+ pInfo1[w] = pInfo0[w];
+ }
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ pInfo0 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + i );
+ pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i );
+ for ( w = 0; w < p->nWords; w++ )
+ pInfo1[w] = pInfo0[w];
+ }
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
+ }
+ assert( k == Vec_PtrSize(vInfo) );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates information to refine equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Abc_Cex_t * pBestState, int fCheckMiter )
+{
+ Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
+ Cec_ManSim_t * pSim;
+ int RetValue, clkTotal = clock();
+ assert( (Vec_PtrSize(vSimInfo) - Gia_ManRegNum(pAig)) % Gia_ManPiNum(pAig) == 0 );
+ Cec_ManSimSetDefaultParams( pParsSim );
+ pParsSim->nFrames = (Vec_PtrSize(vSimInfo) - Gia_ManRegNum(pAig)) / Gia_ManPiNum(pAig);
+ pParsSim->nWords = Vec_PtrReadWordsSimInfo( vSimInfo );
+ pParsSim->fCheckMiter = fCheckMiter;
+ Gia_ManSetRefs( pAig );
+ pSim = Cec_ManSimStart( pAig, pParsSim );
+ if ( pBestState )
+ pSim->pBestState = pBestState;
+ RetValue = Cec_ManSeqResimulate( pSim, vSimInfo );
+ pSim->pBestState = NULL;
+ Cec_ManSimStop( pSim );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimuates one counter-example to refine equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex )
+{
+ Vec_Ptr_t * vSimInfo;
+ int RetValue, clkTotal = clock();
+ if ( pCex == NULL )
+ {
+ Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Counter-example is not available.\n" );
+ return -1;
+ }
+ if ( pAig->pReprs == NULL )
+ {
+ Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Equivalence classes are not available.\n" );
+ return -1;
+ }
+ if ( Gia_ManRegNum(pAig) == 0 )
+ {
+ Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" );
+ return -1;
+ }
+// if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis )
+ if ( Gia_ManPiNum(pAig) != pCex->nPis )
+ {
+ Abc_Print( 1, "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" );
+ return -1;
+ }
+ if ( pPars->fVerbose )
+ Abc_Print( 1, "Resimulating %d timeframes.\n", pPars->nFrames + pCex->iFrame + 1 );
+ Gia_ManRandom( 1 );
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) +
+ Gia_ManPiNum(pAig) * (pPars->nFrames + pCex->iFrame + 1), 1 );
+ Cec_ManSeqDeriveInfoFromCex( vSimInfo, pAig, pCex );
+ if ( pPars->fVerbose )
+ Gia_ManEquivPrintClasses( pAig, 0, 0 );
+ RetValue = Cec_ManSeqResimulateInfo( pAig, vSimInfo, NULL, pPars->fCheckMiter );
+ if ( pPars->fVerbose )
+ Gia_ManEquivPrintClasses( pAig, 0, 0 );
+ Vec_PtrFree( vSimInfo );
+ if ( pPars->fVerbose )
+ ABC_PRT( "Time", clock() - clkTotal );
+// if ( RetValue && pPars->fCheckMiter )
+// Abc_Print( 1, "Cec_ManSeqResimulateCounter(): An output of the miter is asserted!\n" );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of POs that are not const0 cands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ if ( pAig->pReprs == NULL )
+ return -1;
+ Gia_ManForEachPo( pAig, pObj, i )
+ if ( !Gia_ObjIsConst( pAig, Gia_ObjFaninId0p(pAig, pObj) ) )
+ Counter++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of POs that are not const0 cands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig )
+{
+ Gia_Obj_t * pObj;
+ int i, RetValue = 0;
+ if ( pAig->pReprs == NULL )
+ return 0;
+ // label internal nodes driving POs
+ Gia_ManForEachPo( pAig, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ // check if there are non-labled equivs
+ Gia_ManForEachObj( pAig, pObj, i )
+ if ( Gia_ObjIsCand(pObj) && !pObj->fMark0 && Gia_ObjRepr(pAig, i) != GIA_VOID )
+ {
+ RetValue = 1;
+ break;
+ }
+ // clean internal nodes driving POs
+ Gia_ManForEachPo( pAig, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark0 = 0;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs semiformal refinement of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars )
+{
+ int nAddFrames = 16; // additional timeframes to simulate
+ int nCountNoRef = 0;
+ int nFramesReal;
+ Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
+ Vec_Ptr_t * vSimInfo;
+ Vec_Str_t * vStatus;
+ Abc_Cex_t * pState;
+ Gia_Man_t * pSrm, * pReduce, * pAux;
+ int r, nPats, RetValue = 0;
+ if ( pAig->pReprs == NULL )
+ {
+ Abc_Print( 1, "Cec_ManSeqSemiformal(): Equivalence classes are not available.\n" );
+ return -1;
+ }
+ if ( Gia_ManRegNum(pAig) == 0 )
+ {
+ Abc_Print( 1, "Cec_ManSeqSemiformal(): Not a sequential AIG.\n" );
+ return -1;
+ }
+ Gia_ManRandom( 1 );
+ // prepare starting pattern
+ pState = Abc_CexAlloc( Gia_ManRegNum(pAig), 0, 0 );
+ pState->iFrame = -1;
+ pState->iPo = -1;
+ // prepare SAT solving
+ Cec_ManSatSetDefaultParams( pParsSat );
+ pParsSat->nBTLimit = pPars->nBTLimit;
+ pParsSat->fVerbose = pPars->fVerbose;
+ if ( pParsSat->fVerbose )
+ {
+ Abc_Print( 1, "Starting: " );
+ Gia_ManEquivPrintClasses( pAig, 0, 0 );
+ }
+ // perform the given number of BMC rounds
+ Gia_ManCleanMark0( pAig );
+ for ( r = 0; r < pPars->nRounds; r++ )
+ {
+ if ( !Cec_ManCheckNonTrivialCands(pAig) )
+ {
+ Abc_Print( 1, "Cec_ManSeqSemiformal: There are only trivial equiv candidates left (PO drivers). Quitting.\n" );
+ break;
+ }
+// 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 );
+ if ( pSrm == NULL )
+ {
+ Abc_Print( 1, "Quitting refinement because miter could not be unrolled.\n" );
+ break;
+ }
+ assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == (Gia_ManPiNum(pAig) * nFramesReal) );
+ if ( pPars->fVerbose )
+ Abc_Print( 1, "Unrolled for %d frames.\n", nFramesReal );
+ // allocate room for simulation info
+ vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) +
+ Gia_ManPiNum(pAig) * (nFramesReal + nAddFrames), pPars->nWords );
+ Cec_ManSeqDeriveInfoInitRandom( vSimInfo, pAig, pState );
+ // fill in simulation info with counter-examples
+ vStatus = Cec_ManSatSolveSeq( vSimInfo, pSrm, pParsSat, Gia_ManRegNum(pAig), &nPats );
+ Vec_StrFree( vStatus );
+ Gia_ManStop( pSrm );
+ // resimulate and refine the classes
+ RetValue = Cec_ManSeqResimulateInfo( pAig, vSimInfo, pState, pPars->fCheckMiter );
+ Vec_PtrFree( vSimInfo );
+ assert( pState->iPo >= 0 ); // hit counter
+ pState->iPo = -1;
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "BMC = %3d ", nPats );
+ Gia_ManEquivPrintClasses( pAig, 0, 0 );
+ }
+
+ // write equivalence classes
+ Gia_WriteAiger( pAig, "gore.aig", 0, 0 );
+ // reduce the model
+ pReduce = Gia_ManSpecReduce( pAig, 0, 0, 1, 0, 0 );
+ if ( pReduce )
+ {
+ pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 );
+ Gia_ManStop( pAux );
+ Gia_WriteAiger( pReduce, "gsrm.aig", 0, 0 );
+// Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", "gsrm.aig" );
+// Gia_ManPrintStatsShort( pReduce );
+ Gia_ManStop( pReduce );
+ }
+
+ if ( RetValue )
+ {
+ Abc_Print( 1, "Cec_ManSeqSemiformal(): An output of the miter is asserted. Refinement stopped.\n" );
+ break;
+ }
+ // decide when to stop
+ if ( nPats > 0 )
+ nCountNoRef = 0;
+ else if ( ++nCountNoRef == pPars->nNonRefines )
+ break;
+ }
+ ABC_FREE( pState );
+ if ( pPars->fCheckMiter )
+ {
+ int nNonConsts = Cec_ManCountNonConstOutputs( pAig );
+ if ( nNonConsts )
+ Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts );
+ }
+ return RetValue;
+}
+
+//&r s13207.aig; &ps; &equiv; &ps; &semi -R 2 -vm
+//&r bug/50/temp.aig; &ps; &equiv -smv; &semi -v
+//r mentor/1_05c.blif; st; &get; &ps; &equiv -smv; &semi -mv
+//&r bug/50/hdl1.aig; &ps; &equiv -smv; &semi -mv; &srm; &r gsrm.aig; &ps
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSim.c b/src/proof/cec/cecSim.c
new file mode 100644
index 00000000..92f8fc2e
--- /dev/null
+++ b/src/proof/cec/cecSim.c
@@ -0,0 +1,53 @@
+/**CFile****************************************************************
+
+ FileName [cecSim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Simulation manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSolve.c b/src/proof/cec/cecSolve.c
new file mode 100644
index 00000000..bd7202e4
--- /dev/null
+++ b/src/proof/cec/cecSolve.c
@@ -0,0 +1,1023 @@
+/**CFile****************************************************************
+
+ FileName [cecSolve.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Performs one round of SAT solving.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSolve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Cec_ObjSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj ) { return p->pSatVars[Gia_ObjId(p->pAig,pObj)]; }
+static inline void Cec_ObjSetSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj, int Num ) { p->pSatVars[Gia_ObjId(p->pAig,pObj)] = Num; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns value of the SAT variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ return sat_solver_var_value( p->pSat, Cec_ObjSatNum(p, pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_AddClausesMux( Cec_ManSat_t * p, Gia_Obj_t * pNode )
+{
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( Gia_ObjIsMuxType( pNode ) );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Cec_ObjSatNum(p,pNode);
+ VarI = Cec_ObjSatNum(p,pNodeI);
+ VarT = Cec_ObjSatNum(p,Gia_Regular(pNodeT));
+ VarE = Cec_ObjSatNum(p,Gia_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Gia_IsComplement(pNodeT);
+ fCompE = Gia_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 1^fCompT);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 0^fCompT);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+
+ // two additional clauses
+ // t' & e' -> f'
+ // t & e -> f
+
+ // t + e + f'
+ // t' + e' + f
+
+ if ( VarT == VarE )
+ {
+// assert( fCompT == !fCompE );
+ return;
+ }
+
+ pLits[0] = toLitCond(VarT, 0^fCompT);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarT, 1^fCompT);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper )
+{
+ Gia_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsAnd( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ABC_ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = toLitCond(Cec_ObjSatNum(p,pNode), 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = toLitCond(Cec_ObjSatNum(p,pNode), 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||
+ (!fFirst && Gia_ObjValue(pObj) > 1) ||
+ (fUseMuxes && Gia_ObjIsMuxType(pObj)) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Cec_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Cec_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Cec_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ObjAddToFrontier( Cec_ManSat_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier )
+{
+ assert( !Gia_IsComplement(pObj) );
+ if ( Cec_ObjSatNum(p,pObj) )
+ return;
+ assert( Cec_ObjSatNum(p,pObj) == 0 );
+ if ( Gia_ObjIsConst0(pObj) )
+ return;
+ Vec_PtrPush( p->vUsedNodes, pObj );
+ Cec_ObjSetSatNum( p, pObj, p->nSatVars++ );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ Vec_Ptr_t * vFrontier;
+ Gia_Obj_t * pNode, * pFanin;
+ int i, k, fUseMuxes = 1;
+ // quit if CNF is ready
+ if ( Cec_ObjSatNum(p,pObj) )
+ return;
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_PtrPush( p->vUsedNodes, pObj );
+ Cec_ObjSetSatNum( p, pObj, p->nSatVars++ );
+ sat_solver_setnvars( p->pSat, p->nSatVars );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ // start the frontier
+ vFrontier = Vec_PtrAlloc( 100 );
+ Cec_ObjAddToFrontier( p, pObj, vFrontier );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Cec_ObjSatNum(p,pNode) );
+ if ( fUseMuxes && Gia_ObjIsMuxType(pNode) )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier );
+ Cec_AddClausesMux( p, pNode );
+ }
+ else
+ {
+ Cec_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier );
+ Cec_AddClausesSuper( p, pNode, p->vFanins );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ Vec_PtrFree( vFrontier );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatSolverRecycle( Cec_ManSat_t * p )
+{
+ int Lit;
+ if ( p->pSat )
+ {
+ Gia_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vUsedNodes, pObj, i )
+ Cec_ObjSetSatNum( p, pObj, 0 );
+ Vec_PtrClear( p->vUsedNodes );
+// memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) );
+ sat_solver_delete( p->pSat );
+ }
+ p->pSat = sat_solver_new();
+ p->pSat->factors = ABC_CALLOC( double, 1 );
+ sat_solver_setnvars( p->pSat, 1000 );
+ // var 0 is not used
+ // var 1 is reserved for const0 node - add the clause
+ p->nSatVars = 1;
+// p->nSatVars = 0;
+ Lit = toLitCond( p->nSatVars, 1 );
+ if ( p->pPars->fPolarFlip )
+ Lit = lit_neg( Lit );
+ sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
+ Cec_ObjSetSatNum( p, Gia_ManConst0(p->pAig), p->nSatVars++ );
+
+ p->nRecycles++;
+ p->nCallsSince = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets variable activities in the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMin, int LevelMax )
+{
+ float dActConeBumpMax = 20.0;
+ int iVar;
+ // skip visited variables
+ if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p->pAig, pObj);
+ // add the PI to the list
+ if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) )
+ return;
+ // set the factor of this variable
+ // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump
+ if ( (iVar = Cec_ObjSatNum(p,pObj)) )
+ {
+ p->pSat->factors[iVar] = dActConeBumpMax * (Gia_ObjLevel(p->pAig, pObj) - LevelMin)/(LevelMax - LevelMin);
+ veci_push(&p->pSat->act_vars, iVar);
+ }
+ // explore the fanins
+ Cec_SetActivityFactors_rec( p, Gia_ObjFanin0(pObj), LevelMin, LevelMax );
+ Cec_SetActivityFactors_rec( p, Gia_ObjFanin1(pObj), LevelMin, LevelMax );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets variable activities in the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ float dActConeRatio = 0.5;
+ int LevelMin, LevelMax;
+ // reset the active variables
+ veci_resize(&p->pSat->act_vars, 0);
+ // prepare for traversal
+ Gia_ManIncrementTravId( p->pAig );
+ // determine the min and max level to visit
+ assert( dActConeRatio > 0 && dActConeRatio < 1 );
+ LevelMax = Gia_ObjLevel(p->pAig,pObj);
+ LevelMin = (int)(LevelMax * (1.0 - dActConeRatio));
+ // traverse
+ Cec_SetActivityFactors_rec( p, pObj, LevelMin, LevelMax );
+//Cec_PrintActivity( p );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Runs equivalence test for the two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pObjR = Gia_Regular(pObj);
+ int nBTLimit = p->pPars->nBTLimit;
+ int Lit, RetValue, status, clk, clk2, nConflicts;
+
+ if ( pObj == Gia_ManConst0(p->pAig) )
+ return 1;
+ if ( pObj == Gia_ManConst1(p->pAig) )
+ {
+ assert( 0 );
+ return 0;
+ }
+
+ p->nCallsSince++; // experiment with this!!!
+ p->nSatTotal++;
+
+ // check if SAT solver needs recycling
+ if ( p->pSat == NULL ||
+ (p->pPars->nSatVarMax &&
+ p->nSatVars > p->pPars->nSatVarMax &&
+ p->nCallsSince > p->pPars->nCallsRecycle) )
+ Cec_ManSatSolverRecycle( p );
+
+ // if the nodes do not have SAT variables, allocate them
+clk2 = clock();
+ Cec_CnfNodeAddToSolver( p, pObjR );
+//ABC_PRT( "cnf", clock() - clk2 );
+//Abc_Print( 1, "%d \n", p->pSat->size );
+
+clk2 = clock();
+// Cec_SetActivityFactors( p, pObjR );
+//ABC_PRT( "act", clock() - clk2 );
+
+ // propage unit clauses
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ status = sat_solver_simplify(p->pSat);
+ assert( status != 0 );
+ assert( p->pSat->qtail == p->pSat->qhead );
+ }
+
+ // solve under assumptions
+ // A = 1; B = 0 OR A = 1; B = 1
+ Lit = toLitCond( Cec_ObjSatNum(p,pObjR), Gia_IsComplement(pObj) );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pObjR->fPhase ) Lit = lit_neg( Lit );
+ }
+//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
+clk = clock();
+ nConflicts = p->pSat->stats.conflicts;
+
+clk2 = clock();
+ RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1,
+ (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+//ABC_PRT( "sat", clock() - clk2 );
+
+ if ( RetValue == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ Lit = lit_neg( Lit );
+ RetValue = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
+ assert( RetValue );
+ p->nSatUnsat++;
+ p->nConfUnsat += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return 1;
+ }
+ else if ( RetValue == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatSat++;
+ p->nConfSat += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return 0;
+ }
+ else // if ( RetValue == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatUndec++;
+ p->nConfUndec += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return -1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs equivalence test for the two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManSatCheckNodeTwo( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 )
+{
+ Gia_Obj_t * pObjR1 = Gia_Regular(pObj1);
+ Gia_Obj_t * pObjR2 = Gia_Regular(pObj2);
+ int nBTLimit = p->pPars->nBTLimit;
+ int Lits[2], RetValue, status, clk, clk2, nConflicts;
+
+ if ( pObj1 == Gia_ManConst0(p->pAig) || pObj2 == Gia_ManConst0(p->pAig) || pObj1 == Gia_Not(pObj2) )
+ return 1;
+ if ( pObj1 == Gia_ManConst1(p->pAig) && (pObj2 == NULL || pObj2 == Gia_ManConst1(p->pAig)) )
+ {
+ assert( 0 );
+ return 0;
+ }
+
+ p->nCallsSince++; // experiment with this!!!
+ p->nSatTotal++;
+
+ // check if SAT solver needs recycling
+ if ( p->pSat == NULL ||
+ (p->pPars->nSatVarMax &&
+ p->nSatVars > p->pPars->nSatVarMax &&
+ p->nCallsSince > p->pPars->nCallsRecycle) )
+ Cec_ManSatSolverRecycle( p );
+
+ // if the nodes do not have SAT variables, allocate them
+clk2 = clock();
+ Cec_CnfNodeAddToSolver( p, pObjR1 );
+ Cec_CnfNodeAddToSolver( p, pObjR2 );
+//ABC_PRT( "cnf", clock() - clk2 );
+//Abc_Print( 1, "%d \n", p->pSat->size );
+
+clk2 = clock();
+// Cec_SetActivityFactors( p, pObjR1 );
+// Cec_SetActivityFactors( p, pObjR2 );
+//ABC_PRT( "act", clock() - clk2 );
+
+ // propage unit clauses
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ status = sat_solver_simplify(p->pSat);
+ assert( status != 0 );
+ assert( p->pSat->qtail == p->pSat->qhead );
+ }
+
+ // solve under assumptions
+ // A = 1; B = 0 OR A = 1; B = 1
+ Lits[0] = toLitCond( Cec_ObjSatNum(p,pObjR1), Gia_IsComplement(pObj1) );
+ Lits[1] = toLitCond( Cec_ObjSatNum(p,pObjR2), Gia_IsComplement(pObj2) );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pObjR1->fPhase ) Lits[0] = lit_neg( Lits[0] );
+ if ( pObjR2->fPhase ) Lits[1] = lit_neg( Lits[1] );
+ }
+//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
+clk = clock();
+ nConflicts = p->pSat->stats.conflicts;
+
+clk2 = clock();
+ RetValue = sat_solver_solve( p->pSat, Lits, Lits + 2,
+ (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+//ABC_PRT( "sat", clock() - clk2 );
+
+ if ( RetValue == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ Lits[0] = lit_neg( Lits[0] );
+ Lits[1] = lit_neg( Lits[1] );
+ RetValue = sat_solver_addclause( p->pSat, Lits, Lits + 2 );
+ assert( RetValue );
+ p->nSatUnsat++;
+ p->nConfUnsat += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return 1;
+ }
+ else if ( RetValue == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatSat++;
+ p->nConfSat += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return 0;
+ }
+ else // if ( RetValue == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatUndec++;
+ p->nConfUndec += p->pSat->stats.conflicts - nConflicts;
+//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts );
+ return -1;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of solving for the POs of the AIG.]
+
+ Description [Labels the nodes that have been proved (pObj->fMark1)
+ and returns the set of satisfying assignments.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Cec_ManSat_t * p;
+ Gia_Obj_t * pObj;
+ int i, status, clk = clock(), clk2;
+ // reset the manager
+ if ( pPat )
+ {
+ pPat->iStart = Vec_StrSize(pPat->vStorage);
+ pPat->nPats = 0;
+ pPat->nPatLits = 0;
+ pPat->nPatLitsMin = 0;
+ }
+ Gia_ManSetPhase( pAig );
+ Gia_ManLevelNum( pAig );
+ Gia_ManIncrementTravId( pAig );
+ p = Cec_ManSatCreate( pAig, pPars );
+ pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );
+ Gia_ManForEachCo( pAig, pObj, i )
+ {
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ {
+ pObj->fMark0 = 0;
+ pObj->fMark1 = 1;
+ continue;
+ }
+ Bar_ProgressUpdate( pProgress, i, "SAT..." );
+clk2 = clock();
+ status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) );
+ pObj->fMark0 = (status == 0);
+ pObj->fMark1 = (status == 1);
+/*
+ if ( status == -1 )
+ {
+ Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj );
+ Gia_WriteAiger( pTemp, "gia_hard.aig", 0, 0 );
+ Gia_ManStop( pTemp );
+ Abc_Print( 1, "Dumping hard cone into file \"%s\".\n", "gia_hard.aig" );
+ }
+*/
+ if ( status != 0 )
+ continue;
+ // save the pattern
+ if ( pPat )
+ {
+ int clk3 = clock();
+ Cec_ManPatSavePattern( pPat, p, pObj );
+ pPat->timeTotalSave += clock() - clk3;
+ }
+ // quit if one of them is solved
+ if ( pPars->fCheckMiter )
+ break;
+ }
+ p->timeTotal = clock() - clk;
+ Bar_ProgressStop( pProgress );
+ if ( pPars->fVerbose )
+ Cec_ManSatPrintStats( p );
+ Cec_ManSatStop( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the pattern stored.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * pSat )
+{
+ return pSat->vCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Save values in the cone of influence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vInfo, int iPat, int nRegs )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ unsigned * pInfo = (unsigned *)Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) );
+ if ( Cec_ObjSatVarValue( pSat, pObj ) != Abc_InfoHasBit( pInfo, iPat ) )
+ Abc_InfoXorBit( pInfo, iPat );
+ pSat->nCexLits++;
+// Vec_IntPush( pSat->vCex, Abc_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec_ManSatSolveSeq_rec( pSat, p, Gia_ObjFanin0(pObj), vInfo, iPat, nRegs );
+ Cec_ManSatSolveSeq_rec( pSat, p, Gia_ObjFanin1(pObj), vInfo, iPat, nRegs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of solving for the POs of the AIG.]
+
+ Description [Labels the nodes that have been proved (pObj->fMark1)
+ and returns the set of satisfying assignments.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Vec_Str_t * vStatus;
+ Cec_ManSat_t * p;
+ Gia_Obj_t * pObj;
+ int iPat = 0, nPatsInit, nPats;
+ int i, status, clk = clock();
+ nPatsInit = nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts);
+ Gia_ManSetPhase( pAig );
+ Gia_ManLevelNum( pAig );
+ Gia_ManIncrementTravId( pAig );
+ p = Cec_ManSatCreate( pAig, pPars );
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );
+ Gia_ManForEachCo( pAig, pObj, i )
+ {
+ Bar_ProgressUpdate( pProgress, i, "SAT..." );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ {
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+// Abc_Print( 1, "Constant 1 output of SRM!!!\n" );
+ Vec_StrPush( vStatus, 0 );
+ }
+ else
+ {
+// Abc_Print( 1, "Constant 0 output of SRM!!!\n" );
+ Vec_StrPush( vStatus, 1 );
+ }
+ continue;
+ }
+ status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) );
+//Abc_Print( 1, "output %d status = %d\n", i, status );
+ Vec_StrPush( vStatus, (char)status );
+ if ( status != 0 )
+ continue;
+ // resize storage
+ if ( iPat == nPats )
+ {
+ int nWords = Vec_PtrReadWordsSimInfo(vPatts);
+ Vec_PtrReallocSimInfo( vPatts );
+ Vec_PtrCleanSimInfo( vPatts, nWords, 2*nWords );
+ nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts);
+ }
+ if ( iPat % nPatsInit == 0 )
+ iPat++;
+ // save the pattern
+ Gia_ManIncrementTravId( pAig );
+// Vec_IntClear( p->vCex );
+ Cec_ManSatSolveSeq_rec( p, pAig, Gia_ObjFanin0(pObj), vPatts, iPat++, nRegs );
+// Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits );
+// Cec_ManSatAddToStore( p->vCexStore, p->vCex );
+// if ( iPat == nPats )
+// break;
+ // quit if one of them is solved
+// if ( pPars->fFirstStop )
+// break;
+// if ( iPat == 32 * 15 * 16 - 1 )
+// break;
+ }
+ p->timeTotal = clock() - clk;
+ Bar_ProgressStop( pProgress );
+ if ( pPars->fVerbose )
+ Cec_ManSatPrintStats( p );
+// Abc_Print( 1, "Total number of cex literals = %d. (Ave = %d)\n", p->nCexLits, p->nCexLits/p->nSatSat );
+ Cec_ManSatStop( p );
+ if ( pnPats )
+ *pnPats = iPat-1;
+ return vStatus;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Save values in the cone of influence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out )
+{
+ int i, Entry;
+ Vec_IntPush( vCexStore, Out );
+ if ( vCex == NULL ) // timeout
+ {
+ Vec_IntPush( vCexStore, -1 );
+ return;
+ }
+ // write the counter-example
+ Vec_IntPush( vCexStore, Vec_IntSize(vCex) );
+ Vec_IntForEachEntry( vCex, Entry, i )
+ Vec_IntPush( vCexStore, Entry );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Save values in the cone of influence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSatSolveMiter_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pSat->nCexLits++;
+ Vec_IntPush( pSat->vCex, Abc_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin0(pObj) );
+ Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Save patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 )
+{
+ Vec_IntClear( p->vCex );
+ Gia_ManIncrementTravId( p->pAig );
+ Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj1) );
+ if ( pObj2 )
+ Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj2) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of solving for the POs of the AIG.]
+
+ Description [Labels the nodes that have been proved (pObj->fMark1)
+ and returns the set of satisfying assignments.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Vec_Int_t * vCexStore;
+ Vec_Str_t * vStatus;
+ Cec_ManSat_t * p;
+ Gia_Obj_t * pObj;
+ int i, status, clk = clock();
+ // prepare AIG
+ Gia_ManSetPhase( pAig );
+ Gia_ManLevelNum( pAig );
+ Gia_ManIncrementTravId( pAig );
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ // perform solving
+ p = Cec_ManSatCreate( pAig, pPars );
+ pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );
+ Gia_ManForEachCo( pAig, pObj, i )
+ {
+ Vec_IntClear( p->vCex );
+ Bar_ProgressUpdate( pProgress, i, "SAT..." );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ {
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+// Abc_Print( 1, "Constant 1 output of SRM!!!\n" );
+ Cec_ManSatAddToStore( vCexStore, p->vCex, i ); // trivial counter-example
+ Vec_StrPush( vStatus, 0 );
+ }
+ else
+ {
+// Abc_Print( 1, "Constant 0 output of SRM!!!\n" );
+ Vec_StrPush( vStatus, 1 );
+ }
+ continue;
+ }
+ status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) );
+ Vec_StrPush( vStatus, (char)status );
+ if ( status == -1 )
+ {
+ Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
+ continue;
+ }
+ if ( status == 1 )
+ continue;
+ assert( status == 0 );
+ // save the pattern
+// Gia_ManIncrementTravId( pAig );
+// Cec_ManSatSolveMiter_rec( p, pAig, Gia_ObjFanin0(pObj) );
+ Cec_ManSavePattern( p, Gia_ObjFanin0(pObj), NULL );
+// Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits );
+ Cec_ManSatAddToStore( vCexStore, p->vCex, i );
+ }
+ p->timeTotal = clock() - clk;
+ Bar_ProgressStop( pProgress );
+// if ( pPars->fVerbose )
+// Cec_ManSatPrintStats( p );
+ Cec_ManSatStop( p );
+ *pvStatus = vStatus;
+ return vCexStore;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSweep.c b/src/proof/cec/cecSweep.c
new file mode 100644
index 00000000..4523810e
--- /dev/null
+++ b/src/proof/cec/cecSweep.c
@@ -0,0 +1,299 @@
+/**CFile****************************************************************
+
+ FileName [cecSweep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [SAT sweeping manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSweep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs limited speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr = NULL;
+ int iRes0, iRes1, iRepr, iNode, iMiter;
+ int i, fCompl, * piCopies, * pDepths;
+ Gia_ManSetPhase( p->pAig );
+ Vec_IntClear( p->vXorNodes );
+ if ( p->pPars->nLevelMax )
+ Gia_ManLevelNum( p->pAig );
+ pNew = Gia_ManStart( Gia_ManObjNum(p->pAig) );
+ pNew->pName = Abc_UtilStrsav( p->pAig->pName );
+ Gia_ManHashAlloc( pNew );
+ piCopies = ABC_FALLOC( int, Gia_ManObjNum(p->pAig) );
+ pDepths = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
+ piCopies[0] = 0;
+ Gia_ManForEachObj1( p->pAig, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ piCopies[i] = Gia_ManAppendCi( pNew );
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ if ( piCopies[Gia_ObjFaninId0(pObj,i)] == -1 ||
+ piCopies[Gia_ObjFaninId1(pObj,i)] == -1 )
+ continue;
+ iRes0 = Abc_LitNotCond( piCopies[Gia_ObjFaninId0(pObj,i)], Gia_ObjFaninC0(pObj) );
+ iRes1 = Abc_LitNotCond( piCopies[Gia_ObjFaninId1(pObj,i)], Gia_ObjFaninC1(pObj) );
+ iNode = piCopies[i] = Gia_ManHashAnd( pNew, iRes0, iRes1 );
+ pDepths[i] = Abc_MaxInt( pDepths[Gia_ObjFaninId0(pObj,i)], pDepths[Gia_ObjFaninId1(pObj,i)] );
+ if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID || Gia_ObjFailed(p->pAig, i) )
+ continue;
+ assert( Gia_ObjRepr(p->pAig, i) < i );
+ iRepr = piCopies[Gia_ObjRepr(p->pAig, i)];
+ if ( iRepr == -1 )
+ continue;
+ if ( Abc_LitRegular(iNode) == Abc_LitRegular(iRepr) )
+ continue;
+ if ( p->pPars->nLevelMax &&
+ (Gia_ObjLevel(p->pAig, pObj) > p->pPars->nLevelMax ||
+ Gia_ObjLevel(p->pAig, pRepr) > p->pPars->nLevelMax) )
+ continue;
+ if ( p->pPars->fDualOut )
+ {
+// if ( i % 1000 == 0 && Gia_ObjRepr(p->pAig, i) )
+// Gia_ManEquivPrintOne( p->pAig, Gia_ObjRepr(p->pAig, i), 0 );
+ if ( p->pPars->fColorDiff )
+ {
+ if ( !Gia_ObjDiffColors( p->pAig, Gia_ObjRepr(p->pAig, i), i ) )
+ continue;
+ }
+ else
+ {
+ if ( !Gia_ObjDiffColors2( p->pAig, Gia_ObjRepr(p->pAig, i), i ) )
+ continue;
+ }
+ }
+ pRepr = Gia_ManObj( p->pAig, Gia_ObjRepr(p->pAig, i) );
+ fCompl = Gia_ObjPhaseReal(pObj) ^ Gia_ObjPhaseReal(pRepr);
+ piCopies[i] = Abc_LitNotCond( iRepr, fCompl );
+ if ( Gia_ObjProved(p->pAig, i) )
+ continue;
+ // produce speculative miter
+ iMiter = Gia_ManHashXor( pNew, iNode, piCopies[i] );
+ Gia_ManAppendCo( pNew, iMiter );
+ Vec_IntPush( p->vXorNodes, Gia_ObjRepr(p->pAig, i) );
+ Vec_IntPush( p->vXorNodes, i );
+ // add to the depth of this node
+ pDepths[i] = 1 + Abc_MaxInt( pDepths[i], pDepths[Gia_ObjRepr(p->pAig, i)] );
+ if ( p->pPars->nDepthMax && pDepths[i] >= p->pPars->nDepthMax )
+ piCopies[i] = -1;
+ }
+ ABC_FREE( piCopies );
+ ABC_FREE( pDepths );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, 0 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManFraClassesUpdate_rec( Gia_Obj_t * pObj )
+{
+ int Result;
+ if ( pObj->fMark0 )
+ return 1;
+ if ( Gia_ObjIsCi(pObj) || Gia_ObjIsConst0(pObj) )
+ return 0;
+ Result = (Cec_ManFraClassesUpdate_rec( Gia_ObjFanin0(pObj) ) |
+ Cec_ManFraClassesUpdate_rec( Gia_ObjFanin1(pObj) ));
+ return pObj->fMark0 = Result;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates simulation info for this round.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vInfo, int nSeries )
+{
+ unsigned * pRes0, * pRes1;
+ int i, w;
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ {
+ pRes0 = (unsigned *)Vec_PtrEntry( vCiInfo, i );
+ pRes1 = (unsigned *)Vec_PtrEntry( vInfo, i );
+ pRes1 += p->nWords * nSeries;
+ for ( w = 0; w < p->nWords; w++ )
+ pRes0[w] = pRes1[w];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates equivalence classes using the patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew )
+{
+ Vec_Ptr_t * vInfo;
+ Gia_Obj_t * pObj, * pObjOld, * pReprOld;
+ int i, k, iRepr, iNode, clk;
+clk = clock();
+ vInfo = Cec_ManPatCollectPatterns( pPat, Gia_ManCiNum(p->pAig), pSim->nWords );
+p->timePat += clock() - clk;
+clk = clock();
+ if ( vInfo != NULL )
+ {
+ Gia_ManSetRefs( p->pAig );
+ for ( i = 0; i < pPat->nSeries; i++ )
+ {
+ Cec_ManFraCreateInfo( pSim, pSim->vCiSimInfo, vInfo, i );
+ if ( Cec_ManSimSimulateRound( pSim, pSim->vCiSimInfo, pSim->vCoSimInfo ) )
+ {
+ Vec_PtrFree( vInfo );
+ return 1;
+ }
+ }
+ Vec_PtrFree( vInfo );
+ }
+p->timeSim += clock() - clk;
+ assert( Vec_IntSize(p->vXorNodes) == 2*Gia_ManCoNum(pNew) );
+ // mark the transitive fanout of failed nodes
+ if ( p->pPars->nDepthMax != 1 )
+ {
+ Gia_ManCleanMark0( p->pAig );
+ Gia_ManCleanMark1( p->pAig );
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
+ continue;
+// Gia_ManObj(p->pAig, iRepr)->fMark0 = 1;
+ Gia_ManObj(p->pAig, iNode)->fMark0 = 1;
+ }
+ // mark the nodes reachable through the failed nodes
+ Gia_ManForEachAnd( p->pAig, pObjOld, k )
+ pObjOld->fMark0 |= (Gia_ObjFanin0(pObjOld)->fMark0 | Gia_ObjFanin1(pObjOld)->fMark0);
+ // unmark the disproved nodes
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ if ( pObj->fMark0 == 0 && pObj->fMark1 == 1 ) // proved
+ continue;
+ pObjOld = Gia_ManObj(p->pAig, iNode);
+ assert( pObjOld->fMark0 == 1 );
+ if ( Gia_ObjFanin0(pObjOld)->fMark0 == 0 && Gia_ObjFanin1(pObjOld)->fMark0 == 0 )
+ pObjOld->fMark1 = 1;
+ }
+ // clean marks
+ Gia_ManForEachAnd( p->pAig, pObjOld, k )
+ if ( pObjOld->fMark1 )
+ {
+ pObjOld->fMark0 = 0;
+ pObjOld->fMark1 = 0;
+ }
+ }
+ // set the results
+ p->nAllProved = p->nAllDisproved = p->nAllFailed = 0;
+ Gia_ManForEachCo( pNew, pObj, k )
+ {
+ iRepr = Vec_IntEntry( p->vXorNodes, 2*k );
+ iNode = Vec_IntEntry( p->vXorNodes, 2*k+1 );
+ pReprOld = Gia_ManObj(p->pAig, iRepr);
+ pObjOld = Gia_ManObj(p->pAig, iNode);
+ if ( pObj->fMark1 )
+ { // proved
+ assert( pObj->fMark0 == 0 );
+ assert( !Gia_ObjProved(p->pAig, iNode) );
+ if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
+// if ( pObjOld->fMark0 == 0 )
+ {
+ assert( iRepr == Gia_ObjRepr(p->pAig, iNode) );
+ Gia_ObjSetProved( p->pAig, iNode );
+ p->nAllProved++;
+ }
+ }
+ else if ( pObj->fMark0 )
+ { // disproved
+ assert( pObj->fMark1 == 0 );
+ if ( pReprOld->fMark0 == 0 && pObjOld->fMark0 == 0 )
+// if ( pObjOld->fMark0 == 0 )
+ {
+ if ( iRepr == Gia_ObjRepr(p->pAig, iNode) )
+ Abc_Print( 1, "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" );
+ p->nAllDisproved++;
+ }
+ }
+ else
+ { // failed
+ assert( pObj->fMark0 == 0 );
+ assert( pObj->fMark1 == 0 );
+ assert( !Gia_ObjFailed(p->pAig, iNode) );
+ assert( !Gia_ObjProved(p->pAig, iNode) );
+ Gia_ObjSetFailed( p->pAig, iNode );
+ p->nAllFailed++;
+ }
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSynth.c b/src/proof/cec/cecSynth.c
new file mode 100644
index 00000000..21470dd4
--- /dev/null
+++ b/src/proof/cec/cecSynth.c
@@ -0,0 +1,380 @@
+/**CFile****************************************************************
+
+ FileName [cecSynth.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Partitioned sequential synthesis.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSynth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+#include "src/aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Populate sequential synthesis parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * p )
+{
+ memset( p, 0, sizeof(Cec_ParSeq_t) );
+ p->fUseLcorr = 0; // enables latch correspondence
+ p->fUseScorr = 0; // enables signal correspondence
+ p->nBTLimit = 1000; // (scorr/lcorr) conflict limit at a node
+ p->nFrames = 1; // (scorr only) the number of timeframes
+ p->nLevelMax = -1; // (scorr only) the max number of levels
+ p->fConsts = 1; // (scl only) merging constants
+ p->fEquivs = 1; // (scl only) merging equivalences
+ p->fUseMiniSat = 0; // enables MiniSat in lcorr/scorr
+ p->nMinDomSize = 100; // the size of minimum clock domain
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p )
+{
+ return p->nMinDomSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_SeqReadVerbose( Cec_ParSeq_t * p )
+{
+ return p->fVerbose;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes partitioning of registers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManRegCreatePart( Gia_Man_t * p, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vNodes, * vRoots;
+ int i, iOut, nCountPis, nCountRegs;
+ int * pMapBack;
+ // collect/mark nodes/PIs in the DFS order from the roots
+ Gia_ManIncrementTravId( p );
+ vRoots = Vec_IntAlloc( Vec_IntSize(vPart) );
+ Vec_IntForEachEntry( vPart, iOut, i )
+ Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ManCo(p, Gia_ManPoNum(p)+iOut)) );
+ vNodes = Gia_ManCollectNodesCis( p, Vec_IntArray(vRoots), Vec_IntSize(vRoots) );
+ Vec_IntFree( vRoots );
+ // unmark register outputs
+ Vec_IntForEachEntry( vPart, iOut, i )
+ Gia_ObjSetTravIdPrevious( p, Gia_ManCi(p, Gia_ManPiNum(p)+iOut) );
+ // count pure PIs
+ nCountPis = nCountRegs = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ nCountPis += Gia_ObjIsTravIdCurrent(p, pObj);
+ // count outputs of other registers
+ Gia_ManForEachRo( p, pObj, i )
+ nCountRegs += Gia_ObjIsTravIdCurrent(p, pObj); // should be !Gia_... ???
+ if ( pnCountPis )
+ *pnCountPis = nCountPis;
+ if ( pnCountRegs )
+ *pnCountRegs = nCountRegs;
+ // clean old manager
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ // create the new manager
+ pNew = Gia_ManStart( Vec_IntSize(vNodes) );
+ // create the PIs
+ Gia_ManForEachCi( p, pObj, i )
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // add variables for the register outputs
+ // create fake POs to hold the register outputs
+ Vec_IntForEachEntry( vPart, iOut, i )
+ {
+ pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut);
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjSetTravIdCurrent( p, pObj ); // added
+ }
+ // create the nodes
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // add real POs for the registers
+ Vec_IntForEachEntry( vPart, iOut, i )
+ {
+ pObj = Gia_ManCo( p, Gia_ManPoNum(p)+iOut );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManSetRegNum( pNew, Vec_IntSize(vPart) );
+ // create map
+ if ( ppMapBack )
+ {
+ pMapBack = ABC_FALLOC( int, Gia_ManObjNum(pNew) );
+ // map constant nodes
+ pMapBack[0] = 0;
+ // logic cones of register outputs
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ {
+// pObjNew = Aig_Regular(pObj->pData);
+// pMapBack[pObjNew->Id] = pObj->Id;
+ assert( Abc_Lit2Var(Gia_ObjValue(pObj)) >= 0 );
+ assert( Abc_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) );
+ pMapBack[ Abc_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj);
+ }
+ // map register outputs
+ Vec_IntForEachEntry( vPart, iOut, i )
+ {
+ pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut);
+// pObjNew = pObj->pData;
+// pMapBack[pObjNew->Id] = pObj->Id;
+ assert( Abc_Lit2Var(Gia_ObjValue(pObj)) >= 0 );
+ assert( Abc_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) );
+ pMapBack[ Abc_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj);
+ }
+ *ppMapBack = pMapBack;
+ }
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_TransferMappedClasses( Gia_Man_t * pPart, int * pMapBack, int * pReprs )
+{
+ Gia_Obj_t * pObj;
+ int i, Id1, Id2, nClasses;
+ if ( pPart->pReprs == NULL )
+ return 0;
+ nClasses = 0;
+ Gia_ManForEachObj( pPart, pObj, i )
+ {
+ if ( Gia_ObjRepr(pPart, i) == GIA_VOID )
+ continue;
+ assert( i < Gia_ManObjNum(pPart) );
+ assert( Gia_ObjRepr(pPart, i) < Gia_ManObjNum(pPart) );
+ Id1 = pMapBack[ i ];
+ Id2 = pMapBack[ Gia_ObjRepr(pPart, i) ];
+ if ( Id1 == Id2 )
+ continue;
+ if ( Id1 < Id2 )
+ pReprs[Id2] = Id1;
+ else
+ pReprs[Id1] = Id2;
+ nClasses++;
+ }
+ return nClasses;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManFindRepr_rec( int * pReprs, int Id )
+{
+ if ( pReprs[Id] == 0 )
+ return 0;
+ if ( pReprs[Id] == ~0 )
+ return Id;
+ return Gia_ManFindRepr_rec( pReprs, pReprs[Id] );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Normalizes equivalences.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManNormalizeEquivalences( Gia_Man_t * p, int * pReprs )
+{
+ int i, iRepr;
+ assert( p->pReprs == NULL );
+ assert( p->pNexts == NULL );
+ p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ Gia_ObjSetRepr( p, i, GIA_VOID );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( pReprs[i] == ~0 )
+ continue;
+ iRepr = Gia_ManFindRepr_rec( pReprs, i );
+ Gia_ObjSetRepr( p, i, iRepr );
+ }
+ p->pNexts = Gia_ManDeriveNexts( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Partitioned sequential synthesis.]
+
+ Description [Returns AIG annotated with equivalence classes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars )
+{
+ int fPrintParts = 0;
+ char Buffer[100];
+ Gia_Man_t * pTemp;
+ Vec_Ptr_t * vParts = (Vec_Ptr_t *)p->vClockDoms;
+ Vec_Int_t * vPart;
+ int * pMapBack, * pReprs;
+ int i, nCountPis, nCountRegs;
+ int nClasses, clk = clock();
+
+ // save parameters
+ if ( fPrintParts )
+ {
+ // print partitions
+ Abc_Print( 1, "The following clock domains are used:\n" );
+ Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i )
+ {
+ pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, NULL );
+ sprintf( Buffer, "part%03d.aig", i );
+ Gia_WriteAiger( pTemp, Buffer, 0, 0 );
+ Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
+ i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp) );
+ Gia_ManStop( pTemp );
+ }
+ }
+
+ // perform sequential synthesis for clock domains
+ pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) );
+ Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i )
+ {
+ pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, &pMapBack );
+ if ( nCountPis > 0 )
+ {
+ if ( pPars->fUseScorr )
+ {
+ Cec_ParCor_t CorPars, * pCorPars = &CorPars;
+ Cec_ManCorSetDefaultParams( pCorPars );
+ pCorPars->nBTLimit = pPars->nBTLimit;
+ pCorPars->nLevelMax = pPars->nLevelMax;
+ pCorPars->fVerbose = pPars->fVeryVerbose;
+ pCorPars->fUseCSat = 1;
+ Cec_ManLSCorrespondenceClasses( pTemp, pCorPars );
+ }
+ else if ( pPars->fUseLcorr )
+ {
+ Cec_ParCor_t CorPars, * pCorPars = &CorPars;
+ Cec_ManCorSetDefaultParams( pCorPars );
+ pCorPars->fLatchCorr = 1;
+ pCorPars->nBTLimit = pPars->nBTLimit;
+ pCorPars->fVerbose = pPars->fVeryVerbose;
+ pCorPars->fUseCSat = 1;
+ Cec_ManLSCorrespondenceClasses( pTemp, pCorPars );
+ }
+ else
+ {
+// pNew = Gia_ManSeqStructSweep( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose );
+// Gia_ManStop( pNew );
+ Gia_ManSeqCleanupClasses( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose );
+ }
+//Abc_Print( 1, "Part equivalences = %d.\n", Gia_ManEquivCountLitsAll(pTemp) );
+ nClasses = Gia_TransferMappedClasses( pTemp, pMapBack, pReprs );
+ if ( pPars->fVerbose )
+ {
+ Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. Cl = %5d.\n",
+ i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp), nClasses );
+ }
+ }
+ Gia_ManStop( pTemp );
+ ABC_FREE( pMapBack );
+ }
+
+ // generate resulting equivalences
+ Gia_ManNormalizeEquivalences( p, pReprs );
+//Abc_Print( 1, "Total equivalences = %d.\n", Gia_ManEquivCountLitsAll(p) );
+ ABC_FREE( pReprs );
+ if ( pPars->fVerbose )
+ {
+ Abc_PrintTime( 1, "Total time", clock() - clk );
+ }
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make
new file mode 100644
index 00000000..bac6e9bc
--- /dev/null
+++ b/src/proof/cec/module.make
@@ -0,0 +1,13 @@
+SRC += src/proof/cec/cecCec.c \
+ src/proof/cec/cecChoice.c \
+ src/proof/cec/cecClass.c \
+ src/proof/cec/cecCore.c \
+ src/proof/cec/cecCorr.c \
+ src/proof/cec/cecIso.c \
+ src/proof/cec/cecMan.c \
+ src/proof/cec/cecPat.c \
+ src/proof/cec/cecSeq.c \
+ src/proof/cec/cecSim.c \
+ src/proof/cec/cecSolve.c \
+ src/proof/cec/cecSynth.c \
+ src/proof/cec/cecSweep.c