summaryrefslogtreecommitdiffstats
path: root/src/proof/ssw
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-01-21 04:30:10 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2012-01-21 04:30:10 -0800
commit8014f25f6db719fa62336f997963532a14c568f6 (patch)
treec691ee91a3a2d452a2bd24ac89a8c717beaa7af7 /src/proof/ssw
parentc44cc5de9429e6b4f1c05045fcf43c9cb96437b5 (diff)
downloadabc-8014f25f6db719fa62336f997963532a14c568f6.tar.gz
abc-8014f25f6db719fa62336f997963532a14c568f6.tar.bz2
abc-8014f25f6db719fa62336f997963532a14c568f6.zip
Major restructuring of the code.
Diffstat (limited to 'src/proof/ssw')
-rw-r--r--src/proof/ssw/module.make20
-rw-r--r--src/proof/ssw/ssw.h142
-rw-r--r--src/proof/ssw/sswAig.c259
-rw-r--r--src/proof/ssw/sswBmc.c224
-rw-r--r--src/proof/ssw/sswClass.c1170
-rw-r--r--src/proof/ssw/sswCnf.c428
-rw-r--r--src/proof/ssw/sswConstr.c714
-rw-r--r--src/proof/ssw/sswCore.c522
-rw-r--r--src/proof/ssw/sswDyn.c489
-rw-r--r--src/proof/ssw/sswFilter.c493
-rw-r--r--src/proof/ssw/sswInt.h302
-rw-r--r--src/proof/ssw/sswIslands.c598
-rw-r--r--src/proof/ssw/sswLcorr.c336
-rw-r--r--src/proof/ssw/sswMan.c218
-rw-r--r--src/proof/ssw/sswPairs.c477
-rw-r--r--src/proof/ssw/sswPart.c141
-rw-r--r--src/proof/ssw/sswRarity.c1158
-rw-r--r--src/proof/ssw/sswRarity2.c517
-rw-r--r--src/proof/ssw/sswSat.c306
-rw-r--r--src/proof/ssw/sswSemi.c322
-rw-r--r--src/proof/ssw/sswSim.c1405
-rw-r--r--src/proof/ssw/sswSimSat.c123
-rw-r--r--src/proof/ssw/sswSweep.c435
-rw-r--r--src/proof/ssw/sswUnique.c197
24 files changed, 10996 insertions, 0 deletions
diff --git a/src/proof/ssw/module.make b/src/proof/ssw/module.make
new file mode 100644
index 00000000..58345a1b
--- /dev/null
+++ b/src/proof/ssw/module.make
@@ -0,0 +1,20 @@
+SRC += src/proof/ssw/sswAig.c \
+ src/proof/ssw/sswBmc.c \
+ src/proof/ssw/sswClass.c \
+ src/proof/ssw/sswCnf.c \
+ src/proof/ssw/sswConstr.c \
+ src/proof/ssw/sswCore.c \
+ src/proof/ssw/sswDyn.c \
+ src/proof/ssw/sswFilter.c \
+ src/proof/ssw/sswIslands.c \
+ src/proof/ssw/sswLcorr.c \
+ src/proof/ssw/sswMan.c \
+ src/proof/ssw/sswPart.c \
+ src/proof/ssw/sswPairs.c \
+ src/proof/ssw/sswRarity.c \
+ src/proof/ssw/sswSat.c \
+ src/proof/ssw/sswSemi.c \
+ src/proof/ssw/sswSim.c \
+ src/proof/ssw/sswSimSat.c \
+ src/proof/ssw/sswSweep.c \
+ src/proof/ssw/sswUnique.c
diff --git a/src/proof/ssw/ssw.h b/src/proof/ssw/ssw.h
new file mode 100644
index 00000000..4680f6fb
--- /dev/null
+++ b/src/proof/ssw/ssw.h
@@ -0,0 +1,142 @@
+/**CFile****************************************************************
+
+ FileName [ssw.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: ssw.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__aig__ssw__ssw_h
+#define ABC__aig__ssw__ssw_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// choicing parameters
+typedef struct Ssw_Pars_t_ Ssw_Pars_t;
+struct Ssw_Pars_t_
+{
+ int nPartSize; // size of the partition
+ int nOverSize; // size of the overlap between partitions
+ int nFramesK; // the induction depth
+ int nFramesAddSim; // the number of additional frames to simulate
+ int fConstrs; // treat the last nConstrs POs as seq constraints
+ int fMergeFull; // enables full merge when constraints are used
+ int nMaxLevs; // the max number of levels of nodes to consider
+ int nBTLimit; // conflict limit at a node
+ int nBTLimitGlobal;// conflict limit for multiple runs
+ int nMinDomSize; // min clock domain considered for optimization
+ int nItersStop; // stop after the given number of iterations
+ int fDumpSRInit; // dumps speculative reduction
+ int nResimDelta; // the number of nodes to resimulate
+ int nStepsMax; // (scorr only) the max number of induction steps
+ int TimeLimit; // time out in seconds
+ int fPolarFlip; // uses polarity adjustment
+ int fLatchCorr; // perform register correspondence
+ int fConstCorr; // perform constant correspondence
+ int fOutputCorr; // perform 'PO correspondence'
+ int fSemiFormal; // enable semiformal filtering
+// int fUniqueness; // enable uniqueness constraints
+ int fDynamic; // enable dynamic addition of constraints
+ int fLocalSim; // enable local simulation simulation
+ int fPartSigCorr; // uses partial signal correspondence
+ int nIsleDist; // extends islands by the given distance
+ int fScorrGia; // new signal correspondence implementation
+ int fUseCSat; // new SAT solver using when fScorrGia is selected
+ int fVerbose; // verbose stats
+ int fFlopVerbose; // verbose printout of redundant flops
+ int fEquivDump; // enables dumping equivalences
+ // optimized latch correspondence
+ int fLatchCorrOpt; // perform register correspondence (optimized)
+ int nSatVarMax; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
+ int nRecycleCalls; // calls to perform before recycling SAT solver (optimized latch corr only)
+ // optimized signal correspondence
+ int nSatVarMax2; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
+ int nRecycleCalls2;// calls to perform before recycling SAT solver (optimized latch corr only)
+ // internal parameters
+ int nIters; // the number of iterations performed
+ int nConflicts; // the total number of conflicts performed
+ // callback
+ void * pData;
+ void * pFunc;
+};
+
+typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== sswBmc.c ==========================================================*/
+extern int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame );
+/*=== sswConstr.c ==========================================================*/
+extern int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits );
+/*=== sswCore.c ==========================================================*/
+extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
+extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p );
+extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+/*=== sswIslands.c ==========================================================*/
+extern int Ssw_SecWithSimilarityPairs( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs, Ssw_Pars_t * pPars );
+extern int Ssw_SecWithSimilarity( Aig_Man_t * p0, Aig_Man_t * p1, Ssw_Pars_t * pPars );
+/*=== sswMiter.c ===================================================*/
+/*=== sswPart.c ==========================================================*/
+extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+/*=== sswPairs.c ===================================================*/
+extern int Ssw_MiterStatus( Aig_Man_t * p, int fVerbose );
+extern int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars );
+extern int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars );
+extern int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars );
+/*=== sswRarity.c ===================================================*/
+extern int Ssw_RarSignalFilter( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fMiter, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose );
+extern int Ssw_RarSimulate( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fVerbose );
+/*=== sswSim.c ===================================================*/
+extern Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords );
+extern Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords );
+extern void Ssw_SmlUnnormalize( Ssw_Sml_t * p );
+extern void Ssw_SmlStop( Ssw_Sml_t * p );
+extern int Ssw_SmlNumFrames( Ssw_Sml_t * p );
+extern int Ssw_SmlNumWordsTotal( Ssw_Sml_t * p );
+extern unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
+extern void Ssw_SmlInitializeSpecial( Ssw_Sml_t * p, Vec_Int_t * vInit );
+extern int Ssw_SmlCheckNonConstOutputs( Ssw_Sml_t * p );
+extern Vec_Ptr_t * Ssw_SmlSimDataPointers( Ssw_Sml_t * p );
+
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/ssw/sswAig.c b/src/proof/ssw/sswAig.c
new file mode 100644
index 00000000..8ab99f83
--- /dev/null
+++ b/src/proof/ssw/sswAig.c
@@ -0,0 +1,259 @@
+/**CFile****************************************************************
+
+ FileName [sswAig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [AIG manipulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswAig.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the SAT manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Frm_t * Ssw_FrmStart( Aig_Man_t * pAig )
+{
+ Ssw_Frm_t * p;
+ p = ABC_ALLOC( Ssw_Frm_t, 1 );
+ memset( p, 0, sizeof(Ssw_Frm_t) );
+ p->pAig = pAig;
+ p->nObjs = Aig_ManObjNumMax( pAig );
+ p->nFrames = 0;
+ p->pFrames = NULL;
+ p->vAig2Frm = Vec_PtrAlloc( 0 );
+ Vec_PtrFill( p->vAig2Frm, 2 * p->nObjs, NULL );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the SAT manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_FrmStop( Ssw_Frm_t * p )
+{
+ if ( p->pFrames )
+ Aig_ManStop( p->pFrames );
+ Vec_PtrFree( p->vAig2Frm );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs speculative reduction for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ssw_FramesConstrainNode( Ssw_Man_t * p, Aig_Man_t * pFrames, Aig_Man_t * pAig, Aig_Obj_t * pObj, int iFrame, int fTwoPos )
+{
+ Aig_Obj_t * pObjNew, * pObjNew2, * pObjRepr, * pObjReprNew, * pMiter;
+ // skip nodes without representative
+ pObjRepr = Aig_ObjRepr(pAig, pObj);
+ if ( pObjRepr == NULL )
+ return;
+ p->nConstrTotal++;
+ assert( pObjRepr->Id < pObj->Id );
+ // get the new node
+ pObjNew = Ssw_ObjFrame( p, pObj, iFrame );
+ // get the new node of the representative
+ pObjReprNew = Ssw_ObjFrame( p, pObjRepr, iFrame );
+ // if this is the same node, no need to add constraints
+ if ( pObj->fPhase == pObjRepr->fPhase )
+ {
+ assert( pObjNew != Aig_Not(pObjReprNew) );
+ if ( pObjNew == pObjReprNew )
+ return;
+ }
+ else
+ {
+ assert( pObjNew != pObjReprNew );
+ if ( pObjNew == Aig_Not(pObjReprNew) )
+ return;
+ }
+ p->nConstrReduced++;
+ // these are different nodes - perform speculative reduction
+ pObjNew2 = Aig_NotCond( pObjReprNew, pObj->fPhase ^ pObjRepr->fPhase );
+ // set the new node
+ Ssw_ObjSetFrame( p, pObj, iFrame, pObjNew2 );
+ // add the constraint
+ if ( fTwoPos )
+ {
+ Aig_ObjCreatePo( pFrames, pObjNew2 );
+ Aig_ObjCreatePo( pFrames, pObjNew );
+ }
+ else
+ {
+ pMiter = Aig_Exor( pFrames, pObjNew, pObjNew2 );
+ Aig_ObjCreatePo( pFrames, Aig_NotCond(pMiter, Aig_ObjPhaseReal(pMiter)) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the inductive case with speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p )
+{
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew;
+ int i, f, iLits;
+ assert( p->pFrames == NULL );
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ p->nConstrTotal = p->nConstrReduced = 0;
+
+ // start the fraig package
+ pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ // create latches for the first frame
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // add timeframes
+ iLits = 0;
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(pFrames);
+ pObjNew->fPhase = (p->vInits != NULL) && Vec_IntEntry(p->vInits, iLits++);
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ }
+ // set the constraints on the latch outputs
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
+ }
+ // transfer to the primary outputs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj,f) );
+ // transfer latch input to the latch outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjFrame(p, pObjLi,f) );
+ }
+ assert( p->vInits == NULL || Vec_IntSize(p->vInits) == iLits + Saig_ManPiNum(p->pAig) );
+ // add the POs for the latch outputs of the last frame
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) );
+
+ // remove dangling nodes
+ Aig_ManCleanup( pFrames );
+ // make sure the satisfying assignment is node assigned
+ assert( pFrames->pData == NULL );
+//Aig_ManShow( pFrames, 0, NULL );
+ return pFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the inductive case with speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
+{
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjNew;
+ int i;
+ assert( p->pFrames == NULL );
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ p->nConstrTotal = p->nConstrReduced = 0;
+
+ // start the fraig package
+ pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ pFrames->pName = Abc_UtilStrsav( p->pAig->pName );
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // create latches for the first frame
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // set the constraints on the latch outputs
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
+ }
+ // add the POs for the latch outputs of the last frame
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Aig_ObjCreatePo( pFrames, Ssw_ObjChild0Fra(p, pObj,0) );
+ // remove dangling nodes
+ Aig_ManCleanup( pFrames );
+ Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) );
+// printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n",
+// p->nConstrTotal, p->nConstrReduced );
+ return pFrames;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswBmc.c b/src/proof/ssw/sswBmc.c
new file mode 100644
index 00000000..8cb14f4a
--- /dev/null
+++ b/src/proof/ssw/sswBmc.c
@@ -0,0 +1,224 @@
+/**CFile****************************************************************
+
+ FileName [sswBmc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Bounded model checker using dynamic unrolling.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswBmc.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Incrementally unroll the timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Ssw_BmcUnroll_rec( Ssw_Frm_t * pFrm, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pRes, * pRes0, * pRes1;
+ if ( (pRes = Ssw_ObjFrame_(pFrm, pObj, f)) )
+ return pRes;
+ if ( Aig_ObjIsConst1(pObj) )
+ pRes = Aig_ManConst1( pFrm->pFrames );
+ else if ( Saig_ObjIsPi(pFrm->pAig, pObj) )
+ pRes = Aig_ObjCreatePi( pFrm->pFrames );
+ else if ( Aig_ObjIsPo(pObj) )
+ {
+ Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f );
+ pRes = Ssw_ObjChild0Fra_( pFrm, pObj, f );
+ }
+ else if ( Saig_ObjIsLo(pFrm->pAig, pObj) )
+ {
+ if ( f == 0 )
+ pRes = Aig_ManConst0( pFrm->pFrames );
+ else
+ pRes = Ssw_BmcUnroll_rec( pFrm, Saig_ObjLoToLi(pFrm->pAig, pObj), f-1 );
+ }
+ else
+ {
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f );
+ Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin1(pObj), f );
+ pRes0 = Ssw_ObjChild0Fra_( pFrm, pObj, f );
+ pRes1 = Ssw_ObjChild1Fra_( pFrm, pObj, f );
+ pRes = Aig_And( pFrm->pFrames, pRes0, pRes1 );
+ }
+ Ssw_ObjSetFrame_( pFrm, pObj, f, pRes );
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iPo, int iFrame )
+{
+ Abc_Cex_t * pCex;
+ Aig_Obj_t * pObj, * pObjFrames;
+ int f, i, nShift;
+ assert( Saig_ManRegNum(pFrm->pAig) > 0 );
+ // allocate the counter example
+ pCex = Abc_CexAlloc( Saig_ManRegNum(pFrm->pAig), Saig_ManPiNum(pFrm->pAig), iFrame + 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = iFrame;
+ // create data-bits
+ nShift = Saig_ManRegNum(pFrm->pAig);
+ for ( f = 0; f <= iFrame; f++, nShift += Saig_ManPiNum(pFrm->pAig) )
+ Saig_ManForEachPi( pFrm->pAig, pObj, i )
+ {
+ pObjFrames = Ssw_ObjFrame_(pFrm, pObj, f);
+ if ( pObjFrames == NULL )
+ continue;
+ if ( Ssw_CnfGetNodeValue( pSat, pObjFrames ) )
+ Abc_InfoSetBit( pCex->pData, nShift + i );
+ }
+ return pCex;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs BMC for the given AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame )
+{
+ Ssw_Frm_t * pFrm;
+ Ssw_Sat_t * pSat;
+ Aig_Obj_t * pObj, * pObjFrame;
+ int status, clkPart, Lit, i, f, RetValue;
+
+ // start managers
+ assert( Saig_ManRegNum(pAig) > 0 );
+ Aig_ManSetPioNumbers( pAig );
+ pSat = Ssw_SatStart( 0 );
+ pFrm = Ssw_FrmStart( pAig );
+ pFrm->pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * 3 );
+ // report statistics
+ if ( fVerbose )
+ {
+ printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n",
+ Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig),
+ Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) );
+ fflush( stdout );
+ }
+ // perform dynamic unrolling
+ RetValue = -1;
+ for ( f = 0; f < nFramesMax; f++ )
+ {
+ clkPart = clock();
+ Saig_ManForEachPo( pAig, pObj, i )
+ {
+ // unroll the circuit for this output
+ Ssw_BmcUnroll_rec( pFrm, pObj, f );
+ pObjFrame = Ssw_ObjFrame_( pFrm, pObj, f );
+ Ssw_CnfNodeAddToSolver( pSat, Aig_Regular(pObjFrame) );
+ status = sat_solver_simplify(pSat->pSat);
+ assert( status );
+ // solve
+ Lit = toLitCond( Ssw_ObjSatNum(pSat,pObjFrame), Aig_IsComplement(pObjFrame) );
+ if ( fVerbose )
+ {
+ printf( "Solving output %2d of frame %3d ... \r",
+ i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
+ }
+ status = sat_solver_solve( pSat->pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( status == l_False )
+ {
+/*
+ Lit = lit_neg( Lit );
+ RetValue = sat_solver_addclause( pSat->pSat, &Lit, &Lit + 1 );
+ assert( RetValue );
+ if ( pSat->pSat->qtail != pSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(pSat->pSat);
+ assert( RetValue );
+ }
+*/
+ RetValue = 1;
+ continue;
+ }
+ else if ( status == l_True )
+ {
+ pAig->pSeqModel = Ssw_BmcGetCounterExample( pFrm, pSat, i, f );
+ if ( piFrame )
+ *piFrame = f;
+ RetValue = 0;
+ break;
+ }
+ else
+ {
+ if ( piFrame )
+ *piFrame = f;
+ RetValue = -1;
+ break;
+ }
+ }
+ if ( fVerbose )
+ {
+ printf( "Solved %2d outputs of frame %3d. ", Saig_ManPoNum(pAig), f );
+ printf( "Conf =%8.0f. Var =%8d. AIG=%9d. ",
+ (double)pSat->pSat->stats.conflicts,
+ pSat->nSatVars, Aig_ManNodeNum(pFrm->pFrames) );
+ ABC_PRT( "T", clock() - clkPart );
+ clkPart = clock();
+ fflush( stdout );
+ }
+ if ( RetValue != 1 )
+ break;
+ }
+
+ Ssw_SatStop( pSat );
+ Ssw_FrmStop( pFrm );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswClass.c b/src/proof/ssw/sswClass.c
new file mode 100644
index 00000000..dd075f44
--- /dev/null
+++ b/src/proof/ssw/sswClass.c
@@ -0,0 +1,1170 @@
+/**CFile****************************************************************
+
+ FileName [sswClass.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Representation of candidate equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswClass.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+/*
+ The candidate equivalence classes are stored as a vector of pointers
+ to the array of pointers to the nodes in each class.
+ The first node of the class is its representative node.
+ The representative has the smallest topological order among the class nodes.
+ The nodes inside each class are ordered according to their topological order.
+ The classes are ordered according to the topo order of their representatives.
+*/
+
+// internal representation of candidate equivalence classes
+struct Ssw_Cla_t_
+{
+ // class information
+ Aig_Man_t * pAig; // original AIG manager
+ Aig_Obj_t *** pId2Class; // non-const classes by ID of repr node
+ int * pClassSizes; // sizes of each equivalence class
+ int fConstCorr;
+ // statistics
+ int nClasses; // the total number of non-const classes
+ int nCands1; // the total number of const candidates
+ int nLits; // the number of literals in all classes
+ // memory
+ Aig_Obj_t ** pMemClasses; // memory allocated for equivalence classes
+ Aig_Obj_t ** pMemClassesFree; // memory allocated for equivalence classes to be used
+ // temporary data
+ Vec_Ptr_t * vClassOld; // old equivalence class after splitting
+ Vec_Ptr_t * vClassNew; // new equivalence class(es) after splitting
+ Vec_Ptr_t * vRefined; // the nodes refined since the last iteration
+ // procedures used for class refinement
+ void * pManData;
+ unsigned (*pFuncNodeHash) (void *,Aig_Obj_t *); // returns hash key of the node
+ int (*pFuncNodeIsConst) (void *,Aig_Obj_t *); // returns 1 if the node is a constant
+ int (*pFuncNodesAreEqual) (void *,Aig_Obj_t *, Aig_Obj_t *); // returns 1 if nodes are equal up to a complement
+};
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline Aig_Obj_t * Ssw_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj ) { return ppNexts[pObj->Id]; }
+static inline void Ssw_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; }
+
+// iterator through the equivalence classes
+#define Ssw_ManForEachClass( p, ppClass, i ) \
+ for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ ) \
+ if ( ((ppClass) = p->pId2Class[i]) == NULL ) {} else
+// iterator through the nodes in one class
+#define Ssw_ClassForEachNode( p, pRepr, pNode, i ) \
+ for ( i = 0; i < p->pClassSizes[pRepr->Id]; i++ ) \
+ if ( ((pNode) = p->pId2Class[pRepr->Id][i]) == NULL ) {} else
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ssw_ObjAddClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Aig_Obj_t ** pClass, int nSize )
+{
+ assert( p->pId2Class[pRepr->Id] == NULL );
+ assert( pClass[0] == pRepr );
+ p->pId2Class[pRepr->Id] = pClass;
+ assert( p->pClassSizes[pRepr->Id] == 0 );
+ assert( nSize > 1 );
+ p->pClassSizes[pRepr->Id] = nSize;
+ p->nClasses++;
+ p->nLits += nSize - 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Aig_Obj_t ** Ssw_ObjRemoveClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t ** pClass = p->pId2Class[pRepr->Id];
+ int nSize;
+ assert( pClass != NULL );
+ p->pId2Class[pRepr->Id] = NULL;
+ nSize = p->pClassSizes[pRepr->Id];
+ assert( nSize > 1 );
+ p->nClasses--;
+ p->nLits -= nSize - 1;
+ p->pClassSizes[pRepr->Id] = 0;
+ return pClass;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig )
+{
+ Ssw_Cla_t * p;
+ p = ABC_ALLOC( Ssw_Cla_t, 1 );
+ memset( p, 0, sizeof(Ssw_Cla_t) );
+ p->pAig = pAig;
+ p->pId2Class = ABC_CALLOC( Aig_Obj_t **, Aig_ManObjNumMax(pAig) );
+ p->pClassSizes = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) );
+ p->vClassOld = Vec_PtrAlloc( 100 );
+ p->vClassNew = Vec_PtrAlloc( 100 );
+ p->vRefined = Vec_PtrAlloc( 1000 );
+ if ( pAig->pReprs == NULL )
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
+ unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *), // returns hash key of the node
+ int (*pFuncNodeIsConst)(void *,Aig_Obj_t *), // returns 1 if the node is a constant
+ int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) ) // returns 1 if nodes are equal up to a complement
+{
+ p->pManData = pManData;
+ p->pFuncNodeHash = pFuncNodeHash;
+ p->pFuncNodeIsConst = pFuncNodeIsConst;
+ p->pFuncNodesAreEqual = pFuncNodesAreEqual;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesStop( Ssw_Cla_t * p )
+{
+ if ( p->vClassNew ) Vec_PtrFree( p->vClassNew );
+ if ( p->vClassOld ) Vec_PtrFree( p->vClassOld );
+ Vec_PtrFree( p->vRefined );
+ ABC_FREE( p->pId2Class );
+ ABC_FREE( p->pClassSizes );
+ ABC_FREE( p->pMemClasses );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p )
+{
+ return p->pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p )
+{
+ return p->vRefined;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesClearRefined( Ssw_Cla_t * p )
+{
+ Vec_PtrClear( p->vRefined );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesCand1Num( Ssw_Cla_t * p )
+{
+ return p->nCands1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesClassNum( Ssw_Cla_t * p )
+{
+ return p->nClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesLitNum( Ssw_Cla_t * p )
+{
+ return p->nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize )
+{
+ if ( p->pId2Class[pRepr->Id] == NULL )
+ return NULL;
+ assert( p->pId2Class[pRepr->Id] != NULL );
+ assert( p->pClassSizes[pRepr->Id] > 1 );
+ *pnSize = p->pClassSizes[pRepr->Id];
+ return p->pId2Class[pRepr->Id];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass )
+{
+ int i;
+ Vec_PtrClear( vClass );
+ if ( p->pId2Class[pRepr->Id] == NULL )
+ return;
+ assert( p->pClassSizes[pRepr->Id] > 1 );
+ for ( i = 1; i < p->pClassSizes[pRepr->Id]; i++ )
+ Vec_PtrPush( vClass, p->pId2Class[pRepr->Id][i] );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks candidate equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesCheck( Ssw_Cla_t * p )
+{
+ Aig_Obj_t * pObj, * pPrev, ** ppClass;
+ int i, k, nLits, nClasses, nCands1;
+ nClasses = nLits = 0;
+ Ssw_ManForEachClass( p, ppClass, k )
+ {
+ pPrev = NULL;
+ assert( p->pClassSizes[ppClass[0]->Id] >= 2 );
+ Ssw_ClassForEachNode( p, ppClass[0], pObj, i )
+ {
+ if ( i == 0 )
+ assert( Aig_ObjRepr(p->pAig, pObj) == NULL );
+ else
+ {
+ assert( Aig_ObjRepr(p->pAig, pObj) == ppClass[0] );
+ assert( pPrev->Id < pObj->Id );
+ nLits++;
+ }
+ pPrev = pObj;
+ }
+ nClasses++;
+ }
+ nCands1 = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ nCands1 += Ssw_ObjIsConst1Cand( p->pAig, pObj );
+ assert( p->nLits == nLits );
+ assert( p->nCands1 == nCands1 );
+ assert( p->nClasses == nClasses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ printf( "{ " );
+ Ssw_ClassForEachNode( p, pRepr, pObj, i )
+ printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level,
+ Aig_SupportSize(p->pAig,pObj), Aig_NodeMffcSupp(p->pAig,pObj,0,NULL) );
+ printf( "}\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose )
+{
+ Aig_Obj_t ** ppClass;
+ Aig_Obj_t * pObj;
+ int i;
+ printf( "Equiv classes: Const1 = %5d. Class = %5d. Lit = %5d.\n",
+ p->nCands1, p->nClasses, p->nCands1+p->nLits );
+ if ( !fVeryVerbose )
+ return;
+ printf( "Constants { " );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level,
+ Aig_SupportSize(p->pAig,pObj), Aig_NodeMffcSupp(p->pAig,pObj,0,NULL) );
+ printf( "}\n" );
+ Ssw_ManForEachClass( p, ppClass, i )
+ {
+ printf( "%3d (%3d) : ", i, p->pClassSizes[i] );
+ Ssw_ClassesPrintOne( p, ppClass[0] );
+ }
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pRepr, * pTemp;
+ assert( p->pClassSizes[pObj->Id] == 0 );
+ assert( p->pId2Class[pObj->Id] == NULL );
+ pRepr = Aig_ObjRepr( p->pAig, pObj );
+ assert( pRepr != NULL );
+// Vec_PtrPush( p->vRefined, pObj );
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ {
+ assert( p->pClassSizes[pRepr->Id] == 0 );
+ assert( p->pId2Class[pRepr->Id] == NULL );
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ p->nCands1--;
+ return;
+ }
+// Vec_PtrPush( p->vRefined, pRepr );
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ assert( p->pId2Class[pRepr->Id][0] == pRepr );
+ assert( p->pClassSizes[pRepr->Id] >= 2 );
+ if ( p->pClassSizes[pRepr->Id] == 2 )
+ {
+ p->pId2Class[pRepr->Id] = NULL;
+ p->nClasses--;
+ p->pClassSizes[pRepr->Id] = 0;
+ p->nLits--;
+ }
+ else
+ {
+ int i, k = 0;
+ // remove the entry from the class
+ Ssw_ClassForEachNode( p, pRepr, pTemp, i )
+ if ( pTemp != pObj )
+ p->pId2Class[pRepr->Id][k++] = pTemp;
+ assert( k + 1 == p->pClassSizes[pRepr->Id] );
+ // reduce the class
+ p->pClassSizes[pRepr->Id]--;
+ p->nLits--;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Takes the set of const1 cands and rehashes them using sim info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands, int fConstCorr )
+{
+ Aig_Man_t * pAig = p->pAig;
+ Aig_Obj_t ** ppTable, ** ppNexts, ** ppClassNew;
+ Aig_Obj_t * pObj, * pTemp, * pRepr;
+ int i, k, nTableSize, nNodes, iEntry, nEntries, nEntries2;
+
+ // allocate the hash table hashing simulation info into nodes
+ nTableSize = Abc_PrimeCudd( Vec_PtrSize(vCands)/2 );
+ ppTable = ABC_CALLOC( Aig_Obj_t *, nTableSize );
+ ppNexts = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) );
+
+ // sort through the candidates
+ nEntries = 0;
+ p->nCands1 = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, vCands, pObj, i )
+ {
+ assert( p->pClassSizes[pObj->Id] == 0 );
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ // check if the node belongs to the class of constant 1
+ if ( p->pFuncNodeIsConst( p->pManData, pObj ) )
+ {
+ Ssw_ObjSetConst1Cand( p->pAig, pObj );
+ p->nCands1++;
+ continue;
+ }
+ if ( fConstCorr )
+ continue;
+ // hash the node by its simulation info
+ iEntry = p->pFuncNodeHash( p->pManData, pObj ) % nTableSize;
+ // add the node to the class
+ if ( ppTable[iEntry] == NULL )
+ {
+ ppTable[iEntry] = pObj;
+ }
+ else
+ {
+ // set the representative of this node
+ pRepr = ppTable[iEntry];
+ Aig_ObjSetRepr( p->pAig, pObj, pRepr );
+ // add node to the table
+ if ( Ssw_ObjNext( ppNexts, pRepr ) == NULL )
+ { // this will be the second entry
+ p->pClassSizes[pRepr->Id]++;
+ nEntries++;
+ }
+ // add the entry to the list
+ Ssw_ObjSetNext( ppNexts, pObj, Ssw_ObjNext( ppNexts, pRepr ) );
+ Ssw_ObjSetNext( ppNexts, pRepr, pObj );
+ p->pClassSizes[pRepr->Id]++;
+ nEntries++;
+ }
+ }
+
+ // copy the entries into storage in the topological order
+ nEntries2 = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, vCands, pObj, i )
+ {
+ nNodes = p->pClassSizes[pObj->Id];
+ // skip the nodes that are not representatives of non-trivial classes
+ if ( nNodes == 0 )
+ continue;
+ assert( nNodes > 1 );
+ // add the nodes to the class in the topological order
+ ppClassNew = p->pMemClassesFree + nEntries2;
+ ppClassNew[0] = pObj;
+ for ( pTemp = Ssw_ObjNext(ppNexts, pObj), k = 1; pTemp;
+ pTemp = Ssw_ObjNext(ppNexts, pTemp), k++ )
+ {
+ ppClassNew[nNodes-k] = pTemp;
+ }
+ // add the class of nodes
+ p->pClassSizes[pObj->Id] = 0;
+ Ssw_ObjAddClass( p, pObj, ppClassNew, nNodes );
+ // increment the number of entries
+ nEntries2 += nNodes;
+ }
+ p->pMemClassesFree += nEntries2;
+ assert( nEntries == nEntries2 );
+ ABC_FREE( ppTable );
+ ABC_FREE( ppNexts );
+ // now it is time to refine the classes
+ return Ssw_ClassesRefine( p, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int fConstCorr, int fOutputCorr, int nMaxLevs, int fVerbose )
+{
+// int nFrames = 4;
+// int nWords = 1;
+// int nIters = 16;
+
+// int nFrames = 32;
+// int nWords = 4;
+// int nIters = 0;
+
+ int nFrames = Abc_MaxInt( nFramesK, 4 );
+ int nWords = 2;
+ int nIters = 16;
+ Ssw_Cla_t * p;
+ Ssw_Sml_t * pSml;
+ Vec_Ptr_t * vCands;
+ Aig_Obj_t * pObj;
+ int i, k, RetValue, clk;
+
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ p->fConstCorr = fConstCorr;
+
+ // perform sequential simulation
+clk = clock();
+ pSml = Ssw_SmlSimulateSeq( pAig, 0, nFrames, nWords );
+if ( fVerbose )
+{
+ printf( "Allocated %.2f Mb to store simulation information.\n",
+ 1.0*(sizeof(unsigned) * Aig_ManObjNumMax(pAig) * nFrames * nWords)/(1<<20) );
+ printf( "Initial simulation of %d frames with %d words. ", nFrames, nWords );
+ ABC_PRT( "Time", clock() - clk );
+}
+
+ // set comparison procedures
+clk = clock();
+ Ssw_ClassesSetData( p, pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
+
+ // collect nodes to be considered as candidates
+ vCands = Vec_PtrAlloc( 1000 );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( fLatchCorr )
+ {
+ if ( !Saig_ObjIsLo(p->pAig, pObj) )
+ continue;
+ }
+ else
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
+ continue;
+ // skip the node with more that the given number of levels
+ if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
+ continue;
+ }
+ Vec_PtrPush( vCands, pObj );
+ }
+
+ // this change will consider all PO drivers
+ if ( fOutputCorr )
+ {
+ Vec_PtrClear( vCands );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pObj->fMarkB = 0;
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ if ( Aig_ObjIsCand(Aig_ObjFanin0(pObj)) )
+ Aig_ObjFanin0(pObj)->fMarkB = 1;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ if ( pObj->fMarkB )
+ Vec_PtrPush( vCands, pObj );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pObj->fMarkB = 0;
+ }
+
+ // allocate room for classes
+ p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, Vec_PtrSize(vCands) );
+ p->pMemClassesFree = p->pMemClasses;
+
+ // now it is time to refine the classes
+ Ssw_ClassesPrepareRehash( p, vCands, fConstCorr );
+if ( fVerbose )
+{
+ printf( "Collecting candidate equivalence classes. " );
+ABC_PRT( "Time", clock() - clk );
+}
+
+clk = clock();
+ // perform iterative refinement using simulation
+ for ( i = 1; i < nIters; i++ )
+ {
+ // collect const1 candidates
+ Vec_PtrClear( vCands );
+ Aig_ManForEachObj( p->pAig, pObj, k )
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ Vec_PtrPush( vCands, pObj );
+ assert( Vec_PtrSize(vCands) == p->nCands1 );
+ // perform new round of simulation
+ Ssw_SmlResimulateSeq( pSml );
+ // check equivalence classes
+ RetValue = Ssw_ClassesPrepareRehash( p, vCands, fConstCorr );
+ if ( RetValue == 0 )
+ break;
+ }
+ Ssw_SmlStop( pSml );
+ Vec_PtrFree( vCands );
+if ( fVerbose )
+{
+ printf( "Simulation of %d frames with %d words (%2d rounds). ",
+ nFrames, nWords, i-1 );
+ ABC_PRT( "Time", clock() - clk );
+}
+ Ssw_ClassesCheck( p );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // go through the nodes
+ p->nCands1 = 0;
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( fLatchCorr )
+ {
+ if ( !Saig_ObjIsLo(pAig, pObj) )
+ continue;
+ }
+ else
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Saig_ObjIsLo(pAig, pObj) )
+ continue;
+ // skip the node with more that the given number of levels
+ if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
+ continue;
+ }
+ Ssw_ObjSetConst1Cand( pAig, pObj );
+ p->nCands1++;
+ }
+ // allocate room for classes
+ p->pMemClassesFree = p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, p->nCands1 );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepareFromReprs( Aig_Man_t * pAig )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t * pObj, * pRepr;
+ int * pClassSizes, nEntries, i;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // allocate memory for classes
+ p->pMemClasses = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
+ // count classes
+ p->nCands1 = 0;
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( Ssw_ObjIsConst1Cand(pAig, pObj) )
+ {
+ p->nCands1++;
+ continue;
+ }
+ if ( (pRepr = Aig_ObjRepr(pAig, pObj)) )
+ {
+ if ( p->pClassSizes[pRepr->Id]++ == 0 )
+ p->pClassSizes[pRepr->Id]++;
+ }
+ }
+ // add nodes
+ nEntries = 0;
+ p->nClasses = 0;
+ pClassSizes = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( p->pClassSizes[i] )
+ {
+ p->pId2Class[i] = p->pMemClasses + nEntries;
+ nEntries += p->pClassSizes[i];
+ p->pId2Class[i][pClassSizes[i]++] = pObj;
+ p->nClasses++;
+ continue;
+ }
+ if ( Ssw_ObjIsConst1Cand(pAig, pObj) )
+ continue;
+ if ( (pRepr = Aig_ObjRepr(pAig, pObj)) )
+ p->pId2Class[pRepr->Id][pClassSizes[pRepr->Id]++] = pObj;
+ }
+ p->pMemClassesFree = p->pMemClasses + nEntries;
+ p->nLits = nEntries - p->nClasses;
+ assert( memcmp(pClassSizes, p->pClassSizes, sizeof(int)*Aig_ManObjNumMax(pAig)) == 0 );
+ ABC_FREE( pClassSizes );
+// printf( "After converting:\n" );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // go through the nodes
+ p->nCands1 = 0;
+ Saig_ManForEachPo( pAig, pObj, i )
+ {
+ Ssw_ObjSetConst1Cand( pAig, Aig_ObjFanin0(pObj) );
+ p->nCands1++;
+ }
+ // allocate room for classes
+ p->pMemClassesFree = p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, p->nCands1 );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates classes from the temporary representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t ** ppClassNew;
+ Aig_Obj_t * pObj, * pRepr, * pPrev;
+ int i, k, nTotalObjs, nEntries, Entry;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // count the number of entries in the classes
+ nTotalObjs = 0;
+ for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ )
+ nTotalObjs += pvClasses[i] ? Vec_IntSize(pvClasses[i]) : 0;
+ // allocate memory for classes
+ p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, nTotalObjs );
+ // create constant-1 class
+ if ( pvClasses[0] )
+ Vec_IntForEachEntry( pvClasses[0], Entry, i )
+ {
+ assert( (i == 0) == (Entry == 0) );
+ if ( i == 0 )
+ continue;
+ pObj = Aig_ManObj( pAig, Entry );
+ Ssw_ObjSetConst1Cand( pAig, pObj );
+ p->nCands1++;
+ }
+ // create classes
+ nEntries = 0;
+ for ( i = 1; i < Aig_ManObjNumMax(pAig); i++ )
+ {
+ if ( pvClasses[i] == NULL )
+ continue;
+ // get room for storing the class
+ ppClassNew = p->pMemClasses + nEntries;
+ nEntries += Vec_IntSize( pvClasses[i] );
+ // store the nodes of the class
+ pPrev = pRepr = Aig_ManObj( pAig, Vec_IntEntry(pvClasses[i],0) );
+ ppClassNew[0] = pRepr;
+ Vec_IntForEachEntryStart( pvClasses[i], Entry, k, 1 )
+ {
+ pObj = Aig_ManObj( pAig, Entry );
+ assert( pPrev->Id < pObj->Id );
+ pPrev = pObj;
+ ppClassNew[k] = pObj;
+ Aig_ObjSetRepr( pAig, pObj, pRepr );
+ }
+ // create new class
+ Ssw_ObjAddClass( p, pRepr, ppClassNew, Vec_IntSize(pvClasses[i]) );
+ }
+ // prepare room for new classes
+ p->pMemClassesFree = p->pMemClasses + nEntries;
+ Ssw_ClassesCheck( p );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates classes from the temporary representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPreparePairsSimple( Aig_Man_t * pMiter, Vec_Int_t * vPairs )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t ** ppClassNew;
+ Aig_Obj_t * pObj, * pRepr;
+ int i;
+ // start the classes
+ p = Ssw_ClassesStart( pMiter );
+ // allocate memory for classes
+ p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, Vec_IntSize(vPairs) );
+ // create classes
+ for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
+ {
+ pRepr = Aig_ManObj( pMiter, Vec_IntEntry(vPairs, i) );
+ pObj = Aig_ManObj( pMiter, Vec_IntEntry(vPairs, i+1) );
+ assert( Aig_ObjId(pRepr) < Aig_ObjId(pObj) );
+ Aig_ObjSetRepr( pMiter, pObj, pRepr );
+ // get room for storing the class
+ ppClassNew = p->pMemClasses + i;
+ ppClassNew[0] = pRepr;
+ ppClassNew[1] = pObj;
+ // create new class
+ Ssw_ObjAddClass( p, pRepr, ppClassNew, 2 );
+ }
+ // prepare room for new classes
+ p->pMemClassesFree = NULL;
+ Ssw_ClassesCheck( p );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Iteratively refines the classes after simulation.]
+
+ Description [Returns the number of refinements performed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursive )
+{
+ Aig_Obj_t ** pClassOld, ** pClassNew;
+ Aig_Obj_t * pObj, * pReprNew;
+ int i;
+
+ // split the class
+ Vec_PtrClear( p->vClassOld );
+ Vec_PtrClear( p->vClassNew );
+ Ssw_ClassForEachNode( p, pReprOld, pObj, i )
+ if ( p->pFuncNodesAreEqual(p->pManData, pReprOld, pObj) )
+ Vec_PtrPush( p->vClassOld, pObj );
+ else
+ Vec_PtrPush( p->vClassNew, pObj );
+ // check if splitting happened
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ // remember that this class is refined
+// Ssw_ClassForEachNode( p, pReprOld, pObj, i )
+// Vec_PtrPush( p->vRefined, pObj );
+
+ // get the new representative
+ pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 );
+ assert( Vec_PtrSize(p->vClassOld) > 0 );
+ assert( Vec_PtrSize(p->vClassNew) > 0 );
+
+ // create old class
+ pClassOld = Ssw_ObjRemoveClass( p, pReprOld );
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassOld, pObj, i )
+ {
+ pClassOld[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL );
+ }
+ // create new class
+ pClassNew = pClassOld + i;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i )
+ {
+ pClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+
+ // put classes back
+ if ( Vec_PtrSize(p->vClassOld) > 1 )
+ Ssw_ObjAddClass( p, pReprOld, pClassOld, Vec_PtrSize(p->vClassOld) );
+ if ( Vec_PtrSize(p->vClassNew) > 1 )
+ Ssw_ObjAddClass( p, pReprNew, pClassNew, Vec_PtrSize(p->vClassNew) );
+
+ // check if the class should be recursively refined
+ if ( fRecursive && Vec_PtrSize(p->vClassNew) > 1 )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines the classes after simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive )
+{
+ Aig_Obj_t ** ppClass;
+ int i, nRefis = 0;
+ Ssw_ManForEachClass( p, ppClass, i )
+ nRefis += Ssw_ClassesRefineOneClass( p, ppClass[0], fRecursive );
+ return nRefis;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines the classes after simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineGroup( Ssw_Cla_t * p, Vec_Ptr_t * vReprs, int fRecursive )
+{
+ Aig_Obj_t * pObj;
+ int i, nRefis = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, vReprs, pObj, i )
+ nRefis += Ssw_ClassesRefineOneClass( p, pObj, fRecursive );
+ return nRefis;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refine the group of constant 1 nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive )
+{
+ Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
+ int i;
+ if ( Vec_PtrSize(vRoots) == 0 )
+ return 0;
+ // collect the nodes to be refined
+ Vec_PtrClear( p->vClassNew );
+ Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i )
+ if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
+ Vec_PtrPush( p->vClassNew, pObj );
+ // check if there is a new class
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ p->nCands1 -= Vec_PtrSize(p->vClassNew);
+ pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 );
+ Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
+ if ( Vec_PtrSize(p->vClassNew) == 1 )
+ return 1;
+ // create a new class composed of these nodes
+ ppClassNew = p->pMemClassesFree;
+ p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i )
+ {
+ ppClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+ Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
+ // refine them recursively
+ if ( fRecursive )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refine the group of constant 1 nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive )
+{
+ Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
+ int i;
+ // collect the nodes to be refined
+ Vec_PtrClear( p->vClassNew );
+ for ( i = 0; i < Vec_PtrSize(p->pAig->vObjs); i++ )
+ if ( p->pAig->pReprs[i] == Aig_ManConst1(p->pAig) )
+ {
+ pObj = Aig_ManObj( p->pAig, i );
+ if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
+ {
+ Vec_PtrPush( p->vClassNew, pObj );
+// Vec_PtrPush( p->vRefined, pObj );
+ }
+ }
+ // check if there is a new class
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ if ( p->fConstCorr )
+ {
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i )
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ return 1;
+ }
+ p->nCands1 -= Vec_PtrSize(p->vClassNew);
+ pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 );
+ Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
+ if ( Vec_PtrSize(p->vClassNew) == 1 )
+ return 1;
+ // create a new class composed of these nodes
+ ppClassNew = p->pMemClassesFree;
+ p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i )
+ {
+ ppClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+ Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
+ // refine them recursively
+ if ( fRecursive )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswCnf.c b/src/proof/ssw/sswCnf.c
new file mode 100644
index 00000000..1970c62f
--- /dev/null
+++ b/src/proof/ssw/sswCnf.c
@@ -0,0 +1,428 @@
+/**CFile****************************************************************
+
+ FileName [sswCnf.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Computation of CNF.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswCnf.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the SAT manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sat_t * Ssw_SatStart( int fPolarFlip )
+{
+ Ssw_Sat_t * p;
+ int Lit;
+ p = ABC_ALLOC( Ssw_Sat_t, 1 );
+ memset( p, 0, sizeof(Ssw_Sat_t) );
+ p->pAig = NULL;
+ p->fPolarFlip = fPolarFlip;
+ p->vSatVars = Vec_IntStart( 10000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vUsedPis = Vec_PtrAlloc( 100 );
+ p->pSat = sat_solver_new();
+ sat_solver_setnvars( p->pSat, 1000 );
+ // var 0 is not used
+ // var 1 is reserved for const1 node - add the clause
+ p->nSatVars = 1;
+ Lit = toLit( p->nSatVars );
+ if ( fPolarFlip )
+ Lit = lit_neg( Lit );
+ sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
+// Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
+ Vec_IntWriteEntry( p->vSatVars, 0, p->nSatVars++ );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop the SAT manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SatStop( Ssw_Sat_t * p )
+{
+// printf( "Recycling SAT solver with %d vars and %d restarts.\n",
+// p->pSat->size, p->pSat->stats.starts );
+ if ( p->pSat )
+ sat_solver_delete( p->pSat );
+ Vec_IntFree( p->vSatVars );
+ Vec_PtrFree( p->vFanins );
+ Vec_PtrFree( p->vUsedPis );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_AddClausesMux( Ssw_Sat_t * p, Aig_Obj_t * pNode )
+{
+ Aig_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Aig_IsComplement( pNode ) );
+ assert( Aig_ObjIsMuxType( pNode ) );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Aig_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Ssw_ObjSatNum(p,pNode);
+ VarI = Ssw_ObjSatNum(p,pNodeI);
+ VarT = Ssw_ObjSatNum(p,Aig_Regular(pNodeT));
+ VarE = Ssw_ObjSatNum(p,Aig_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Aig_IsComplement(pNodeT);
+ fCompE = Aig_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->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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->fPolarFlip )
+ {
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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->fPolarFlip )
+ {
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_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 Ssw_AddClausesSuper( Ssw_Sat_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
+{
+ Aig_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Aig_IsComplement(pNode) );
+ assert( Aig_ObjIsNode( 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( Aig_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin));
+ pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1);
+ if ( p->fPolarFlip )
+ {
+ if ( Aig_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( Aig_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin));
+ if ( p->fPolarFlip )
+ {
+ if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0);
+ if ( p->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 Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ||
+ (!fFirst && Aig_ObjRefs(pObj) > 1) ||
+ (fUseMuxes && Aig_ObjIsMuxType(pObj)) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+// pObj->fMarkA = 1;
+ // go through the branches
+ Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( !Aig_ObjIsPi(pObj) );
+ Vec_PtrClear( vSuper );
+ Ssw_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ObjAddToFrontier( Ssw_Sat_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( Ssw_ObjSatNum(p,pObj) )
+ return;
+ assert( Ssw_ObjSatNum(p,pObj) == 0 );
+ if ( Aig_ObjIsConst1(pObj) )
+ return;
+// pObj->fMarkA = 1;
+ // save PIs (used by register correspondence)
+ if ( Aig_ObjIsPi(pObj) )
+ Vec_PtrPush( p->vUsedPis, pObj );
+ Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ );
+ sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) );
+ if ( Aig_ObjIsNode(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj )
+{
+ Vec_Ptr_t * vFrontier;
+ Aig_Obj_t * pNode, * pFanin;
+ int i, k, fUseMuxes = 1;
+ // quit if CNF is ready
+ if ( Ssw_ObjSatNum(p,pObj) )
+ return;
+ // start the frontier
+ vFrontier = Vec_PtrAlloc( 100 );
+ Ssw_ObjAddToFrontier( p, pObj, vFrontier );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Aig_Obj_t *, vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Ssw_ObjSatNum(p,pNode) );
+ if ( fUseMuxes && Aig_ObjIsMuxType(pNode) )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k )
+ Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
+ Ssw_AddClausesMux( p, pNode );
+ }
+ else
+ {
+ Ssw_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k )
+ Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
+ Ssw_AddClausesSuper( p, pNode, p->vFanins );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ Vec_PtrFree( vFrontier );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObj )
+{
+ int Value0, Value1, nVarNum;
+ assert( !Aig_IsComplement(pObj) );
+ nVarNum = Ssw_ObjSatNum( p, pObj );
+ if ( nVarNum > 0 )
+ return sat_solver_var_value( p->pSat, nVarNum );
+// if ( pObj->fMarkA == 1 )
+// return 0;
+ if ( Aig_ObjIsPi(pObj) )
+ return 0;
+ assert( Aig_ObjIsNode(pObj) );
+ Value0 = Ssw_CnfGetNodeValue( p, Aig_ObjFanin0(pObj) );
+ Value0 ^= Aig_ObjFaninC0(pObj);
+ Value1 = Ssw_CnfGetNodeValue( p, Aig_ObjFanin1(pObj) );
+ Value1 ^= Aig_ObjFaninC1(pObj);
+ return Value0 & Value1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswConstr.c b/src/proof/ssw/sswConstr.c
new file mode 100644
index 00000000..239e35b9
--- /dev/null
+++ b/src/proof/ssw/sswConstr.c
@@ -0,0 +1,714 @@
+/**CFile****************************************************************
+
+ FileName [sswConstr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [One round of SAT sweeping.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswConstr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/sat/cnf/cnf.h"
+#include "src/misc/bar/bar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Constructs initialized timeframes with constraints as POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_FramesWithConstraints( Aig_Man_t * p, int nFrames )
+{
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, f;
+ assert( Saig_ManConstrNum(p) > 0 );
+ assert( Aig_ManRegNum(p) > 0 );
+ assert( Aig_ManRegNum(p) < Aig_ManPiNum(p) );
+ // start the fraig package
+ pFrames = Aig_ManStart( Aig_ManObjNumMax(p) * nFrames );
+ // create latches for the first frame
+ Saig_ManForEachLo( p, pObj, i )
+ Aig_ObjSetCopy( pObj, Aig_ManConst0(pFrames) );
+ // add timeframes
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // map constants and PIs
+ Aig_ObjSetCopy( Aig_ManConst1(p), Aig_ManConst1(pFrames) );
+ Saig_ManForEachPi( p, pObj, i )
+ Aig_ObjSetCopy( pObj, Aig_ObjCreatePi(pFrames) );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( p, pObj, i )
+ Aig_ObjSetCopy( pObj, Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ) );
+ // transfer to the primary output
+ Aig_ManForEachPo( p, pObj, i )
+ Aig_ObjSetCopy( pObj, Aig_ObjChild0Copy(pObj) );
+ // create constraint outputs
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) )
+ continue;
+ Aig_ObjCreatePo( pFrames, Aig_Not( Aig_ObjCopy(pObj) ) );
+ }
+ // transfer latch inputs to the latch outputs
+ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
+ Aig_ObjSetCopy( pObjLo, Aig_ObjCopy(pObjLi) );
+ }
+ // remove dangling nodes
+ Aig_ManCleanup( pFrames );
+ return pFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds one satisfiable assignment of the timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits )
+{
+ Aig_Man_t * pFrames;
+ sat_solver * pSat;
+ Cnf_Dat_t * pCnf;
+ Aig_Obj_t * pObj;
+ int i, RetValue;
+ if ( pvInits )
+ *pvInits = NULL;
+ assert( p->nConstrs > 0 );
+ // derive the timeframes
+ pFrames = Ssw_FramesWithConstraints( p, nFrames );
+ // create CNF
+ pCnf = Cnf_Derive( pFrames, 0 );
+ // create SAT solver
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ if ( pSat == NULL )
+ {
+ Cnf_DataFree( pCnf );
+ Aig_ManStop( pFrames );
+ return 1;
+ }
+ // solve
+ RetValue = sat_solver_solve( pSat, NULL, NULL,
+ (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( RetValue == l_True && pvInits )
+ {
+ *pvInits = Vec_IntAlloc( 1000 );
+ Aig_ManForEachPi( pFrames, pObj, i )
+ Vec_IntPush( *pvInits, sat_solver_var_value(pSat, pCnf->pVarNums[Aig_ObjId(pObj)]) );
+
+// Aig_ManForEachPi( pFrames, pObj, i )
+// printf( "%d", Vec_IntEntry(*pvInits, i) );
+// printf( "\n" );
+ }
+ sat_solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ Aig_ManStop( pFrames );
+ if ( RetValue == l_False )
+ return 1;
+ if ( RetValue == l_True )
+ return 0;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSetConstrPhases_( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits )
+{
+ Vec_Int_t * vLits;
+ sat_solver * pSat;
+ Cnf_Dat_t * pCnf;
+ Aig_Obj_t * pObj;
+ int i, f, iVar, RetValue, nRegs;
+ if ( pvInits )
+ *pvInits = NULL;
+ assert( p->nConstrs > 0 );
+ // create CNF
+ nRegs = p->nRegs; p->nRegs = 0;
+ pCnf = Cnf_Derive( p, Aig_ManPoNum(p) );
+ p->nRegs = nRegs;
+ // create SAT solver
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 );
+ assert( pSat->size == nFrames * pCnf->nVars );
+ // collect constraint literals
+ vLits = Vec_IntAlloc( 100 );
+ Saig_ManForEachLo( p, pObj, i )
+ {
+ assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 );
+ Vec_IntPush( vLits, toLitCond(pCnf->pVarNums[Aig_ObjId(pObj)], 1) );
+ }
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) )
+ continue;
+ assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 );
+ iVar = pCnf->pVarNums[Aig_ObjId(pObj)] + pCnf->nVars*f;
+ Vec_IntPush( vLits, toLitCond(iVar, 1) );
+ }
+ }
+ RetValue = sat_solver_solve( pSat, (int *)Vec_IntArray(vLits),
+ (int *)Vec_IntArray(vLits) + Vec_IntSize(vLits),
+ (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( RetValue == l_True && pvInits )
+ {
+ *pvInits = Vec_IntAlloc( 1000 );
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Saig_ManForEachPi( p, pObj, i )
+ {
+ iVar = pCnf->pVarNums[Aig_ObjId(pObj)] + pCnf->nVars*f;
+ Vec_IntPush( *pvInits, sat_solver_var_value(pSat, iVar) );
+ }
+ }
+ }
+ sat_solver_delete( pSat );
+ Vec_IntFree( vLits );
+ Cnf_DataFree( pCnf );
+ if ( RetValue == l_False )
+ return 1;
+ if ( RetValue == l_True )
+ return 0;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManPrintPolarity( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Aig_ManForEachObj( p, pObj, i )
+ printf( "%d", pObj->fPhase );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManRefineByConstrSim( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i, iLits, RetValue1, RetValue2;
+ int nFrames = Vec_IntSize(p->vInits) / Saig_ManPiNum(p->pAig);
+ assert( Vec_IntSize(p->vInits) % Saig_ManPiNum(p->pAig) == 0 );
+ // assign register outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ pObj->fMarkB = 0;
+ // simulate the timeframes
+ iLits = 0;
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = Vec_IntEntry( p->vInits, iLits++ );
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ // check the outputs
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) )
+ {
+ if ( pObj->fMarkB )
+ printf( "output %d failed in frame %d.\n", i, f );
+ }
+ else
+ {
+ if ( pObj->fMarkB )
+ printf( "constraint %d failed in frame %d.\n", i, f );
+ }
+ }
+ // transfer
+ if ( f == 0 )
+ { // copy markB into phase
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pObj->fPhase = pObj->fMarkB;
+ }
+ else
+ { // refine classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
+ }
+ }
+ assert( iLits == Vec_IntSize(p->vInits) );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepNodeConstr( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
+{
+ Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
+ int RetValue;
+ // get representative of this class
+ pObjRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pObjRepr == NULL )
+ return 0;
+ // get the fraiged node
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ // get the fraiged representative
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
+ // check if constant 0 pattern distinquishes these nodes
+ assert( pObjFraig != NULL && pObjReprFraig != NULL );
+ assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) );
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return 0;
+ // call equivalence checking
+ if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ else
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
+ if ( RetValue == 1 ) // proved equivalent
+ {
+ pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
+ Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
+ return 0;
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+ Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ return 1;
+ }
+ // disproved equivalence
+ Ssw_SmlSavePatternAig( p, f );
+ Ssw_ManResimulateBit( p, pObj, pObjRepr );
+ assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
+ if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
+ {
+ printf( "Ssw_ManSweepNodeConstr(): Failed to refine representative.\n" );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Ssw_ManSweepBmcConstr_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pObjNew, * pObjLi;
+ pObjNew = Ssw_ObjFrame( p, pObj, f );
+ if ( pObjNew )
+ return pObjNew;
+ assert( !Saig_ObjIsPi(p->pAig, pObj) );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ {
+ assert( f > 0 );
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
+ pObjNew = Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObjLi), f-1 );
+ pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) );
+ }
+ else
+ {
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObj), f );
+ Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin1(pObj), f );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ }
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ assert( pObjNew != NULL );
+ return pObjNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepBmcConstr_old( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ int i, f, iLits, clk;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
+
+ // build the constraint outputs
+ iLits = 0;
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(p->pFrames);
+ pObjNew->fPhase = Vec_IntEntry( p->vInits, iLits++ );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ }
+ // build the constraint cones
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) )
+ continue;
+ pObjNew = Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObj), f );
+ pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) );
+ if ( Aig_Regular(pObjNew) == Aig_ManConst1(p->pFrames) )
+ {
+ assert( Aig_IsComplement(pObjNew) );
+ continue;
+ }
+ Ssw_NodesAreConstrained( p, pObjNew, Aig_ManConst0(p->pFrames) );
+ }
+ }
+ assert( Vec_IntSize(p->vInits) == iLits + Saig_ManPiNum(p->pAig) );
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 1 );
+ }
+ // quit if this is the last timeframe
+ if ( f == p->pPars->nFramesK - 1 )
+ break;
+ // transfer latch input to the latch outputs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjFrame( p, pObjLi, f );
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
+ }
+ }
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return p->fRefined;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepBmcConstr( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ int i, f, iLits, clk;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
+
+ // build the constraint outputs
+ iLits = 0;
+ p->fRefined = 0;
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(p->pFrames);
+ pObjNew->fPhase = Vec_IntEntry( p->vInits, iLits++ );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ }
+ // build the constraint cones
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) )
+ continue;
+ pObjNew = Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObj), f );
+ pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) );
+ if ( Aig_Regular(pObjNew) == Aig_ManConst1(p->pFrames) )
+ {
+ assert( Aig_IsComplement(pObjNew) );
+ continue;
+ }
+ Ssw_NodesAreConstrained( p, pObjNew, Aig_ManConst0(p->pFrames) );
+ }
+
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 1 );
+ }
+ // quit if this is the last timeframe
+ if ( f == p->pPars->nFramesK - 1 )
+ break;
+ // transfer latch input to the latch outputs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjFrame( p, pObjLi, f );
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
+ }
+ }
+ assert( Vec_IntSize(p->vInits) == iLits + Saig_ManPiNum(p->pAig) );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return p->fRefined;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Ssw_FramesWithClasses_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pObjNew, * pObjLi;
+ pObjNew = Ssw_ObjFrame( p, pObj, f );
+ if ( pObjNew )
+ return pObjNew;
+ assert( !Saig_ObjIsPi(p->pAig, pObj) );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ {
+ assert( f > 0 );
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
+ pObjNew = Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObjLi), f-1 );
+ pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) );
+ }
+ else
+ {
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObj), f );
+ Ssw_FramesWithClasses_rec( p, Aig_ObjFanin1(pObj), f );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ }
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ assert( pObjNew != NULL );
+ return pObjNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepConstr( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObj2, * pObjNew;
+ int nConstrPairs, clk, i, f, iLits;
+//Ssw_ManPrintPolarity( p->pAig );
+
+ // perform speculative reduction
+clk = clock();
+ // create timeframes
+ p->pFrames = Ssw_FramesWithClasses( p );
+ // add constants
+ nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
+ assert( (nConstrPairs & 1) == 0 );
+ for ( i = 0; i < nConstrPairs; i += 2 )
+ {
+ pObj = Aig_ManPo( p->pFrames, i );
+ pObj2 = Aig_ManPo( p->pFrames, i+1 );
+ Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
+ }
+ // build logic cones for register inputs
+ for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
+ {
+ pObj = Aig_ManPo( p->pFrames, nConstrPairs + i );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pObj) );//
+ }
+
+ // map constants and PIs of the last frame
+ f = p->pPars->nFramesK;
+// iLits = 0;
+ iLits = f * Saig_ManPiNum(p->pAig);
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(p->pFrames);
+ pObjNew->fPhase = (p->vInits != NULL) && Vec_IntEntry(p->vInits, iLits++);
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ }
+ assert( Vec_IntSize(p->vInits) == iLits );
+p->timeReduce += clock() - clk;
+
+ // add constraints to all timeframes
+ for ( f = 0; f <= p->pPars->nFramesK; f++ )
+ {
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) )
+ continue;
+ Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObj), f );
+// if ( Aig_Regular(Ssw_ObjChild0Fra(p,pObj,f)) == Aig_ManConst1(p->pFrames) )
+ if ( Ssw_ObjChild0Fra(p,pObj,f) == Aig_ManConst0(p->pFrames) )
+ continue;
+ assert( Ssw_ObjChild0Fra(p,pObj,f) != Aig_ManConst1(p->pFrames) );
+ if ( Ssw_ObjChild0Fra(p,pObj,f) == Aig_ManConst1(p->pFrames) )
+ {
+ printf( "Polarity violation.\n" );
+ continue;
+ }
+ Ssw_NodesAreConstrained( p, Ssw_ObjChild0Fra(p,pObj,f), Aig_ManConst0(p->pFrames) );
+ }
+ }
+ f = p->pPars->nFramesK;
+ // clean the solver
+ sat_solver_simplify( p->pMSat->pSat );
+
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ Ssw_ClassesClearRefined( p->ppClasses );
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, i, NULL );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 0 );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 0 );
+ }
+ }
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswCore.c b/src/proof/ssw/sswCore.c
new file mode 100644
index 00000000..df48a5b8
--- /dev/null
+++ b/src/proof/ssw/sswCore.c
@@ -0,0 +1,522 @@
+/**CFile****************************************************************
+
+ FileName [sswCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [The core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswCore.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
+{
+ memset( p, 0, sizeof(Ssw_Pars_t) );
+ p->nPartSize = 0; // size of the partition
+ p->nOverSize = 0; // size of the overlap between partitions
+ p->nFramesK = 1; // the induction depth
+ p->nFramesAddSim = 2; // additional frames to simulate
+ p->fConstrs = 0; // treat the last nConstrs POs as seq constraints
+ p->fMergeFull = 0; // enables full merge when constraints are used
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->nBTLimitGlobal = 5000000; // conflict limit for all runs
+ p->nMinDomSize = 100; // min clock domain considered for optimization
+ p->nItersStop = -1; // stop after the given number of iterations
+ p->nResimDelta = 1000; // the internal of nodes to resimulate
+ p->nStepsMax = -1; // (scorr only) the max number of induction steps
+ p->fPolarFlip = 0; // uses polarity adjustment
+ p->fLatchCorr = 0; // performs register correspondence
+ p->fConstCorr = 0; // performs constant correspondence
+ p->fOutputCorr = 0; // perform 'PO correspondence'
+ p->fSemiFormal = 0; // enable semiformal filtering
+ p->fDynamic = 0; // dynamic partitioning
+ p->fLocalSim = 0; // local simulation
+ p->fVerbose = 0; // verbose stats
+ p->fEquivDump = 0; // enables dumping equivalences
+
+ // latch correspondence
+ p->fLatchCorrOpt = 0; // performs optimized register correspondence
+ p->nSatVarMax = 1000; // the max number of SAT variables
+ p->nRecycleCalls = 50; // calls to perform before recycling SAT solver
+ // signal correspondence
+ p->nSatVarMax2 = 5000; // the max number of SAT variables
+ p->nRecycleCalls2 = 250; // calls to perform before recycling SAT solver
+ // return values
+ p->nIters = 0; // the number of iterations performed
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p )
+{
+ Ssw_ManSetDefaultParams( p );
+ p->fLatchCorrOpt = 1;
+ p->nBTLimit = 10000;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports improvements for property cones.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ReportConeReductions( Ssw_Man_t * p, Aig_Man_t * pAigInit, Aig_Man_t * pAigStop )
+{
+ Aig_Man_t * pAig1, * pAig2, * pAux;
+ pAig1 = Aig_ManDupOneOutput( pAigInit, 0, 1 );
+ pAig1 = Aig_ManScl( pAux = pAig1, 1, 1, 0, -1, -1, 0, 0 );
+ Aig_ManStop( pAux );
+ pAig2 = Aig_ManDupOneOutput( pAigStop, 0, 1 );
+ pAig2 = Aig_ManScl( pAux = pAig2, 1, 1, 0, -1, -1, 0, 0 );
+ Aig_ManStop( pAux );
+
+ p->nNodesBegC = Aig_ManNodeNum(pAig1);
+ p->nNodesEndC = Aig_ManNodeNum(pAig2);
+ p->nRegsBegC = Aig_ManRegNum(pAig1);
+ p->nRegsEndC = Aig_ManRegNum(pAig2);
+
+ Aig_ManStop( pAig1 );
+ Aig_ManStop( pAig2 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ReportOneOutput( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ if ( pObj == Aig_ManConst1(p) )
+ printf( "1" );
+ else if ( pObj == Aig_ManConst0(p) )
+ printf( "0" );
+ else
+ printf( "X" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports improvements for property cones.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ReportOutputs( Aig_Man_t * pAig )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Saig_ManForEachPo( pAig, pObj, i )
+ {
+ if ( i < Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) )
+ printf( "o" );
+ else
+ printf( "c" );
+ Ssw_ReportOneOutput( pAig, Aig_ObjChild0(pObj) );
+ }
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remove from-equivs that are in the cone of constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManUpdateEquivs( Ssw_Man_t * p, Aig_Man_t * pAig, int fVerbose )
+{
+ Vec_Ptr_t * vCones;
+ Aig_Obj_t ** pArray;
+ Aig_Obj_t * pObj;
+ int i, nTotal = 0, nRemoved = 0;
+ // collect the nodes in the cone of constraints
+ pArray = (Aig_Obj_t **)Vec_PtrArray(pAig->vPos);
+ pArray += Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig);
+ vCones = Aig_ManDfsNodes( pAig, pArray, Saig_ManConstrNum(pAig) );
+ // remove all the node that are equiv to something and are in the cones
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) )
+ continue;
+ if ( pAig->pReprs[i] != NULL )
+ nTotal++;
+ if ( !Aig_ObjIsTravIdCurrent(pAig, pObj) )
+ continue;
+ if ( pAig->pReprs[i] )
+ {
+ if ( p->pPars->fConstrs && !p->pPars->fMergeFull )
+ {
+ pAig->pReprs[i] = NULL;
+ nRemoved++;
+ }
+ }
+ }
+ // collect statistics
+ p->nConesTotal = Aig_ManPiNum(pAig) + Aig_ManNodeNum(pAig);
+ p->nConesConstr = Vec_PtrSize(vCones);
+ p->nEquivsTotal = nTotal;
+ p->nEquivsConstr = nRemoved;
+ Vec_PtrFree( vCones );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of signal correspondence with constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
+{
+ int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal, nUniques;
+ Aig_Man_t * pAigNew;
+ int RetValue, nIter = -1;
+ int clk, clkTotal = clock();
+ // get the starting stats
+ p->nLitsBeg = Ssw_ClassesLitNum( p->ppClasses );
+ p->nNodesBeg = Aig_ManNodeNum(p->pAig);
+ p->nRegsBeg = Aig_ManRegNum(p->pAig);
+ // refine classes using BMC
+ if ( p->pPars->fVerbose )
+ {
+ printf( "Before BMC: " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ if ( !p->pPars->fLatchCorr )
+ {
+ p->pMSat = Ssw_SatStart( 0 );
+ if ( p->pPars->fConstrs )
+ Ssw_ManSweepBmcConstr( p );
+ else
+ Ssw_ManSweepBmc( p );
+ Ssw_SatStop( p->pMSat );
+ p->pMSat = NULL;
+ Ssw_ManCleanup( p );
+ }
+ if ( p->pPars->fVerbose )
+ {
+ printf( "After BMC: " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ // apply semi-formal filtering
+/*
+ if ( p->pPars->fSemiFormal )
+ {
+ Aig_Man_t * pSRed;
+ Ssw_FilterUsingSemi( p, 0, 2000, p->pPars->fVerbose );
+// Ssw_FilterUsingSemi( p, 1, 100000, p->pPars->fVerbose );
+ pSRed = Ssw_SpeculativeReduction( p );
+ Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
+ Aig_ManStop( pSRed );
+ }
+*/
+ if ( p->pPars->pFunc )
+ {
+ ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData );
+ ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData );
+ }
+ if ( p->pPars->nStepsMax == 0 )
+ {
+ printf( "Stopped signal correspondence after BMC.\n" );
+ goto finalize;
+ }
+ // refine classes using induction
+ nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = nUniques = 0;
+ for ( nIter = 0; ; nIter++ )
+ {
+ if ( p->pPars->nStepsMax == nIter )
+ {
+ printf( "Stopped signal correspondence after %d refiment iterations.\n", nIter );
+ goto finalize;
+ }
+ if ( p->pPars->nItersStop >= 0 && p->pPars->nItersStop == nIter )
+ {
+ Aig_Man_t * pSRed = Ssw_SpeculativeReduction( p );
+ Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
+ Aig_ManStop( pSRed );
+ printf( "Iterative refinement is stopped before iteration %d.\n", nIter );
+ printf( "The network is reduced using candidate equivalences.\n" );
+ printf( "Speculatively reduced miter is saved in file \"%s\".\n", "srm.blif" );
+ printf( "If the miter is SAT, the reduced result is incorrect.\n" );
+ break;
+ }
+
+clk = clock();
+ p->pMSat = Ssw_SatStart( 0 );
+ if ( p->pPars->fLatchCorrOpt )
+ {
+ RetValue = Ssw_ManSweepLatch( p );
+ if ( p->pPars->fVerbose )
+ {
+ printf( "%3d : C =%7d. Cl =%7d. Pr =%6d. Cex =%5d. R =%4d. F =%4d. ",
+ nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
+ p->nSatProof-nSatProof, p->nSatCallsSat-nSatCallsSat,
+ p->nRecycles-nRecycles, p->nSatFailsReal-nSatFailsReal );
+ ABC_PRT( "T", clock() - clk );
+ }
+ }
+ else
+ {
+ if ( p->pPars->fConstrs )
+ RetValue = Ssw_ManSweepConstr( p );
+ else if ( p->pPars->fDynamic )
+ RetValue = Ssw_ManSweepDyn( p );
+ else
+ RetValue = Ssw_ManSweep( p );
+
+ p->pPars->nConflicts += p->pMSat->pSat->stats.conflicts;
+ if ( p->pPars->fVerbose )
+ {
+ printf( "%3d : C =%7d. Cl =%7d. LR =%6d. NR =%6d. ",
+ nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
+ p->nConstrReduced, Aig_ManNodeNum(p->pFrames) );
+ if ( p->pPars->fDynamic )
+ {
+ printf( "Cex =%5d. ", p->nSatCallsSat-nSatCallsSat );
+ printf( "R =%4d. ", p->nRecycles-nRecycles );
+ }
+ printf( "F =%5d. %s ", p->nSatFailsReal-nSatFailsReal,
+ (Saig_ManPoNum(p->pAig)==1 && Ssw_ObjIsConst1Cand(p->pAig,Aig_ObjFanin0(Aig_ManPo(p->pAig,0))))? "+" : "-" );
+ ABC_PRT( "T", clock() - clk );
+ }
+// if ( p->pPars->fDynamic && p->nSatCallsSat-nSatCallsSat < 100 )
+// p->pPars->nBTLimit = 10000;
+ }
+ nSatProof = p->nSatProof;
+ nSatCallsSat = p->nSatCallsSat;
+ nRecycles = p->nRecycles;
+ nSatFailsReal = p->nSatFailsReal;
+ nUniques = p->nUniques;
+
+ p->nVarsMax = Abc_MaxInt( p->nVarsMax, p->pMSat->nSatVars );
+ p->nCallsMax = Abc_MaxInt( p->nCallsMax, p->pMSat->nSolverCalls );
+ Ssw_SatStop( p->pMSat );
+ p->pMSat = NULL;
+ Ssw_ManCleanup( p );
+ if ( !RetValue )
+ break;
+ if ( p->pPars->pFunc )
+ ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData );
+ }
+
+finalize:
+ p->pPars->nIters = nIter + 1;
+p->timeTotal = clock() - clkTotal;
+
+ Ssw_ManUpdateEquivs( p, p->pAig, p->pPars->fVerbose );
+ pAigNew = Aig_ManDupRepr( p->pAig, 0 );
+ Aig_ManSeqCleanup( pAigNew );
+//Ssw_ClassesPrint( p->ppClasses, 1 );
+ // get the final stats
+ p->nLitsEnd = Ssw_ClassesLitNum( p->ppClasses );
+ p->nNodesEnd = Aig_ManNodeNum(pAigNew);
+ p->nRegsEnd = Aig_ManRegNum(pAigNew);
+ // cleanup
+ Aig_ManSetPhase( p->pAig );
+ Aig_ManCleanMarkB( p->pAig );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of signal correspondence with constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Ssw_Pars_t Pars;
+ Aig_Man_t * pAigNew;
+ Ssw_Man_t * p;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ // reset random numbers
+ Aig_ManRandom( 1 );
+ // if parameters are not given, create them
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ {
+ pPars->nIters = 0;
+ // Ntl_ManFinalize() needs the following to satisfy an assertion
+ Aig_ManReprStart( pAig,Aig_ManObjNumMax(pAig) );
+ return Aig_ManDupOrdered(pAig);
+ }
+ // check and update parameters
+ if ( pPars->fLatchCorrOpt )
+ {
+ pPars->fLatchCorr = 1;
+ pPars->nFramesAddSim = 0;
+ if ( (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
+ return Ssw_SignalCorrespondencePart( pAig, pPars );
+ }
+ else
+ {
+ assert( pPars->nFramesK > 0 );
+ // perform partitioning
+ if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig))
+ || (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
+ return Ssw_SignalCorrespondencePart( pAig, pPars );
+ }
+
+ if ( pPars->fScorrGia )
+ {
+ if ( pPars->fLatchCorrOpt )
+ {
+ extern Aig_Man_t * Cec_LatchCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat );
+ return Cec_LatchCorrespondence( pAig, pPars->nBTLimit, pPars->fUseCSat );
+ }
+ else
+ {
+ extern Aig_Man_t * Cec_SignalCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat );
+ return Cec_SignalCorrespondence( pAig, pPars->nBTLimit, pPars->fUseCSat );
+ }
+ }
+
+ // start the induction manager
+ p = Ssw_ManCreate( pAig, pPars );
+ // compute candidate equivalence classes
+// p->pPars->nConstrs = 1;
+ if ( p->pPars->fConstrs )
+ {
+ // create trivial equivalence classes with all nodes being candidates for constant 1
+ p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs );
+ Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
+ // derive phase bits to satisfy the constraints
+ if ( Ssw_ManSetConstrPhases( pAig, p->pPars->nFramesK + 1, &p->vInits ) != 0 )
+ {
+ printf( "Ssw_SignalCorrespondence(): The init state does not satisfy the constraints!\n" );
+ p->pPars->fVerbose = 0;
+ Ssw_ManStop( p );
+ return NULL;
+ }
+ // perform simulation of the first timeframes
+ Ssw_ManRefineByConstrSim( p );
+ }
+ else
+ {
+ // perform one round of seq simulation and generate candidate equivalence classes
+ p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->nFramesK, pPars->fLatchCorr, pPars->fConstCorr, pPars->fOutputCorr, pPars->nMaxLevs, pPars->fVerbose );
+// p->ppClasses = Ssw_ClassesPrepareTargets( pAig );
+ if ( pPars->fLatchCorrOpt )
+ p->pSml = Ssw_SmlStart( pAig, 0, 2, 1 );
+ else if ( pPars->fDynamic )
+ p->pSml = Ssw_SmlStart( pAig, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
+ else
+ p->pSml = Ssw_SmlStart( pAig, 0, 1 + p->pPars->nFramesAddSim, 1 );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
+ }
+ // allocate storage
+ if ( p->pPars->fLocalSim )
+ p->pVisited = ABC_CALLOC( int, Ssw_SmlNumFrames( p->pSml ) * Aig_ManObjNumMax(p->pAig) );
+ // perform refinement of classes
+ pAigNew = Ssw_SignalCorrespondenceRefine( p );
+// Ssw_ReportOutputs( pAigNew );
+ if ( pPars->fConstrs && pPars->fVerbose )
+ Ssw_ReportConeReductions( p, pAig, pAigNew );
+ // cleanup
+ Ssw_ManStop( p );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of latch correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pRes;
+ Ssw_Pars_t Pars;
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParamsLcorr( pPars = &Pars );
+ pRes = Ssw_SignalCorrespondence( pAig, pPars );
+// if ( pPars->fConstrs && pPars->fVerbose )
+// Ssw_ReportConeReductions( pAig, pRes );
+ return pRes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswDyn.c b/src/proof/ssw/sswDyn.c
new file mode 100644
index 00000000..d9a16e22
--- /dev/null
+++ b/src/proof/ssw/sswDyn.c
@@ -0,0 +1,489 @@
+/**CFile****************************************************************
+
+ FileName [sswDyn.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Dynamic loading of constraints.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswDyn.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/misc/bar/bar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Label PIs nodes of the frames corresponding to PIs of AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManLabelPiNodes( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjFrames;
+ int f, i;
+ Aig_ManConst1( p->pFrames )->fMarkA = 1;
+ Aig_ManConst1( p->pFrames )->fMarkB = 1;
+ for ( f = 0; f < p->nFrames; f++ )
+ {
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjFrames = Ssw_ObjFrame( p, pObj, f );
+ assert( Aig_ObjIsPi(pObjFrames) );
+ assert( pObjFrames->fMarkB == 0 );
+ pObjFrames->fMarkA = 1;
+ pObjFrames->fMarkB = 1;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects new POs in p->vNewPos.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManCollectPis_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vNewPis )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( pObj->fMarkA )
+ return;
+ pObj->fMarkA = 1;
+ if ( Aig_ObjIsPi(pObj) )
+ {
+ Vec_PtrPush( vNewPis, pObj );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_ManCollectPis_rec( Aig_ObjFanin0(pObj), vNewPis );
+ Ssw_ManCollectPis_rec( Aig_ObjFanin1(pObj), vNewPis );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects new POs in p->vNewPos.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManCollectPos_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vNewPos )
+{
+ Aig_Obj_t * pFanout;
+ int iFanout = -1, i;
+ assert( !Aig_IsComplement(pObj) );
+ if ( pObj->fMarkB )
+ return;
+ pObj->fMarkB = 1;
+ if ( pObj->Id > p->nSRMiterMaxId )
+ return;
+ if ( Aig_ObjIsPo(pObj) )
+ {
+ // skip if it is a register input PO
+ if ( Aig_ObjPioNum(pObj) >= Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig) )
+ return;
+ // add the number of this constraint
+ Vec_IntPush( vNewPos, Aig_ObjPioNum(pObj)/2 );
+ return;
+ }
+ // visit the fanouts
+ assert( p->pFrames->pFanData != NULL );
+ Aig_ObjForEachFanout( p->pFrames, pObj, pFanout, iFanout, i )
+ Ssw_ManCollectPos_rec( p, pFanout, vNewPos );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Loads logic cones and relevant constraints.]
+
+ Description [Both pRepr and pObj are objects of the AIG.
+ The result is the current SAT solver loaded with the logic cones
+ for pRepr and pObj corresponding to them in the frames,
+ as well as all the relevant constraints.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManLoadSolver( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObjFrames, * pReprFrames;
+ Aig_Obj_t * pTemp, * pObj0, * pObj1;
+ int i, iConstr, RetValue;
+
+ assert( pRepr != pObj );
+ // get the corresponding frames nodes
+ pReprFrames = Aig_Regular( Ssw_ObjFrame( p, pRepr, p->pPars->nFramesK ) );
+ pObjFrames = Aig_Regular( Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) );
+ assert( pReprFrames != pObjFrames );
+ /*
+ // compute the AIG support
+ Vec_PtrClear( p->vNewLos );
+ Ssw_ManCollectPis_rec( pRepr, p->vNewLos );
+ Ssw_ManCollectPis_rec( pObj, p->vNewLos );
+ // add logic cones for register outputs
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vNewLos, pTemp, i )
+ {
+ pObj0 = Aig_Regular( Ssw_ObjFrame( p, pTemp, p->pPars->nFramesK ) );
+ Ssw_CnfNodeAddToSolver( p->pMSat, pObj0 );
+ }
+*/
+ // add cones for the nodes
+ Ssw_CnfNodeAddToSolver( p->pMSat, pReprFrames );
+ Ssw_CnfNodeAddToSolver( p->pMSat, pObjFrames );
+
+ // compute the frames support
+ Vec_PtrClear( p->vNewLos );
+ Ssw_ManCollectPis_rec( pReprFrames, p->vNewLos );
+ Ssw_ManCollectPis_rec( pObjFrames, p->vNewLos );
+ // these nodes include both nodes corresponding to PIs and LOs
+ // (the nodes corresponding to PIs should be labeled with fMarkB!)
+
+ // collect the related constraint POs
+ Vec_IntClear( p->vNewPos );
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vNewLos, pTemp, i )
+ Ssw_ManCollectPos_rec( p, pTemp, p->vNewPos );
+ // check if the corresponding pairs are added
+ Vec_IntForEachEntry( p->vNewPos, iConstr, i )
+ {
+ pObj0 = Aig_ManPo( p->pFrames, 2*iConstr );
+ pObj1 = Aig_ManPo( p->pFrames, 2*iConstr+1 );
+// if ( pObj0->fMarkB && pObj1->fMarkB )
+ if ( pObj0->fMarkB || pObj1->fMarkB )
+ {
+ pObj0->fMarkB = 1;
+ pObj1->fMarkB = 1;
+ Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj0), Aig_ObjChild0(pObj1) );
+ }
+ }
+ if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pMSat->pSat);
+ assert( RetValue != 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tranfers simulation information from FRAIG to AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepTransferDyn( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjFraig;
+ unsigned * pInfo;
+ int i, f, nFrames;
+
+ // transfer simulation information
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjFraig = Ssw_ObjFrame( p, pObj, 0 );
+ if ( pObjFraig == Aig_ManConst0(p->pFrames) )
+ {
+ Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 );
+ continue;
+ }
+ assert( !Aig_IsComplement(pObjFraig) );
+ assert( Aig_ObjIsPi(pObjFraig) );
+ pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) );
+ Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 );
+ }
+ // set random simulation info for the second frame
+ for ( f = 1; f < p->nFrames; f++ )
+ {
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ assert( !Aig_IsComplement(pObjFraig) );
+ assert( Aig_ObjIsPi(pObjFraig) );
+ pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) );
+ Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, f );
+ }
+ }
+ // create random info
+ nFrames = Ssw_SmlNumFrames( p->pSml );
+ for ( ; f < nFrames; f++ )
+ {
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandomFrame( p->pSml, pObj, f );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of simulation with counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepResimulateDyn( Ssw_Man_t * p, int f )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // transfer PI simulation information from storage
+// Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
+ Ssw_ManSweepTransferDyn( p );
+ // simulate internal nodes
+// Ssw_SmlSimulateOneFrame( p->pSml );
+ Ssw_SmlSimulateOne( p->pSml );
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // prepare simulation info for the next round
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+ p->nPatterns = 0;
+ p->nSimRounds++;
+p->timeSimSat += clock() - clk;
+ return RetValue1 > 0 || RetValue2 > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of simulation with counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepResimulateDynLocal( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj, * pRepr, ** ppClass;
+ int i, k, nSize, RetValue1, RetValue2, clk = clock();
+ p->nSimRounds++;
+ // transfer PI simulation information from storage
+// Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
+ Ssw_ManSweepTransferDyn( p );
+ // determine const1 cands and classes to be simulated
+ Vec_PtrClear( p->vResimConsts );
+ Vec_PtrClear( p->vResimClasses );
+ Aig_ManIncrementTravId( p->pAig );
+ for ( i = p->iNodeStart; i < p->iNodeLast + p->pPars->nResimDelta; i++ )
+ {
+ if ( i >= Aig_ManObjNumMax( p->pAig ) )
+ break;
+ pObj = Aig_ManObj( p->pAig, i );
+ if ( pObj == NULL )
+ continue;
+ if ( Ssw_ObjIsConst1Cand(p->pAig, pObj) )
+ {
+ Vec_PtrPush( p->vResimConsts, pObj );
+ continue;
+ }
+ pRepr = Aig_ObjRepr(p->pAig, pObj);
+ if ( pRepr == NULL )
+ continue;
+ if ( Aig_ObjIsTravIdCurrent(p->pAig, pRepr) )
+ continue;
+ Aig_ObjSetTravIdCurrent(p->pAig, pRepr);
+ Vec_PtrPush( p->vResimClasses, pRepr );
+ }
+ // simulate internal nodes
+// Ssw_SmlSimulateOneFrame( p->pSml );
+// Ssw_SmlSimulateOne( p->pSml );
+ // resimulate dynamically
+// Aig_ManIncrementTravId( p->pAig );
+// Aig_ObjIsTravIdCurrent( p->pAig, Aig_ManConst1(p->pAig) );
+ p->nVisCounter++;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimConsts, pObj, i )
+ Ssw_SmlSimulateOneDyn_rec( p->pSml, pObj, p->nFrames-1, p->pVisited, p->nVisCounter );
+ // resimulate the cone of influence of the cand classes
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimClasses, pRepr, i )
+ {
+ ppClass = Ssw_ClassesReadClass( p->ppClasses, pRepr, &nSize );
+ for ( k = 0; k < nSize; k++ )
+ Ssw_SmlSimulateOneDyn_rec( p->pSml, ppClass[k], p->nFrames-1, p->pVisited, p->nVisCounter );
+ }
+
+ // check equivalence classes
+// RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+// RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // refine these nodes
+ RetValue1 = Ssw_ClassesRefineConst1Group( p->ppClasses, p->vResimConsts, 1 );
+ RetValue2 = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimClasses, pRepr, i )
+ RetValue2 += Ssw_ClassesRefineOneClass( p->ppClasses, pRepr, 1 );
+
+ // prepare simulation info for the next round
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+ p->nPatterns = 0;
+ p->nSimRounds++;
+p->timeSimSat += clock() - clk;
+ return RetValue1 > 0 || RetValue2 > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepDyn( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObjNew;
+ int clk, i, f;
+
+ // perform speculative reduction
+clk = clock();
+ // create timeframes
+ p->pFrames = Ssw_FramesWithClasses( p );
+ Aig_ManFanoutStart( p->pFrames );
+ p->nSRMiterMaxId = Aig_ManObjNumMax( p->pFrames );
+
+ // map constants and PIs of the last frame
+ f = p->pPars->nFramesK;
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+ Aig_ManSetPioNumbers( p->pFrames );
+ // label nodes corresponding to primary inputs
+ Ssw_ManLabelPiNodes( p );
+p->timeReduce += clock() - clk;
+
+ // prepare simulation info
+ assert( p->vSimInfo == NULL );
+ p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManPiNum(p->pFrames), 1 );
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ Ssw_ClassesClearRefined( p->ppClasses );
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
+ p->iNodeStart = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( p->iNodeStart == 0 )
+ p->iNodeStart = i;
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, i, NULL );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, NULL );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, NULL );
+ }
+ // check if it is time to recycle the solver
+ if ( p->pMSat->pSat == NULL ||
+ (p->pPars->nSatVarMax2 &&
+ p->pMSat->nSatVars > p->pPars->nSatVarMax2 &&
+ p->nRecycleCalls > p->pPars->nRecycleCalls2) )
+ {
+ // resimulate
+ if ( p->nPatterns > 0 )
+ {
+ p->iNodeLast = i;
+ if ( p->pPars->fLocalSim )
+ Ssw_ManSweepResimulateDynLocal( p, f );
+ else
+ Ssw_ManSweepResimulateDyn( p, f );
+ p->iNodeStart = i+1;
+ }
+// printf( "Recycling SAT solver with %d vars and %d calls.\n",
+// p->pMSat->nSatVars, p->nRecycleCalls );
+// Aig_ManCleanMarkAB( p->pAig );
+ Aig_ManCleanMarkAB( p->pFrames );
+ // label nodes corresponding to primary inputs
+ Ssw_ManLabelPiNodes( p );
+ // replace the solver
+ if ( p->pMSat )
+ {
+ p->nVarsMax = Abc_MaxInt( p->nVarsMax, p->pMSat->nSatVars );
+ p->nCallsMax = Abc_MaxInt( p->nCallsMax, p->pMSat->nSolverCalls );
+ Ssw_SatStop( p->pMSat );
+ p->nRecycles++;
+ p->nRecyclesTotal++;
+ p->nRecycleCalls = 0;
+ }
+ p->pMSat = Ssw_SatStart( 0 );
+ assert( p->nPatterns == 0 );
+ }
+ // resimulate
+ if ( p->nPatterns == 32 )
+ {
+ p->iNodeLast = i;
+ if ( p->pPars->fLocalSim )
+ Ssw_ManSweepResimulateDynLocal( p, f );
+ else
+ Ssw_ManSweepResimulateDyn( p, f );
+ p->iNodeStart = i+1;
+ }
+ }
+ // resimulate
+ if ( p->nPatterns > 0 )
+ {
+ p->iNodeLast = i;
+ if ( p->pPars->fLocalSim )
+ Ssw_ManSweepResimulateDynLocal( p, f );
+ else
+ Ssw_ManSweepResimulateDyn( p, f );
+ }
+ // collect stats
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswFilter.c b/src/proof/ssw/sswFilter.c
new file mode 100644
index 00000000..380ac7e5
--- /dev/null
+++ b/src/proof/ssw/sswFilter.c
@@ -0,0 +1,493 @@
+/**CFile****************************************************************
+
+ FileName [sswConstr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [One round of SAT sweeping.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswConstr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManRefineByFilterSim( Ssw_Man_t * p, int nFrames )
+{
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i, RetValue1, RetValue2;
+ assert( nFrames > 0 );
+ // assign register outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
+ // simulate the timeframes
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = 0;
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ // transfer
+ if ( f == 0 )
+ { // copy markB into phase
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pObj->fPhase = pObj->fMarkB;
+ }
+ else
+ { // refine classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManRollForward( Ssw_Man_t * p, int nFrames )
+{
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i;
+ assert( nFrames > 0 );
+ // assign register outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
+ // simulate the timeframes
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = Aig_ManRandom(0) & 1;
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ }
+ // record the new pattern
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ if ( pObj->fMarkB ^ Abc_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) )
+ Abc_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManFindStartingState( Ssw_Man_t * p, Abc_Cex_t * pCex )
+{
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i, iBit;
+ // assign register outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ pObj->fMarkB = 0;
+ // simulate the timeframes
+ iBit = pCex->nRegs;
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( pCex->pData, iBit++ );
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ }
+ assert( iBit == pCex->nBits );
+ // check that the output failed as expected -- cannot check because it is not an SRM!
+// pObj = Aig_ManPo( p->pAig, pCex->iPo );
+// if ( pObj->fMarkB != 1 )
+// printf( "The counter-example does not refine the output.\n" );
+ // record the new pattern
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ if ( pObj->fMarkB ^ Abc_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) )
+ Abc_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepNodeFilter( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
+ int RetValue;
+ // get representative of this class
+ pObjRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pObjRepr == NULL )
+ return 0;
+ // get the fraiged node
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ // get the fraiged representative
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
+ // check if constant 0 pattern distinquishes these nodes
+ assert( pObjFraig != NULL && pObjReprFraig != NULL );
+ assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) );
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return 0;
+ // call equivalence checking
+ if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ else
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
+ if ( RetValue == 1 ) // proved equivalent
+ {
+ pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
+ Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
+ return 0;
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+// Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ return 1;
+ }
+ // disproved equivalence
+ Ssw_SmlSavePatternAig( p, f );
+ Ssw_ManResimulateBit( p, pObj, pObjRepr );
+ assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
+ if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
+ {
+ printf( "Ssw_ManSweepNodeFilter(): Failed to refine representative.\n" );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Ssw_ManSweepBmcFilter_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pObjNew, * pObjLi;
+ pObjNew = Ssw_ObjFrame( p, pObj, f );
+ if ( pObjNew )
+ return pObjNew;
+ assert( !Saig_ObjIsPi(p->pAig, pObj) );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ {
+ assert( f > 0 );
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
+ pObjNew = Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObjLi), f-1 );
+ pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) );
+ }
+ else
+ {
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObj), f );
+ Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin1(pObj), f );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ }
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ assert( pObjNew != NULL );
+ return pObjNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepBmcFilter( Ssw_Man_t * p, int TimeLimit )
+{
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ int f, f1, i, clkTotal = clock();
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ if ( Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ) )
+ {
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst1(p->pFrames) );
+//printf( "1" );
+ }
+ else
+ {
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
+//printf( "0" );
+ }
+ }
+//printf( "\n" );
+
+ // sweep internal nodes
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // realloc mapping of timeframes
+ if ( f == p->nFrames-1 )
+ {
+ Aig_Obj_t ** pNodeToFrames;
+ pNodeToFrames = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * 2 * p->nFrames );
+ for ( f1 = 0; f1 < p->nFrames; f1++ )
+ {
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pNodeToFrames[2*p->nFrames*pObj->Id + f1] = Ssw_ObjFrame( p, pObj, f1 );
+ }
+ ABC_FREE( p->pNodeToFrames );
+ p->pNodeToFrames = pNodeToFrames;
+ p->nFrames *= 2;
+ }
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(p->pFrames);
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ }
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ if ( Ssw_ManSweepNodeFilter( p, pObj, f ) )
+ break;
+ }
+ // printout
+ if ( p->pPars->fVerbose )
+ {
+ printf( "Frame %4d : ", f );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ if ( i < Vec_PtrSize(p->pAig->vObjs) )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Exceeded the resource limits (%d conflicts). Quitting...\n", p->pPars->nBTLimit );
+ break;
+ }
+ // quit if this is the last timeframe
+ if ( f == p->pPars->nFramesK - 1 )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Exceeded the time frame limit (%d time frames). Quitting...\n", p->pPars->nFramesK );
+ break;
+ }
+ // check timeout
+ if ( TimeLimit && ((float)TimeLimit <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) )
+ break;
+ // transfer latch input to the latch outputs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjFrame( p, pObjLi, f );
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
+ }
+ }
+ // verify
+// Ssw_ClassesCheck( p->ppClasses );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description [Unrolls at most nFramesMax frames. Works with nConfMax
+ conflicts until the first undefined SAT call. Verbose prints the message.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SignalFilter( Aig_Man_t * pAig, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ Ssw_Pars_t Pars, * pPars = &Pars;
+ Ssw_Man_t * p;
+ int r, TimeLimitPart, clkTotal = clock();
+ int nTimeToStop = TimeLimit ? TimeLimit + time(NULL) : 0;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManConstrNum(pAig) == 0 );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ return;
+ // reset random numbers
+ Aig_ManRandom( 1 );
+ // if parameters are not given, create them
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ pPars->nFramesK = 3; //nFramesMax;
+ pPars->nBTLimit = nConfMax;
+ pPars->TimeLimit = TimeLimit;
+ pPars->fVerbose = fVerbose;
+ // start the induction manager
+ p = Ssw_ManCreate( pAig, pPars );
+ pPars->nFramesK = nFramesMax;
+ // create trivial equivalence classes with all nodes being candidates for constant 1
+ if ( pAig->pReprs == NULL )
+ p->ppClasses = Ssw_ClassesPrepareSimple( pAig, fLatchOnly, 0 );
+ else
+ p->ppClasses = Ssw_ClassesPrepareFromReprs( pAig );
+ Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
+ assert( p->vInits == NULL );
+ // compute starting state if needed
+ if ( pCex )
+ Ssw_ManFindStartingState( p, pCex );
+ // refine classes using BMC
+ for ( r = 0; r < nRounds; r++ )
+ {
+ if ( p->pPars->fVerbose )
+ printf( "Round %3d:\n", r );
+ // start filtering equivalence classes
+ Ssw_ManRefineByFilterSim( p, p->pPars->nFramesK );
+ if ( Ssw_ClassesCand1Num(p->ppClasses) == 0 && Ssw_ClassesClassNum(p->ppClasses) == 0 )
+ {
+ printf( "All equivalences are refined away.\n" );
+ break;
+ }
+ // printout
+ if ( p->pPars->fVerbose )
+ {
+ printf( "Initial : " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ p->pMSat = Ssw_SatStart( 0 );
+ TimeLimitPart = TimeLimit ? nTimeToStop - time(NULL) : 0;
+ if ( TimeLimit2 )
+ {
+ if ( TimeLimitPart )
+ TimeLimitPart = Abc_MinInt( TimeLimitPart, TimeLimit2 );
+ else
+ TimeLimitPart = TimeLimit2;
+ }
+ Ssw_ManSweepBmcFilter( p, TimeLimitPart );
+ Ssw_SatStop( p->pMSat );
+ p->pMSat = NULL;
+ Ssw_ManCleanup( p );
+ // simulate pattern forward
+ Ssw_ManRollForward( p, p->pPars->nFramesK );
+ // check timeout
+ if ( TimeLimit && time(NULL) > nTimeToStop )
+ {
+ printf( "Reached timeout (%d seconds).\n", TimeLimit );
+ break;
+ }
+ }
+ // cleanup
+ Aig_ManSetPhase( p->pAig );
+ Aig_ManCleanMarkB( p->pAig );
+ // cleanup
+ pPars->fVerbose = 0;
+ Ssw_ManStop( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SignalFilterGia( Gia_Man_t * p, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ Aig_Man_t * pAig;
+ pAig = Gia_ManToAigSimple( p );
+ if ( p->pReprs != NULL )
+ {
+ Gia_ManReprToAigRepr2( pAig, p );
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ }
+ Ssw_SignalFilter( pAig, nFramesMax, nConfMax, nRounds, TimeLimit, TimeLimit2, pCex, fLatchOnly, fVerbose );
+ Gia_ManReprFromAigRepr( pAig, p );
+ Aig_ManStop( pAig );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswInt.h b/src/proof/ssw/sswInt.h
new file mode 100644
index 00000000..acd273fd
--- /dev/null
+++ b/src/proof/ssw/sswInt.h
@@ -0,0 +1,302 @@
+/**CFile****************************************************************
+
+ FileName [sswInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswInt.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__aig__ssw__sswInt_h
+#define ABC__aig__ssw__sswInt_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "src/aig/saig/saig.h"
+#include "src/sat/bsat/satSolver.h"
+#include "ssw.h"
+#include "src/aig/ioa/ioa.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager
+typedef struct Ssw_Frm_t_ Ssw_Frm_t; // unrolled frames manager
+typedef struct Ssw_Sat_t_ Ssw_Sat_t; // SAT solver manager
+typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager
+
+struct Ssw_Man_t_
+{
+ // parameters
+ Ssw_Pars_t * pPars; // parameters
+ int nFrames; // for quick lookup
+ // AIGs used in the package
+ Aig_Man_t * pAig; // user-given AIG
+ Aig_Man_t * pFrames; // final AIG
+ Aig_Obj_t ** pNodeToFrames; // mapping of AIG nodes into FRAIG nodes
+ // equivalence classes
+ Ssw_Cla_t * ppClasses; // equivalence classes of nodes
+ int fRefined; // is set to 1 when refinement happens
+ // SAT solving
+ Ssw_Sat_t * pMSatBmc; // SAT manager for base case
+ Ssw_Sat_t * pMSat; // SAT manager for inductive case
+ // SAT solving (latch corr only)
+ Vec_Ptr_t * vSimInfo; // simulation information for the framed PIs
+ int nPatterns; // the number of patterns saved
+ int nSimRounds; // the number of simulation rounds performed
+ int nCallsCount; // the number of calls in this round
+ int nCallsDelta; // the number of calls to skip
+ int nCallsSat; // the number of SAT calls in this round
+ int nCallsUnsat; // the number of UNSAT calls in this round
+ int nRecycleCalls; // the number of calls since last recycling
+ int nRecycles; // the number of time SAT solver was recycled
+ int nRecyclesTotal; // the number of time SAT solver was recycled
+ int nVarsMax; // the maximum variables in the solver
+ int nCallsMax; // the maximum number of SAT calls
+ // uniqueness
+ Vec_Ptr_t * vCommon; // the set of common variables in the logic cones
+ int iOutputLit; // the output literal of the uniqueness constraint
+ Vec_Int_t * vDiffPairs; // is set to 1 if reg pair can be diff
+ int nUniques; // the number of uniqueness constraints used
+ int nUniquesAdded; // useful uniqueness constraints
+ int nUniquesUseful; // useful uniqueness constraints
+ // dynamic constraint addition
+ int nSRMiterMaxId; // max ID after which the last frame begins
+ Vec_Ptr_t * vNewLos; // new time frame LOs of to constrain
+ Vec_Int_t * vNewPos; // new time frame POs of to add constraints
+ int * pVisited; // flags to label visited nodes in each frame
+ int nVisCounter; // the traversal ID
+ // sequential simulation
+ Ssw_Sml_t * pSml; // the simulator
+ int iNodeStart; // the first node considered
+ int iNodeLast; // the last node considered
+ Vec_Ptr_t * vResimConsts; // resimulation constants
+ Vec_Ptr_t * vResimClasses; // resimulation classes
+ Vec_Int_t * vInits; // the init values of primary inputs under constraints
+ // counter example storage
+ int nPatWords; // the number of words in the counter example
+ unsigned * pPatWords; // the counter example
+ // constraints
+ int nConstrTotal; // the number of total constraints
+ int nConstrReduced; // the number of reduced constraints
+ int nStrangers; // the number of strange situations
+ // SAT calls statistics
+ int nSatCalls; // the number of SAT calls
+ int nSatProof; // the number of proofs
+ int nSatFailsReal; // the number of timeouts
+ int nSatCallsUnsat; // the number of unsat SAT calls
+ int nSatCallsSat; // the number of sat SAT calls
+ // node/register/lit statistics
+ int nLitsBeg;
+ int nLitsEnd;
+ int nNodesBeg;
+ int nNodesEnd;
+ int nRegsBeg;
+ int nRegsEnd;
+ // equiv statistis
+ int nConesTotal;
+ int nConesConstr;
+ int nEquivsTotal;
+ int nEquivsConstr;
+ int nNodesBegC;
+ int nNodesEndC;
+ int nRegsBegC;
+ int nRegsEndC;
+ // runtime stats
+ int timeBmc; // bounded model checking
+ int timeReduce; // speculative reduction
+ int timeMarkCones; // marking the cones not to be refined
+ int timeSimSat; // simulation of the counter-examples
+ int timeSat; // solving SAT
+ int timeSatSat; // sat
+ int timeSatUnsat; // unsat
+ int timeSatUndec; // undecided
+ int timeOther; // other runtime
+ int timeTotal; // total runtime
+};
+
+// internal SAT manager
+struct Ssw_Sat_t_
+{
+ Aig_Man_t * pAig; // the AIG manager
+ int fPolarFlip; // flips polarity
+ sat_solver * pSat; // recyclable SAT solver
+ int nSatVars; // the counter of SAT variables
+ Vec_Int_t * vSatVars; // mapping of each node into its SAT var
+ Vec_Ptr_t * vFanins; // fanins of the CNF node
+ Vec_Ptr_t * vUsedPis; // the PIs with SAT variables
+ int nSolverCalls; // the total number of SAT calls
+};
+
+// internal frames manager
+struct Ssw_Frm_t_
+{
+ Aig_Man_t * pAig; // user-given AIG
+ int nObjs; // offset in terms of AIG nodes
+ int nFrames; // the number of frames in current unrolling
+ Aig_Man_t * pFrames; // unrolled AIG
+ Vec_Ptr_t * vAig2Frm; // mapping of AIG nodes into frame nodes
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Ssw_ObjSatNum( Ssw_Sat_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vSatVars, pObj->Id ); }
+static inline void Ssw_ObjSetSatNum( Ssw_Sat_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vSatVars, pObj->Id, Num); }
+
+static inline int Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
+{
+ return Aig_ObjRepr(pAig, pObj) == Aig_ManConst1(pAig);
+}
+static inline void Ssw_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
+{
+ assert( !Ssw_ObjIsConst1Cand( pAig, pObj ) );
+ Aig_ObjSetRepr( pAig, pObj, Aig_ManConst1(pAig) );
+}
+
+static inline Aig_Obj_t * Ssw_ObjFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { return p->pNodeToFrames[p->nFrames*pObj->Id + i]; }
+static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { p->pNodeToFrames[p->nFrames*pObj->Id + i] = pNode; }
+
+static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
+static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
+
+static inline Aig_Obj_t * Ssw_ObjFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { return (Aig_Obj_t *)Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); }
+static inline void Ssw_ObjSetFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); }
+
+static inline Aig_Obj_t * Ssw_ObjChild0Fra_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame_(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
+static inline Aig_Obj_t * Ssw_ObjChild1Fra_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame_(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== sswAig.c ===================================================*/
+extern Ssw_Frm_t * Ssw_FrmStart( Aig_Man_t * pAig );
+extern void Ssw_FrmStop( Ssw_Frm_t * p );
+extern Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p );
+extern Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p );
+/*=== sswBmc.c ===================================================*/
+/*=== sswClass.c =================================================*/
+extern Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig );
+extern void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
+ unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *),
+ int (*pFuncNodeIsConst)(void *,Aig_Obj_t *),
+ int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) );
+extern void Ssw_ClassesStop( Ssw_Cla_t * p );
+extern Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p );
+extern Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p );
+extern void Ssw_ClassesClearRefined( Ssw_Cla_t * p );
+extern int Ssw_ClassesCand1Num( Ssw_Cla_t * p );
+extern int Ssw_ClassesClassNum( Ssw_Cla_t * p );
+extern int Ssw_ClassesLitNum( Ssw_Cla_t * p );
+extern Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize );
+extern void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass );
+extern void Ssw_ClassesCheck( Ssw_Cla_t * p );
+extern void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose );
+extern void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj );
+extern Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int fConstCorr, int fOutputCorr, int nMaxLevs, int fVerbose );
+extern Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs );
+extern Ssw_Cla_t * Ssw_ClassesPrepareFromReprs( Aig_Man_t * pAig );
+extern Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig );
+extern Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses );
+extern Ssw_Cla_t * Ssw_ClassesPreparePairsSimple( Aig_Man_t * pMiter, Vec_Int_t * vPairs );
+extern int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive );
+extern int Ssw_ClassesRefineGroup( Ssw_Cla_t * p, Vec_Ptr_t * vReprs, int fRecursive );
+extern int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int fRecursive );
+extern int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive );
+extern int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive );
+extern int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands, int fConstCorr );
+/*=== sswCnf.c ===================================================*/
+extern Ssw_Sat_t * Ssw_SatStart( int fPolarFlip );
+extern void Ssw_SatStop( Ssw_Sat_t * p );
+extern void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj );
+extern int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObjFraig );
+/*=== sswConstr.c ===================================================*/
+extern int Ssw_ManSweepBmcConstr( Ssw_Man_t * p );
+extern int Ssw_ManSweepConstr( Ssw_Man_t * p );
+extern void Ssw_ManRefineByConstrSim( Ssw_Man_t * p );
+/*=== sswCore.c ===================================================*/
+extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p );
+/*=== sswDyn.c ===================================================*/
+extern void Ssw_ManLoadSolver( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj );
+extern int Ssw_ManSweepDyn( Ssw_Man_t * p );
+/*=== sswLcorr.c ==========================================================*/
+extern int Ssw_ManSweepLatch( Ssw_Man_t * p );
+/*=== sswMan.c ===================================================*/
+extern Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+extern void Ssw_ManCleanup( Ssw_Man_t * p );
+extern void Ssw_ManStop( Ssw_Man_t * p );
+/*=== sswSat.c ===================================================*/
+extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
+extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
+extern int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj );
+/*=== sswSemi.c ===================================================*/
+extern int Ssw_FilterUsingSemi( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose );
+/*=== sswSim.c ===================================================*/
+extern unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
+extern int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
+extern void Ssw_SmlAssignRandomFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame );
+extern Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame );
+extern void Ssw_SmlClean( Ssw_Sml_t * p );
+extern void Ssw_SmlStop( Ssw_Sml_t * p );
+extern void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame );
+extern void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame );
+extern void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat );
+extern void Ssw_SmlSimulateOne( Ssw_Sml_t * p );
+extern void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p );
+extern void Ssw_SmlSimulateOneDyn_rec( Ssw_Sml_t * p, Aig_Obj_t * pObj, int f, int * pVisited, int nVisCounter );
+extern void Ssw_SmlResimulateSeq( Ssw_Sml_t * p );
+/*=== sswSimSat.c ===================================================*/
+extern void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr );
+extern void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f );
+/*=== sswSweep.c ===================================================*/
+extern int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f );
+extern void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f );
+extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc, Vec_Int_t * vPairs );
+extern int Ssw_ManSweepBmc( Ssw_Man_t * p );
+extern int Ssw_ManSweep( Ssw_Man_t * p );
+/*=== sswUnique.c ===================================================*/
+extern void Ssw_UniqueRegisterPairInfo( Ssw_Man_t * p );
+extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj, int fVerbose );
+extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 );
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/ssw/sswIslands.c b/src/proof/ssw/sswIslands.c
new file mode 100644
index 00000000..0802aca5
--- /dev/null
+++ b/src/proof/ssw/sswIslands.c
@@ -0,0 +1,598 @@
+/**CFile****************************************************************
+
+ FileName [sswIslands.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Detection of islands of difference.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswIslands.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates pair of structurally equivalent nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CreatePair( Vec_Int_t * vPairs, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ pObj0->pData = pObj1;
+ pObj1->pData = pObj0;
+ Vec_IntPush( vPairs, pObj0->Id );
+ Vec_IntPush( vPairs, pObj1->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Establishes relationship between nodes using pairing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_MatchingStart( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs )
+{
+ Aig_Obj_t * pObj0, * pObj1;
+ int i;
+ // create matching
+ Aig_ManCleanData( p0 );
+ Aig_ManCleanData( p1 );
+ for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
+ {
+ pObj0 = Aig_ManObj( p0, Vec_IntEntry(vPairs, i) );
+ pObj1 = Aig_ManObj( p1, Vec_IntEntry(vPairs, i+1) );
+ assert( pObj0->pData == NULL );
+ assert( pObj1->pData == NULL );
+ pObj0->pData = pObj1;
+ pObj1->pData = pObj0;
+ }
+ // make sure constants are matched
+ pObj0 = Aig_ManConst1( p0 );
+ pObj1 = Aig_ManConst1( p1 );
+ assert( pObj0->pData == pObj1 );
+ assert( pObj1->pData == pObj0 );
+ // make sure PIs are matched
+ Saig_ManForEachPi( p0, pObj0, i )
+ {
+ pObj1 = Aig_ManPi( p1, i );
+ assert( pObj0->pData == pObj1 );
+ assert( pObj1->pData == pObj0 );
+ }
+ // make sure the POs are not matched
+ Aig_ManForEachPo( p0, pObj0, i )
+ {
+ pObj1 = Aig_ManPo( p1, i );
+ assert( pObj0->pData == NULL );
+ assert( pObj1->pData == NULL );
+ }
+
+ // check that LIs/LOs are matched in sync
+ Saig_ManForEachLo( p0, pObj0, i )
+ {
+ if ( pObj0->pData == NULL )
+ continue;
+ pObj1 = (Aig_Obj_t *)pObj0->pData;
+ if ( !Saig_ObjIsLo(p1, pObj1) )
+ printf( "Mismatch between LO pairs.\n" );
+ }
+ Saig_ManForEachLo( p1, pObj1, i )
+ {
+ if ( pObj1->pData == NULL )
+ continue;
+ pObj0 = (Aig_Obj_t *)pObj1->pData;
+ if ( !Saig_ObjIsLo(p0, pObj0) )
+ printf( "Mismatch between LO pairs.\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Establishes relationship between nodes using pairing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_MatchingExtendOne( Aig_Man_t * p, Vec_Ptr_t * vNodes )
+{
+ Aig_Obj_t * pNext, * pObj;
+ int i, k, iFan;
+ Vec_PtrClear( vNodes );
+ Aig_ManIncrementTravId( p );
+ Aig_ManForEachObj( p, pObj, i )
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
+ continue;
+ if ( pObj->pData != NULL )
+ continue;
+ if ( Saig_ObjIsLo(p, pObj) )
+ {
+ pNext = Saig_ObjLoToLi(p, pObj);
+ pNext = Aig_ObjFanin0(pNext);
+ if ( pNext->pData && !Aig_ObjIsTravIdCurrent(p, pNext) && !Aig_ObjIsConst1(pNext) )
+ {
+ Aig_ObjSetTravIdCurrent(p, pNext);
+ Vec_PtrPush( vNodes, pNext );
+ }
+ }
+ if ( Aig_ObjIsNode(pObj) )
+ {
+ pNext = Aig_ObjFanin0(pObj);
+ if ( pNext->pData && !Aig_ObjIsTravIdCurrent(p, pNext) )
+ {
+ Aig_ObjSetTravIdCurrent(p, pNext);
+ Vec_PtrPush( vNodes, pNext );
+ }
+ pNext = Aig_ObjFanin1(pObj);
+ if ( pNext->pData && !Aig_ObjIsTravIdCurrent(p, pNext) )
+ {
+ Aig_ObjSetTravIdCurrent(p, pNext);
+ Vec_PtrPush( vNodes, pNext );
+ }
+ }
+ Aig_ObjForEachFanout( p, pObj, pNext, iFan, k )
+ {
+ if ( Saig_ObjIsPo(p, pNext) )
+ continue;
+ if ( Saig_ObjIsLi(p, pNext) )
+ pNext = Saig_ObjLiToLo(p, pNext);
+ if ( pNext->pData && !Aig_ObjIsTravIdCurrent(p, pNext) )
+ {
+ Aig_ObjSetTravIdCurrent(p, pNext);
+ Vec_PtrPush( vNodes, pNext );
+ }
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Establishes relationship between nodes using pairing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_MatchingCountUnmached( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i, Counter = 0;
+ Aig_ManForEachObj( p, pObj, i )
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
+ continue;
+ if ( pObj->pData != NULL )
+ continue;
+ Counter++;
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Establishes relationship between nodes using pairing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_MatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose )
+{
+ Vec_Ptr_t * vNodes0, * vNodes1;
+ Aig_Obj_t * pNext0, * pNext1;
+ int d, k;
+ Aig_ManFanoutStart(p0);
+ Aig_ManFanoutStart(p1);
+ vNodes0 = Vec_PtrAlloc( 1000 );
+ vNodes1 = Vec_PtrAlloc( 1000 );
+ if ( fVerbose )
+ {
+ int nUnmached = Ssw_MatchingCountUnmached(p0);
+ printf( "Extending islands by %d steps:\n", nDist );
+ printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n",
+ 0, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0),
+ nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) );
+ }
+ for ( d = 0; d < nDist; d++ )
+ {
+ Ssw_MatchingExtendOne( p0, vNodes0 );
+ Ssw_MatchingExtendOne( p1, vNodes1 );
+ Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pNext0, k )
+ {
+ pNext1 = (Aig_Obj_t *)pNext0->pData;
+ if ( pNext1 == NULL )
+ continue;
+ assert( pNext1->pData == pNext0 );
+ if ( Saig_ObjIsPi(p0, pNext1) )
+ continue;
+ pNext0->pData = NULL;
+ pNext1->pData = NULL;
+ }
+ Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pNext0, k )
+ {
+ pNext1 = (Aig_Obj_t *)pNext0->pData;
+ if ( pNext1 == NULL )
+ continue;
+ assert( pNext1->pData == pNext0 );
+ if ( Saig_ObjIsPi(p1, pNext1) )
+ continue;
+ pNext0->pData = NULL;
+ pNext1->pData = NULL;
+ }
+ if ( fVerbose )
+ {
+ int nUnmached = Ssw_MatchingCountUnmached(p0);
+ printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n",
+ d+1, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0),
+ nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) );
+ }
+ }
+ Vec_PtrFree( vNodes0 );
+ Vec_PtrFree( vNodes1 );
+ Aig_ManFanoutStop(p0);
+ Aig_ManFanoutStop(p1);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Used differences in p0 to complete p1.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_MatchingComplete( Aig_Man_t * p0, Aig_Man_t * p1 )
+{
+ Vec_Ptr_t * vNewLis;
+ Aig_Obj_t * pObj0, * pObj0Li, * pObj1;
+ int i;
+ // create register outputs in p0 that are absent in p1
+ vNewLis = Vec_PtrAlloc( 100 );
+ Saig_ManForEachLiLo( p0, pObj0Li, pObj0, i )
+ {
+ if ( pObj0->pData != NULL )
+ continue;
+ pObj1 = Aig_ObjCreatePi( p1 );
+ pObj0->pData = pObj1;
+ pObj1->pData = pObj0;
+ Vec_PtrPush( vNewLis, pObj0Li );
+ }
+ // add missing nodes in the topological order
+ Aig_ManForEachNode( p0, pObj0, i )
+ {
+ if ( pObj0->pData != NULL )
+ continue;
+ pObj1 = Aig_And( p1, Aig_ObjChild0Copy(pObj0), Aig_ObjChild1Copy(pObj0) );
+ pObj0->pData = pObj1;
+ pObj1->pData = pObj0;
+ }
+ // create register outputs in p0 that are absent in p1
+ Vec_PtrForEachEntry( Aig_Obj_t *, vNewLis, pObj0Li, i )
+ Aig_ObjCreatePo( p1, Aig_ObjChild0Copy(pObj0Li) );
+ // increment the number of registers
+ Aig_ManSetRegNum( p1, Aig_ManRegNum(p1) + Vec_PtrSize(vNewLis) );
+ Vec_PtrFree( vNewLis );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives matching for all pairs.]
+
+ Description [Modifies both AIGs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ssw_MatchingPairs( Aig_Man_t * p0, Aig_Man_t * p1 )
+{
+ Vec_Int_t * vPairsNew;
+ Aig_Obj_t * pObj0, * pObj1;
+ int i;
+ // check correctness
+ assert( Aig_ManPiNum(p0) == Aig_ManPiNum(p1) );
+ assert( Aig_ManPoNum(p0) == Aig_ManPoNum(p1) );
+ assert( Aig_ManRegNum(p0) == Aig_ManRegNum(p1) );
+ assert( Aig_ManObjNum(p0) == Aig_ManObjNum(p1) );
+ // create complete pairs
+ vPairsNew = Vec_IntAlloc( 2*Aig_ManObjNum(p0) );
+ Aig_ManForEachObj( p0, pObj0, i )
+ {
+ if ( Aig_ObjIsPo(pObj0) )
+ continue;
+ pObj1 = (Aig_Obj_t *)pObj0->pData;
+ Vec_IntPush( vPairsNew, pObj0->Id );
+ Vec_IntPush( vPairsNew, pObj1->Id );
+ }
+ return vPairsNew;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the result of matching to miter.]
+
+ Description [The array of pairs should be complete.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ssw_MatchingMiter( Aig_Man_t * pMiter, Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairsAll )
+{
+ Vec_Int_t * vPairsMiter;
+ Aig_Obj_t * pObj0, * pObj1;
+ int i;
+ // create matching of nodes in the miter
+ vPairsMiter = Vec_IntAlloc( 2*Aig_ManObjNum(p0) );
+ for ( i = 0; i < Vec_IntSize(vPairsAll); i += 2 )
+ {
+ pObj0 = Aig_ManObj( p0, Vec_IntEntry(vPairsAll, i) );
+ pObj1 = Aig_ManObj( p1, Vec_IntEntry(vPairsAll, i+1) );
+ assert( pObj0->pData != NULL );
+ assert( pObj1->pData != NULL );
+ if ( pObj0->pData == pObj1->pData )
+ continue;
+ if ( Aig_ObjIsNone((Aig_Obj_t *)pObj0->pData) || Aig_ObjIsNone((Aig_Obj_t *)pObj1->pData) )
+ continue;
+ // get the miter nodes
+ pObj0 = (Aig_Obj_t *)pObj0->pData;
+ pObj1 = (Aig_Obj_t *)pObj1->pData;
+ assert( !Aig_IsComplement(pObj0) );
+ assert( !Aig_IsComplement(pObj1) );
+ assert( Aig_ObjType(pObj0) == Aig_ObjType(pObj1) );
+ if ( Aig_ObjIsPo(pObj0) )
+ continue;
+ assert( Aig_ObjIsNode(pObj0) || Saig_ObjIsLo(pMiter, pObj0) );
+ assert( Aig_ObjIsNode(pObj1) || Saig_ObjIsLo(pMiter, pObj1) );
+ assert( pObj0->Id < pObj1->Id );
+ Vec_IntPush( vPairsMiter, pObj0->Id );
+ Vec_IntPush( vPairsMiter, pObj1->Id );
+ }
+ return vPairsMiter;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Solves SEC using structural similarity.]
+
+ Description [Modifies both p0 and p1 by adding extra logic.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SecWithSimilaritySweep( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs, Ssw_Pars_t * pPars )
+{
+ Ssw_Man_t * p;
+ Vec_Int_t * vPairsAll, * vPairsMiter;
+ Aig_Man_t * pMiter, * pAigNew;
+ // derive full matching
+ Ssw_MatchingStart( p0, p1, vPairs );
+ if ( pPars->nIsleDist )
+ Ssw_MatchingExtend( p0, p1, pPars->nIsleDist, pPars->fVerbose );
+ Ssw_MatchingComplete( p0, p1 );
+ Ssw_MatchingComplete( p1, p0 );
+ vPairsAll = Ssw_MatchingPairs( p0, p1 );
+ // create miter and transfer matching
+ pMiter = Saig_ManCreateMiter( p0, p1, 0 );
+ vPairsMiter = Ssw_MatchingMiter( pMiter, p0, p1, vPairsAll );
+ Vec_IntFree( vPairsAll );
+ // start the induction manager
+ p = Ssw_ManCreate( pMiter, pPars );
+ // create equivalence classes using these IDs
+ if ( p->pPars->fPartSigCorr )
+ p->ppClasses = Ssw_ClassesPreparePairsSimple( pMiter, vPairsMiter );
+ else
+ p->ppClasses = Ssw_ClassesPrepare( pMiter, pPars->nFramesK, pPars->fLatchCorr, pPars->fConstCorr, pPars->fOutputCorr, pPars->nMaxLevs, pPars->fVerbose );
+ if ( p->pPars->fDumpSRInit )
+ {
+ if ( p->pPars->fPartSigCorr )
+ {
+ Aig_Man_t * pSRed = Ssw_SpeculativeReduction( p );
+ Aig_ManDumpBlif( pSRed, "srm_part.blif", NULL, NULL );
+ Aig_ManStop( pSRed );
+ printf( "Speculatively reduced miter is saved in file \"%s\".\n", "srm_part.blif" );
+ }
+ else
+ printf( "Dumping speculative miter is possible only for partial signal correspondence (switch \"-c\").\n" );
+ }
+ p->pSml = Ssw_SmlStart( pMiter, 0, 1 + p->pPars->nFramesAddSim, 1 );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
+ // perform refinement of classes
+ pAigNew = Ssw_SignalCorrespondenceRefine( p );
+ // cleanup
+ Ssw_ManStop( p );
+ Aig_ManStop( pMiter );
+ Vec_IntFree( vPairsMiter );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solves SEC with structural similarity.]
+
+ Description [The first two arguments are pointers to the AIG managers.
+ The third argument is the array of pairs of IDs of structurally equivalent
+ nodes from the first and second managers, respectively.]
+
+ SideEffects [The managers will be updated by adding "islands of difference".]
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecWithSimilarityPairs( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs, Ssw_Pars_t * pPars )
+{
+ Ssw_Pars_t Pars;
+ Aig_Man_t * pAigRes;
+ int RetValue, clk = clock();
+ // derive parameters if not given
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ // reduce the AIG with pairs
+ pAigRes = Ssw_SecWithSimilaritySweep( p0, p1, vPairs, pPars );
+ // report the result of verification
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(p0)+Aig_ManRegNum(p1) );
+ ABC_PRT( "Time", clock() - clk );
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dummy procedure to detect structural similarity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_StrSimPerformMatching_hack( Aig_Man_t * p0, Aig_Man_t * p1 )
+{
+ Vec_Int_t * vPairs;
+ Aig_Obj_t * pObj;
+ int i;
+ // create array of pairs
+ vPairs = Vec_IntAlloc( 100 );
+ Aig_ManForEachObj( p0, pObj, i )
+ {
+ if ( !Aig_ObjIsConst1(pObj) && !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) )
+ continue;
+ Vec_IntPush( vPairs, i );
+ Vec_IntPush( vPairs, i );
+ }
+ return vPairs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solves SEC with structural similarity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecWithSimilarity( Aig_Man_t * p0, Aig_Man_t * p1, Ssw_Pars_t * pPars )
+{
+ Vec_Int_t * vPairs;
+ Aig_Man_t * pPart0, * pPart1;
+ int RetValue;
+ if ( pPars->fVerbose )
+ printf( "Performing sequential verification using structural similarity.\n" );
+ // consider the case when a miter is given
+ if ( p1 == NULL )
+ {
+ if ( pPars->fVerbose )
+ {
+ Aig_ManPrintStats( p0 );
+ }
+ // demiter the miter
+ if ( !Saig_ManDemiterSimpleDiff( p0, &pPart0, &pPart1 ) )
+ {
+ printf( "Demitering has failed.\n" );
+ return -1;
+ }
+ }
+ else
+ {
+ pPart0 = Aig_ManDupSimple( p0 );
+ pPart1 = Aig_ManDupSimple( p1 );
+ }
+ if ( pPars->fVerbose )
+ {
+// Aig_ManPrintStats( pPart0 );
+// Aig_ManPrintStats( pPart1 );
+ if ( p1 == NULL )
+ {
+// Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL );
+// Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL );
+// printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" );
+ }
+ }
+ assert( Aig_ManRegNum(pPart0) > 0 );
+ assert( Aig_ManRegNum(pPart1) > 0 );
+ assert( Saig_ManPiNum(pPart0) == Saig_ManPiNum(pPart1) );
+ assert( Saig_ManPoNum(pPart0) == Saig_ManPoNum(pPart1) );
+ // derive pairs
+// vPairs = Saig_StrSimPerformMatching_hack( pPart0, pPart1 );
+ vPairs = Saig_StrSimPerformMatching( pPart0, pPart1, 0, pPars->fVerbose, NULL );
+ RetValue = Ssw_SecWithSimilarityPairs( pPart0, pPart1, vPairs, pPars );
+ Aig_ManStop( pPart0 );
+ Aig_ManStop( pPart1 );
+ Vec_IntFree( vPairs );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswLcorr.c b/src/proof/ssw/sswLcorr.c
new file mode 100644
index 00000000..ce9c2563
--- /dev/null
+++ b/src/proof/ssw/sswLcorr.c
@@ -0,0 +1,336 @@
+/**CFile****************************************************************
+
+ FileName [sswLcorr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Latch correspondence.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+//#include "bar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Tranfers simulation information from FRAIG to AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepTransfer( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjFraig;
+ unsigned * pInfo;
+ int i;
+ // transfer simulation information
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjFraig = Ssw_ObjFrame( p, pObj, 0 );
+ if ( pObjFraig == Aig_ManConst0(p->pFrames) )
+ {
+ Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 );
+ continue;
+ }
+ assert( !Aig_IsComplement(pObjFraig) );
+ assert( Aig_ObjIsPi(pObjFraig) );
+ pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) );
+ Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of simulation with counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepResimulate( Ssw_Man_t * p )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // transfer PI simulation information from storage
+ Ssw_ManSweepTransfer( p );
+ // simulate internal nodes
+ Ssw_SmlSimulateOneFrame( p->pSml );
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // prepare simulation info for the next round
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+ p->nPatterns = 0;
+ p->nSimRounds++;
+p->timeSimSat += clock() - clk;
+ return RetValue1 > 0 || RetValue2 > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves one counter-example into internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pInfo;
+ int i, nVarNum, Value;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i )
+ {
+ nVarNum = Ssw_ObjSatNum( p->pMSat, pObj );
+ assert( nVarNum > 0 );
+ Value = sat_solver_var_value( p->pMSat->pSat, nVarNum );
+ if ( Value == 0 )
+ continue;
+ pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
+ Abc_InfoSetBit( pInfo, p->nPatterns );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds fraiged logic cone of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObjNew;
+ assert( !Aig_IsComplement(pObj) );
+ if ( Ssw_ObjFrame( p, pObj, 0 ) )
+ return;
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi;
+ int RetValue, clk;
+ assert( Aig_ObjIsPi(pObj) );
+ assert( Aig_ObjIsPi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) );
+ // check if it makes sense to skip some calls
+ if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat )
+ {
+ if ( ++p->nCallsDelta < 0 )
+ return;
+ }
+ p->nCallsDelta = 0;
+clk = clock();
+ // get the fraiged node
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
+ pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
+ // get the fraiged representative
+ if ( Aig_ObjIsPi(pObjRepr) )
+ {
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
+ pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
+ }
+ else
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 );
+p->timeReduce += clock() - clk;
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return;
+ p->nRecycleCalls++;
+ p->nCallsCount++;
+
+ // check equivalence of the two nodes
+ if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
+ {
+ p->nPatterns++;
+ p->nStrangers++;
+ p->fRefined = 1;
+ }
+ else
+ {
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ if ( RetValue == 1 ) // proved equivalence
+ {
+ p->nCallsUnsat++;
+ return;
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+ Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ p->nCallsUnsat++;
+ p->fRefined = 1;
+ return;
+ }
+ else // disproved equivalence
+ {
+ Ssw_SmlAddPattern( p, pObjRepr, pObj );
+ p->nPatterns++;
+ p->nCallsSat++;
+ p->fRefined = 1;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one iteration of sweeping latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepLatch( Ssw_Man_t * p )
+{
+// Bar_Progress_t * pProgress = NULL;
+ Vec_Ptr_t * vClass;
+ Aig_Obj_t * pObj, * pRepr, * pTemp;
+ int i, k;
+
+ // start the timeframe
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(p->pFrames) );
+
+ // implement equivalence classes
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ pRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pRepr == NULL )
+ {
+ pTemp = Aig_ObjCreatePi(p->pFrames);
+ pTemp->pData = pObj;
+ }
+ else
+ pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase );
+ Ssw_ObjSetFrame( p, pObj, 0, pTemp );
+ }
+ Aig_ManSetPioNumbers( p->pFrames );
+
+ // prepare simulation info
+ assert( p->vSimInfo == NULL );
+ p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManPiNum(p->pFrames), 1 );
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+
+ // go through the registers
+// if ( p->pPars->fVerbose )
+// pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) );
+ vClass = Vec_PtrAlloc( 100 );
+ p->fRefined = 0;
+ p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+// if ( p->pPars->fVerbose )
+// Bar_ProgressUpdate( pProgress, i, NULL );
+ // consider the case of constant candidate
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj );
+ else
+ {
+ // consider the case of equivalence class
+ Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass );
+ if ( Vec_PtrSize(vClass) == 0 )
+ continue;
+ // try to prove equivalences in this class
+ Vec_PtrForEachEntry( Aig_Obj_t *, vClass, pTemp, k )
+ if ( Aig_ObjRepr(p->pAig, pTemp) == pObj )
+ {
+ Ssw_ManSweepLatchOne( p, pObj, pTemp );
+ if ( p->nPatterns == 32 )
+ break;
+ }
+ }
+ // resimulate
+ if ( p->nPatterns == 32 )
+ Ssw_ManSweepResimulate( p );
+ // attempt recycling the SAT solver
+ if ( p->pPars->nSatVarMax &&
+ p->pMSat->nSatVars > p->pPars->nSatVarMax &&
+ p->nRecycleCalls > p->pPars->nRecycleCalls )
+ {
+ p->nVarsMax = Abc_MaxInt( p->nVarsMax, p->pMSat->nSatVars );
+ p->nCallsMax = Abc_MaxInt( p->nCallsMax, p->pMSat->nSolverCalls );
+ Ssw_SatStop( p->pMSat );
+ p->pMSat = Ssw_SatStart( 0 );
+ p->nRecycles++;
+ p->nRecycleCalls = 0;
+ }
+ }
+// ABC_PRT( "reduce", p->timeReduce );
+// Aig_TableProfile( p->pFrames );
+// printf( "And gates = %d\n", Aig_ManNodeNum(p->pFrames) );
+ // resimulate
+ if ( p->nPatterns > 0 )
+ Ssw_ManSweepResimulate( p );
+ // cleanup
+ Vec_PtrFree( vClass );
+// if ( p->pPars->fVerbose )
+// Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswMan.c b/src/proof/ssw/sswMan.c
new file mode 100644
index 00000000..c635569d
--- /dev/null
+++ b/src/proof/ssw/sswMan.c
@@ -0,0 +1,218 @@
+/**CFile****************************************************************
+
+ FileName [sswMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswMan.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Ssw_Man_t * p;
+ // prepare the sequential AIG
+ assert( Saig_ManRegNum(pAig) > 0 );
+ Aig_ManFanoutStart( pAig );
+ Aig_ManSetPioNumbers( pAig );
+ // create interpolation manager
+ p = ABC_ALLOC( Ssw_Man_t, 1 );
+ memset( p, 0, sizeof(Ssw_Man_t) );
+ p->pPars = pPars;
+ p->pAig = pAig;
+ p->nFrames = pPars->nFramesK + 1;
+ p->pNodeToFrames = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ p->vCommon = Vec_PtrAlloc( 100 );
+ p->iOutputLit = -1;
+ // allocate storage for sim pattern
+ p->nPatWords = Abc_BitWordNum( Saig_ManPiNum(pAig) * p->nFrames + Saig_ManRegNum(pAig) );
+ p->pPatWords = ABC_CALLOC( unsigned, p->nPatWords );
+ // other
+ p->vNewLos = Vec_PtrAlloc( 100 );
+ p->vNewPos = Vec_IntAlloc( 100 );
+ p->vResimConsts = Vec_PtrAlloc( 100 );
+ p->vResimClasses = Vec_PtrAlloc( 100 );
+// p->pPars->fVerbose = 1;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManCountEquivs( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i, nEquivs = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ nEquivs += ( Aig_ObjRepr(p->pAig, pObj) != NULL );
+ return nEquivs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManPrintStats( Ssw_Man_t * p )
+{
+ double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20);
+
+ printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n",
+ p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, Saig_ManConstrNum(p->pAig), p->pPars->nMaxLevs, nMemory );
+ printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n",
+ Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),
+ 0/(p->pPars->nIters+1) );
+ printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Lits proved = %d.\n",
+ p->nSatProof, p->nSatCallsSat, p->nSatFailsReal, Ssw_ManCountEquivs(p) );
+ printf( "SAT solver: Vars max = %d. Calls max = %d. Recycles = %d. Sim rounds = %d.\n",
+ p->nVarsMax, p->nCallsMax, p->nRecyclesTotal, p->nSimRounds );
+ printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1),
+ p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) );
+
+ p->timeOther = p->timeTotal-p->timeBmc-p->timeReduce-p->timeMarkCones-p->timeSimSat-p->timeSat;
+ ABC_PRTP( "BMC ", p->timeBmc, p->timeTotal );
+ ABC_PRTP( "Spec reduce", p->timeReduce, p->timeTotal );
+ ABC_PRTP( "Mark cones ", p->timeMarkCones, p->timeTotal );
+ ABC_PRTP( "Sim SAT ", p->timeSimSat, p->timeTotal );
+ ABC_PRTP( "SAT solving", p->timeSat, p->timeTotal );
+ ABC_PRTP( " unsat ", p->timeSatUnsat, p->timeTotal );
+ ABC_PRTP( " sat ", p->timeSatSat, p->timeTotal );
+ ABC_PRTP( " undecided", p->timeSatUndec, p->timeTotal );
+ ABC_PRTP( "Other ", p->timeOther, p->timeTotal );
+ ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
+
+ // report the reductions
+ if ( p->pAig->nConstrs )
+ {
+ printf( "Statistics reflecting the use of constraints:\n" );
+ printf( "Total cones = %6d. Constraint cones = %6d. (%6.2f %%)\n",
+ p->nConesTotal, p->nConesConstr, 100.0*p->nConesConstr/p->nConesTotal );
+ printf( "Total equivs = %6d. Removed equivs = %6d. (%6.2f %%)\n",
+ p->nEquivsTotal, p->nEquivsConstr, 100.0*p->nEquivsConstr/p->nEquivsTotal );
+ printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ p->nNodesBegC, p->nNodesEndC, 100.0*(p->nNodesBegC-p->nNodesEndC)/(p->nNodesBegC?p->nNodesBegC:1),
+ p->nRegsBegC, p->nRegsEndC, 100.0*(p->nRegsBegC-p->nRegsEndC)/(p->nRegsBegC?p->nRegsBegC:1) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManCleanup( Ssw_Man_t * p )
+{
+// Aig_ManCleanMarkAB( p->pAig );
+ assert( p->pMSat == NULL );
+ if ( p->pFrames )
+ {
+ Aig_ManCleanMarkAB( p->pFrames );
+ Aig_ManStop( p->pFrames );
+ p->pFrames = NULL;
+ memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ }
+ if ( p->vSimInfo )
+ {
+ Vec_PtrFree( p->vSimInfo );
+ p->vSimInfo = NULL;
+ }
+ p->nConstrTotal = 0;
+ p->nConstrReduced = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManStop( Ssw_Man_t * p )
+{
+ ABC_FREE( p->pVisited );
+ if ( p->pPars->fVerbose )//&& p->pPars->nStepsMax == -1 )
+ Ssw_ManPrintStats( p );
+ if ( p->ppClasses )
+ Ssw_ClassesStop( p->ppClasses );
+ if ( p->pSml )
+ Ssw_SmlStop( p->pSml );
+ if ( p->vDiffPairs )
+ Vec_IntFree( p->vDiffPairs );
+ if ( p->vInits )
+ Vec_IntFree( p->vInits );
+ Vec_PtrFree( p->vResimConsts );
+ Vec_PtrFree( p->vResimClasses );
+ Vec_PtrFree( p->vNewLos );
+ Vec_IntFree( p->vNewPos );
+ Vec_PtrFree( p->vCommon );
+ ABC_FREE( p->pNodeToFrames );
+ ABC_FREE( p->pPatWords );
+ ABC_FREE( p );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswPairs.c b/src/proof/ssw/sswPairs.c
new file mode 100644
index 00000000..0aba942f
--- /dev/null
+++ b/src/proof/ssw/sswPairs.c
@@ -0,0 +1,477 @@
+/**CFile****************************************************************
+
+ FileName [sswPairs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswPairs.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reports the status of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_MiterStatus( Aig_Man_t * p, int fVerbose )
+{
+ Aig_Obj_t * pObj, * pChild;
+ int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
+// if ( p->pData )
+// return 0;
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ pChild = Aig_ObjChild0(pObj);
+ // check if the output is constant 0
+ if ( pChild == Aig_ManConst0(p) )
+ {
+ CountConst0++;
+ continue;
+ }
+ // check if the output is constant 1
+ if ( pChild == Aig_ManConst1(p) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ // check if the output is a primary input
+ if ( p->nRegs == 0 && Aig_ObjIsPi(Aig_Regular(pChild)) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ // check if the output can be not constant 0
+ if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ CountUndecided++;
+ }
+
+ if ( fVerbose )
+ {
+ printf( "Miter has %d outputs. ", Saig_ManPoNum(p) );
+ printf( "Const0 = %d. ", CountConst0 );
+ printf( "NonConst0 = %d. ", CountNonConst0 );
+ printf( "Undecided = %d. ", CountUndecided );
+ printf( "\n" );
+ }
+
+ if ( CountNonConst0 )
+ return 0;
+ if ( CountUndecided )
+ return -1;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfer equivalent pairs to the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ssw_TransferSignalPairs( Aig_Man_t * pMiter, Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2 )
+{
+ Vec_Int_t * vIds;
+ Aig_Obj_t * pObj1, * pObj2;
+ Aig_Obj_t * pObj1m, * pObj2m;
+ int i;
+ vIds = Vec_IntAlloc( 2 * Vec_IntSize(vIds1) );
+ for ( i = 0; i < Vec_IntSize(vIds1); i++ )
+ {
+ pObj1 = Aig_ManObj( pAig1, Vec_IntEntry(vIds1, i) );
+ pObj2 = Aig_ManObj( pAig2, Vec_IntEntry(vIds2, i) );
+ pObj1m = Aig_Regular((Aig_Obj_t *)pObj1->pData);
+ pObj2m = Aig_Regular((Aig_Obj_t *)pObj2->pData);
+ assert( pObj1m && pObj2m );
+ if ( pObj1m == pObj2m )
+ continue;
+ if ( pObj1m->Id < pObj2m->Id )
+ {
+ Vec_IntPush( vIds, pObj1m->Id );
+ Vec_IntPush( vIds, pObj2m->Id );
+ }
+ else
+ {
+ Vec_IntPush( vIds, pObj2m->Id );
+ Vec_IntPush( vIds, pObj1m->Id );
+ }
+ }
+ return vIds;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform pairs into class representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t ** Ssw_TransformPairsIntoTempClasses( Vec_Int_t * vPairs, int nObjNumMax )
+{
+ Vec_Int_t ** pvClasses; // vector of classes
+ int * pReprs; // mapping nodes into their representatives
+ int Entry, idObj, idRepr, idReprObj, idReprRepr, i;
+ // allocate data-structures
+ pvClasses = ABC_CALLOC( Vec_Int_t *, nObjNumMax );
+ pReprs = ABC_ALLOC( int, nObjNumMax );
+ for ( i = 0; i < nObjNumMax; i++ )
+ pReprs[i] = -1;
+ // consider pairs
+ for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
+ {
+ // get both objects
+ idRepr = Vec_IntEntry( vPairs, i );
+ idObj = Vec_IntEntry( vPairs, i+1 );
+ assert( idObj > 0 );
+ assert( (pReprs[idRepr] == -1) || (pvClasses[pReprs[idRepr]] != NULL) );
+ assert( (pReprs[idObj] == -1) || (pvClasses[pReprs[idObj] ] != NULL) );
+ // get representatives of both objects
+ idReprRepr = pReprs[idRepr];
+ idReprObj = pReprs[idObj];
+ // check different situations
+ if ( idReprRepr == -1 && idReprObj == -1 )
+ { // they do not have classes
+ // create a class
+ pvClasses[idRepr] = Vec_IntAlloc( 4 );
+ Vec_IntPush( pvClasses[idRepr], idRepr );
+ Vec_IntPush( pvClasses[idRepr], idObj );
+ pReprs[ idRepr ] = idRepr;
+ pReprs[ idObj ] = idRepr;
+ }
+ else if ( idReprRepr >= 0 && idReprObj == -1 )
+ { // representative has a class
+ // add iObj to the same class
+ Vec_IntPushUniqueOrder( pvClasses[idReprRepr], idObj );
+ pReprs[ idObj ] = idReprRepr;
+ }
+ else if ( idReprRepr == -1 && idReprObj >= 0 )
+ { // object has a class
+ assert( idReprObj != idRepr );
+ if ( idReprObj < idRepr )
+ { // add idRepr to the same class
+ Vec_IntPushUniqueOrder( pvClasses[idReprObj], idRepr );
+ pReprs[ idRepr ] = idReprObj;
+ }
+ else // if ( idReprObj > idRepr )
+ { // make idRepr new representative
+ Vec_IntPushFirst( pvClasses[idReprObj], idRepr );
+ pvClasses[idRepr] = pvClasses[idReprObj];
+ pvClasses[idReprObj] = NULL;
+ // set correct representatives of each node
+ Vec_IntForEachEntry( pvClasses[idRepr], Entry, i )
+ pReprs[ Entry ] = idRepr;
+ }
+ }
+ else // if ( idReprRepr >= 0 && idReprObj >= 0 )
+ { // both have classes
+ if ( idReprRepr == idReprObj )
+ { // the classes are the same
+ // nothing to do
+ }
+ else
+ { // the classes are different
+ // find the repr of the new class
+ if ( idReprRepr < idReprObj )
+ {
+ Vec_IntForEachEntry( pvClasses[idReprObj], Entry, i )
+ {
+ Vec_IntPushUniqueOrder( pvClasses[idReprRepr], Entry );
+ pReprs[ Entry ] = idReprRepr;
+ }
+ Vec_IntFree( pvClasses[idReprObj] );
+ pvClasses[idReprObj] = NULL;
+ }
+ else // if ( idReprRepr > idReprObj )
+ {
+ Vec_IntForEachEntry( pvClasses[idReprRepr], Entry, i )
+ {
+ Vec_IntPushUniqueOrder( pvClasses[idReprObj], Entry );
+ pReprs[ Entry ] = idReprObj;
+ }
+ Vec_IntFree( pvClasses[idReprRepr] );
+ pvClasses[idReprRepr] = NULL;
+ }
+ }
+ }
+ }
+ ABC_FREE( pReprs );
+ return pvClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_FreeTempClasses( Vec_Int_t ** pvClasses, int nObjNumMax )
+{
+ int i;
+ for ( i = 0; i < nObjNumMax; i++ )
+ if ( pvClasses[i] )
+ Vec_IntFree( pvClasses[i] );
+ ABC_FREE( pvClasses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs signal correspondence for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondenceWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
+{
+ Ssw_Man_t * p;
+ Aig_Man_t * pAigNew, * pMiter;
+ Ssw_Pars_t Pars;
+ Vec_Int_t * vPairs;
+ Vec_Int_t ** pvClasses;
+ assert( Vec_IntSize(vIds1) == Vec_IntSize(vIds2) );
+ // create sequential miter
+ pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
+ Aig_ManCleanup( pMiter );
+ // transfer information to the miter
+ vPairs = Ssw_TransferSignalPairs( pMiter, pAig1, pAig2, vIds1, vIds2 );
+ // create representation of the classes
+ pvClasses = Ssw_TransformPairsIntoTempClasses( vPairs, Aig_ManObjNumMax(pMiter) );
+ Vec_IntFree( vPairs );
+ // if parameters are not given, create them
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ // start the induction manager
+ p = Ssw_ManCreate( pMiter, pPars );
+ // create equivalence classes using these IDs
+ p->ppClasses = Ssw_ClassesPreparePairs( pMiter, pvClasses );
+ p->pSml = Ssw_SmlStart( pMiter, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
+ // perform refinement of classes
+ pAigNew = Ssw_SignalCorrespondenceRefine( p );
+ // cleanup
+ Ssw_FreeTempClasses( pvClasses, Aig_ManObjNumMax(pMiter) );
+ Ssw_ManStop( p );
+ Aig_ManStop( pMiter );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig )
+{
+ Aig_Man_t * pAigNew, * pAigRes;
+ Ssw_Pars_t Pars, * pPars = &Pars;
+ Vec_Int_t * vIds1, * vIds2;
+ Aig_Obj_t * pObj, * pRepr;
+ int RetValue, i, clk = clock();
+ Ssw_ManSetDefaultParams( pPars );
+ pPars->fVerbose = 1;
+ pAigNew = Ssw_SignalCorrespondence( pAig, pPars );
+ // record pairs of equivalent nodes
+ vIds1 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
+ vIds2 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ pRepr = Aig_Regular((Aig_Obj_t *)pObj->pData);
+ if ( pRepr == NULL )
+ continue;
+ if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL )
+ continue;
+/*
+ if ( Aig_ObjIsNode(pObj) )
+ printf( "n " );
+ else if ( Saig_ObjIsPi(pAig, pObj) )
+ printf( "pi " );
+ else if ( Saig_ObjIsLo(pAig, pObj) )
+ printf( "lo " );
+*/
+ Vec_IntPush( vIds1, Aig_ObjId(pObj) );
+ Vec_IntPush( vIds2, Aig_ObjId(pRepr) );
+ }
+ printf( "Recorded %d pairs (before: %d after: %d).\n", Vec_IntSize(vIds1), Aig_ManObjNumMax(pAig), Aig_ManObjNumMax(pAigNew) );
+ // try the new AIGs
+ pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig, pAigNew, vIds1, vIds2, pPars );
+ Vec_IntFree( vIds1 );
+ Vec_IntFree( vIds2 );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with the counter-example. " );
+ else
+ printf( "Verification UNDECIDED. Remaining registers %d (total %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig) + Aig_ManRegNum(pAigNew) );
+ ABC_PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigNew );
+ return pAigRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes;
+ int RetValue, clk = clock();
+ assert( vIds1 != NULL && vIds2 != NULL );
+ // try the new AIGs
+ printf( "Performing specialized verification with node pairs.\n" );
+ pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig1, pAig2, vIds1, vIds2, pPars );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
+ ABC_PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes, * pMiter;
+ int RetValue, clk = clock();
+ // try the new AIGs
+ printf( "Performing general verification without node pairs.\n" );
+ pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
+ Aig_ManCleanup( pMiter );
+ pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
+ Aig_ManStop( pMiter );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
+ ABC_PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes;
+ int RetValue, clk = clock();
+ // try the new AIGs
+// printf( "Performing general verification without node pairs.\n" );
+ pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pMiter) );
+ ABC_PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswPart.c b/src/proof/ssw/sswPart.c
new file mode 100644
index 00000000..d2f07dc8
--- /dev/null
+++ b/src/proof/ssw/sswPart.c
@@ -0,0 +1,141 @@
+/**CFile****************************************************************
+
+ FileName [sswPart.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Partitioned signal correspondence.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswPart.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/aig/ioa/ioa.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs partitioned sequential SAT sweeping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ int fPrintParts = 0;
+ char Buffer[100];
+ Aig_Man_t * pTemp, * pNew;
+ Vec_Ptr_t * vResult;
+ Vec_Int_t * vPart;
+ int * pMapBack;
+ int i, nCountPis, nCountRegs;
+ int nClasses, nPartSize, fVerbose;
+ int clk = clock();
+ if ( pPars->fConstrs )
+ {
+ printf( "Cannot use partitioned computation with constraints.\n" );
+ return NULL;
+ }
+ // save parameters
+ nPartSize = pPars->nPartSize; pPars->nPartSize = 0;
+ fVerbose = pPars->fVerbose; pPars->fVerbose = 0;
+ // generate partitions
+ if ( pAig->vClockDoms )
+ {
+ // divide large clock domains into separate partitions
+ vResult = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
+ {
+ if ( nPartSize && Vec_IntSize(vPart) > nPartSize )
+ Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize );
+ else
+ Vec_PtrPush( vResult, Vec_IntDup(vPart) );
+ }
+ }
+ else
+ vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize );
+// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );
+// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize );
+ if ( fPrintParts )
+ {
+ // print partitions
+ printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) );
+ Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
+ {
+// extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
+ sprintf( Buffer, "part%03d.aig", i );
+ pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL );
+ Ioa_WriteAiger( pTemp, Buffer, 0, 0 );
+ printf( "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
+ i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) );
+ Aig_ManStop( pTemp );
+ }
+ }
+
+ // perform SSW with partitions
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
+ Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
+ {
+ pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
+ Aig_ManSetRegNum( pTemp, pTemp->nRegs );
+ // create the projection of 1-hot registers
+ if ( pAig->vOnehots )
+ pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );
+ // run SSW
+ if (nCountPis>0) {
+ pNew = Ssw_SignalCorrespondence( pTemp, pPars );
+ nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
+ if ( fVerbose )
+ printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
+ i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
+ Aig_ManStop( pNew );
+ }
+ Aig_ManStop( pTemp );
+ ABC_FREE( pMapBack );
+ }
+ // remap the AIG
+ pNew = Aig_ManDupRepr( pAig, 0 );
+ Aig_ManSeqCleanup( pNew );
+// Aig_ManPrintStats( pAig );
+// Aig_ManPrintStats( pNew );
+ Vec_VecFree( (Vec_Vec_t *)vResult );
+ pPars->nPartSize = nPartSize;
+ pPars->fVerbose = fVerbose;
+ if ( fVerbose )
+ {
+ ABC_PRT( "Total time", clock() - clk );
+ }
+ return pNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswRarity.c b/src/proof/ssw/sswRarity.c
new file mode 100644
index 00000000..264bb2c8
--- /dev/null
+++ b/src/proof/ssw/sswRarity.c
@@ -0,0 +1,1158 @@
+/**CFile****************************************************************
+
+ FileName [sswRarity.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Rarity-driven refinement of equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswRarity.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_RarMan_t_ Ssw_RarMan_t;
+struct Ssw_RarMan_t_
+{
+ // parameters
+ int nWords; // the number of words to simulate
+ int nFrames; // the number of frames to simulate
+ int nBinSize; // the number of flops in one group
+ int fVerbose; // the verbosiness flag
+ int nGroups; // the number of flop groups
+ int nWordsReg; // the number of words in the registers
+ // internal data
+ Aig_Man_t * pAig; // AIG with equivalence classes
+ Ssw_Cla_t * ppClasses; // equivalence classes
+ Vec_Int_t * vInits; // initial state
+ // simulation data
+ word * pObjData; // simulation info for each obj
+ word * pPatData; // pattern data for each reg
+ // candidates to update
+ Vec_Ptr_t * vUpdConst; // constant 1 candidates
+ Vec_Ptr_t * vUpdClass; // class representatives
+ // rarity data
+ int * pRarity; // occur counts for patterns in groups
+ double * pPatCosts; // pattern costs
+ // best patterns
+ Vec_Int_t * vPatBests; // best patterns
+ int iFailPo; // failed primary output
+ int iFailPat; // failed pattern
+};
+
+
+static inline int Ssw_RarGetBinPat( Ssw_RarMan_t * p, int iBin, int iPat )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ return p->pRarity[iBin * (1 << p->nBinSize) + iPat];
+}
+static inline void Ssw_RarSetBinPat( Ssw_RarMan_t * p, int iBin, int iPat, int Value )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ p->pRarity[iBin * (1 << p->nBinSize) + iPat] = Value;
+}
+static inline void Ssw_RarAddToBinPat( Ssw_RarMan_t * p, int iBin, int iPat )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ p->pRarity[iBin * (1 << p->nBinSize) + iPat]++;
+}
+
+static inline int Ssw_RarBitWordNum( int nBits ) { return (nBits>>6) + ((nBits&63) > 0); }
+
+static inline word * Ssw_RarObjSim( Ssw_RarMan_t * p, int Id ) { assert( Id < Aig_ManObjNumMax(p->pAig) ); return p->pObjData + p->nWords * Id; }
+static inline word * Ssw_RarPatSim( Ssw_RarMan_t * p, int Id ) { assert( Id < 64 * p->nWords ); return p->pPatData + p->nWordsReg * Id; }
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Prepares random number generator.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_RarManPrepareRandom( int nRandSeed )
+{
+ int i;
+ Aig_ManRandom( 1 );
+ for ( i = 0; i < nRandSeed; i++ )
+ Aig_ManRandom( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Initializes random primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_RarManAssingRandomPis( Ssw_RarMan_t * p )
+{
+ word * pSim;
+ Aig_Obj_t * pObj;
+ int w, i;
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = Aig_ManRandom64(0);
+// pSim[0] <<= 1;
+// pSim[0] = (pSim[0] << 2) | 2;
+ pSim[0] = (pSim[0] << 4) | ((i & 1) ? 0xA : 0xC);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Ssw_RarDeriveCex( Ssw_RarMan_t * p, int iFrame, int iPo, int iPatFinal, int fVerbose )
+{
+ Abc_Cex_t * pCex;
+ Aig_Obj_t * pObj;
+ Vec_Int_t * vTrace;
+ word * pSim;
+ int i, r, f, iBit, iPatThis;
+ // compute the pattern sequence
+ iPatThis = iPatFinal;
+ vTrace = Vec_IntStartFull( iFrame / p->nFrames + 1 );
+ Vec_IntWriteEntry( vTrace, iFrame / p->nFrames, iPatThis );
+ for ( r = iFrame / p->nFrames - 1; r >= 0; r-- )
+ {
+ iPatThis = Vec_IntEntry( p->vPatBests, r * p->nWords + iPatThis / 64 );
+ Vec_IntWriteEntry( vTrace, r, iPatThis );
+ }
+ // create counter-example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), iFrame+1 );
+ pCex->iFrame = iFrame;
+ pCex->iPo = iPo;
+ // insert the bits
+ iBit = Aig_ManRegNum(p->pAig);
+ for ( f = 0; f <= iFrame; f++ )
+ {
+ Ssw_RarManAssingRandomPis( p );
+ iPatThis = Vec_IntEntry( vTrace, f / p->nFrames );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ if ( Abc_InfoHasBit( (unsigned *)pSim, iPatThis ) )
+ Abc_InfoSetBit( pCex->pData, iBit );
+ iBit++;
+ }
+ }
+ Vec_IntFree( vTrace );
+ assert( iBit == pCex->nBits );
+ // verify the counter example
+ if ( !Saig_ManVerifyCex( p->pAig, pCex ) )
+ {
+ printf( "Ssw_RarDeriveCex(): Counter-example is invalid.\n" );
+// Abc_CexFree( pCex );
+// pCex = NULL;
+ }
+ else
+ {
+// printf( "Counter-example verification is successful.\n" );
+ if ( fVerbose )
+ printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). \n", pCex->iPo, pCex->iFrame );
+ }
+ return pCex;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transposing 32-bit matrix.]
+
+ Description [Borrowed from "Hacker's Delight", by Henry Warren.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void transpose32( unsigned A[32] )
+{
+ int j, k;
+ unsigned t, m = 0x0000FFFF;
+ for ( j = 16; j != 0; j = j >> 1, m = m ^ (m << j) )
+ {
+ for ( k = 0; k < 32; k = (k + j + 1) & ~j )
+ {
+ t = (A[k] ^ (A[k+j] >> j)) & m;
+ A[k] = A[k] ^ t;
+ A[k+j] = A[k+j] ^ (t << j);
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transposing 64-bit matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void transpose64( word A[64] )
+{
+ int j, k;
+ word t, m = 0x00000000FFFFFFFF;
+ for ( j = 32; j != 0; j = j >> 1, m = m ^ (m << j) )
+ {
+ for ( k = 0; k < 64; k = (k + j + 1) & ~j )
+ {
+ t = (A[k] ^ (A[k+j] >> j)) & m;
+ A[k] = A[k] ^ t;
+ A[k+j] = A[k+j] ^ (t << j);
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transposing 64-bit matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void transpose64Simple( word A[64], word B[64] )
+{
+ int i, k;
+ for ( i = 0; i < 64; i++ )
+ B[i] = 0;
+ for ( i = 0; i < 64; i++ )
+ for ( k = 0; k < 64; k++ )
+ if ( (A[i] >> k) & 1 )
+ B[k] |= ((word)1 << (63-i));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testing the transposing code.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void TransposeTest()
+{
+ word M[64], N[64];
+ int i, clk;
+ Aig_ManRandom64( 1 );
+// for ( i = 0; i < 64; i++ )
+// M[i] = Aig_ManRandom64( 0 );
+ for ( i = 0; i < 64; i++ )
+ M[i] = i? (word)0 : ~(word)0;
+// for ( i = 0; i < 64; i++ )
+// Extra_PrintBinary( stdout, (unsigned *)&M[i], 64 ), printf( "\n" );
+
+ clk = clock();
+ for ( i = 0; i < 100001; i++ )
+ transpose64Simple( M, N );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+
+ clk = clock();
+ for ( i = 0; i < 100001; i++ )
+ transpose64( M );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+
+ for ( i = 0; i < 64; i++ )
+ if ( M[i] != N[i] )
+ printf( "Mismatch\n" );
+/*
+ printf( "\n" );
+ for ( i = 0; i < 64; i++ )
+ Extra_PrintBinary( stdout, (unsigned *)&M[i], 64 ), printf( "\n" );
+ printf( "\n" );
+ for ( i = 0; i < 64; i++ )
+ Extra_PrintBinary( stdout, (unsigned *)&N[i], 64 ), printf( "\n" );
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transposing pObjData[ nRegs x nWords ] -> pPatData[ nWords x nRegs ].]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_RarTranspose( Ssw_RarMan_t * p )
+{
+ Aig_Obj_t * pObj;
+ word M[64];
+ int w, r, i;
+ for ( w = 0; w < p->nWords; w++ )
+ for ( r = 0; r < p->nWordsReg; r++ )
+ {
+ // save input
+ for ( i = 0; i < 64; i++ )
+ {
+ if ( r*64 + 63-i < Aig_ManRegNum(p->pAig) )
+ {
+ pObj = Saig_ManLi( p->pAig, r*64 + 63-i );
+ M[i] = Ssw_RarObjSim( p, Aig_ObjId(pObj) )[w];
+ }
+ else
+ M[i] = 0;
+ }
+ // transpose
+ transpose64( M );
+ // save output
+ for ( i = 0; i < 64; i++ )
+ Ssw_RarPatSim( p, w*64 + 63-i )[r] = M[i];
+ }
+/*
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ {
+ word * pBitData = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ Extra_PrintBinary( stdout, (unsigned *)pBitData, 64*p->nWords ); printf( "\n" );
+ }
+ printf( "\n" );
+ for ( i = 0; i < p->nWords*64; i++ )
+ {
+ word * pBitData = Ssw_RarPatSim( p, i );
+ Extra_PrintBinary( stdout, (unsigned *)pBitData, Aig_ManRegNum(p->pAig) ); printf( "\n" );
+ }
+ printf( "\n" );
+*/
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets random inputs and specialied flop outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_RarManInitialize( Ssw_RarMan_t * p, Vec_Int_t * vInit )
+{
+ Aig_Obj_t * pObj, * pObjLi;
+ word * pSim, * pSimLi;
+ int w, i;
+ // constant
+ pObj = Aig_ManConst1( p->pAig );
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = ~(word)0;
+ // primary inputs
+ Ssw_RarManAssingRandomPis( p );
+ // flop outputs
+ if ( vInit )
+ {
+ assert( Vec_IntSize(vInit) == Saig_ManRegNum(p->pAig) * p->nWords );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = Vec_IntEntry(vInit, w * Saig_ManRegNum(p->pAig) + i) ? ~(word)0 : (word)0;
+ }
+ }
+ else
+ {
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
+ {
+ pSimLi = Ssw_RarObjSim( p, Aig_ObjId(pObjLi) );
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = pSimLi[w];
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarManObjIsConst( void * pMan, Aig_Obj_t * pObj )
+{
+ Ssw_RarMan_t * p = (Ssw_RarMan_t *)pMan;
+ word * pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ word Flip = pObj->fPhase ? ~0 : 0;
+ int w;
+ for ( w = 0; w < p->nWords; w++ )
+ if ( pSim[w] ^ Flip )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation infos are equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarManObjsAreEqual( void * pMan, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ Ssw_RarMan_t * p = (Ssw_RarMan_t *)pMan;
+ word * pSim0 = Ssw_RarObjSim( p, pObj0->Id );
+ word * pSim1 = Ssw_RarObjSim( p, pObj1->Id );
+ word Flip = (pObj0->fPhase != pObj1->fPhase) ? ~0 : 0;
+ int w;
+ for ( w = 0; w < p->nWords; w++ )
+ if ( pSim0[w] ^ pSim1[w] ^ Flip )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash value of the node using its simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ssw_RarManObjHashWord( void * pMan, Aig_Obj_t * pObj )
+{
+ Ssw_RarMan_t * p = (Ssw_RarMan_t *)pMan;
+ static int s_SPrimes[128] = {
+ 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
+ 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
+ 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
+ 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
+ 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
+ 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
+ 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
+ 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
+ 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
+ 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
+ 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
+ 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
+ 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
+ };
+ unsigned * pSims;
+ unsigned uHash;
+ int i;
+ uHash = 0;
+ pSims = (unsigned *)Ssw_RarObjSim( p, pObj->Id );
+ for ( i = 0; i < 2 * p->nWords; i++ )
+ uHash ^= pSims[i] * s_SPrimes[i & 0x7F];
+ return uHash;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarManObjWhichOne( Ssw_RarMan_t * p, Aig_Obj_t * pObj )
+{
+ word * pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ word Flip = pObj->fPhase ? ~0 : 0;
+ int w, i;
+ for ( w = 0; w < p->nWords; w++ )
+ if ( pSim[w] ^ Flip )
+ {
+ for ( i = 0; i < 64; i++ )
+ if ( ((pSim[w] ^ Flip) >> i) & 1 )
+ break;
+ assert( i < 64 );
+ return w * 64 + i;
+ }
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check if any of the POs becomes non-constant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarManCheckNonConstOutputs( Ssw_RarMan_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ p->iFailPo = -1;
+ p->iFailPat = -1;
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( p->pAig->nConstrs && i >= Saig_ManPoNum(p->pAig) - p->pAig->nConstrs )
+ return 0;
+ if ( !Ssw_RarManObjIsConst(p, pObj) )
+ {
+ p->iFailPo = i;
+ p->iFailPat = Ssw_RarManObjWhichOne( p, pObj );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_RarManSimulate( Ssw_RarMan_t * p, Vec_Int_t * vInit, int fUpdate, int fFirst )
+{
+ Aig_Obj_t * pObj, * pRepr;
+ word * pSim, * pSim0, * pSim1;
+ word Flip, Flip0, Flip1;
+ int w, i;
+ // initialize
+ Ssw_RarManInitialize( p, vInit );
+ Vec_PtrClear( p->vUpdConst );
+ Vec_PtrClear( p->vUpdClass );
+ Aig_ManIncrementTravId( p->pAig );
+ // check comb inputs
+ if ( fUpdate )
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pRepr = Aig_ObjRepr(p->pAig, pObj);
+ if ( pRepr == NULL || Aig_ObjIsTravIdCurrent( p->pAig, pRepr ) )
+ continue;
+ if ( Ssw_RarManObjsAreEqual( p, pObj, pRepr ) )
+ continue;
+ // save for update
+ if ( pRepr == Aig_ManConst1(p->pAig) )
+ Vec_PtrPush( p->vUpdConst, pObj );
+ else
+ {
+ Vec_PtrPush( p->vUpdClass, pRepr );
+ Aig_ObjSetTravIdCurrent( p->pAig, pRepr );
+ }
+ }
+ // simulate
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ pSim0 = Ssw_RarObjSim( p, Aig_ObjFaninId0(pObj) );
+ pSim1 = Ssw_RarObjSim( p, Aig_ObjFaninId1(pObj) );
+ Flip0 = Aig_ObjFaninC0(pObj) ? ~0 : 0;
+ Flip1 = Aig_ObjFaninC1(pObj) ? ~0 : 0;
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = (Flip0 ^ pSim0[w]) & (Flip1 ^ pSim1[w]);
+ if ( !fUpdate )
+ continue;
+ // check classes
+ pRepr = Aig_ObjRepr(p->pAig, pObj);
+ if ( pRepr == NULL || Aig_ObjIsTravIdCurrent( p->pAig, pRepr ) )
+ continue;
+ if ( Ssw_RarManObjsAreEqual( p, pObj, pRepr ) )
+ continue;
+ // save for update
+ if ( pRepr == Aig_ManConst1(p->pAig) )
+ Vec_PtrPush( p->vUpdConst, pObj );
+ else
+ {
+ Vec_PtrPush( p->vUpdClass, pRepr );
+ Aig_ObjSetTravIdCurrent( p->pAig, pRepr );
+ }
+ }
+ // transfer to POs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ {
+ pSim = Ssw_RarObjSim( p, Aig_ObjId(pObj) );
+ pSim0 = Ssw_RarObjSim( p, Aig_ObjFaninId0(pObj) );
+ Flip = Aig_ObjFaninC0(pObj) ? ~0 : 0;
+ for ( w = 0; w < p->nWords; w++ )
+ pSim[w] = Flip ^ pSim0[w];
+ }
+ // refine classes
+ if ( fUpdate )
+ {
+ if ( fFirst )
+ {
+ Vec_Ptr_t * vCands = Vec_PtrAlloc( 1000 );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ Vec_PtrPush( vCands, pObj );
+ assert( Vec_PtrSize(vCands) == Ssw_ClassesCand1Num(p->ppClasses) );
+ Ssw_ClassesPrepareRehash( p->ppClasses, vCands, 0 );
+ Vec_PtrFree( vCands );
+ }
+ else
+ {
+ Ssw_ClassesRefineConst1Group( p->ppClasses, p->vUpdConst, 1 );
+ Ssw_ClassesRefineGroup( p->ppClasses, p->vUpdClass, 1 );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Ssw_RarMan_t * Ssw_RarManStart( Aig_Man_t * pAig, int nWords, int nFrames, int nBinSize, int fVerbose )
+{
+ Ssw_RarMan_t * p;
+// if ( Aig_ManRegNum(pAig) < nBinSize || nBinSize <= 0 )
+// return NULL;
+ p = ABC_CALLOC( Ssw_RarMan_t, 1 );
+ p->pAig = pAig;
+ p->nWords = nWords;
+ p->nFrames = nFrames;
+ p->nBinSize = nBinSize;
+ p->fVerbose = fVerbose;
+ p->nGroups = Aig_ManRegNum(pAig) / nBinSize;
+ p->pRarity = ABC_CALLOC( int, (1 << nBinSize) * p->nGroups );
+ p->pPatCosts = ABC_CALLOC( double, p->nWords * 64 );
+ p->nWordsReg = Ssw_RarBitWordNum( Aig_ManRegNum(pAig) );
+ p->pObjData = ABC_ALLOC( word, Aig_ManObjNumMax(pAig) * p->nWords );
+ p->pPatData = ABC_ALLOC( word, 64 * p->nWords * p->nWordsReg );
+ p->vUpdConst = Vec_PtrAlloc( 100 );
+ p->vUpdClass = Vec_PtrAlloc( 100 );
+ p->vPatBests = Vec_IntAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Ssw_RarManStop( Ssw_RarMan_t * p )
+{
+ if ( p->ppClasses ) Ssw_ClassesStop( p->ppClasses );
+ Vec_IntFreeP( &p->vInits );
+ Vec_IntFreeP( &p->vPatBests );
+ Vec_PtrFreeP( &p->vUpdConst );
+ Vec_PtrFreeP( &p->vUpdClass );
+ ABC_FREE( p->pObjData );
+ ABC_FREE( p->pPatData );
+ ABC_FREE( p->pPatCosts );
+ ABC_FREE( p->pRarity );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Select best patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Ssw_RarTransferPatterns( Ssw_RarMan_t * p, Vec_Int_t * vInits )
+{
+// Aig_Obj_t * pObj;
+ unsigned char * pData;
+ unsigned * pPattern;
+ int i, k, Value;
+
+ // more data from regs to pats
+ Ssw_RarTranspose( p );
+
+ // update counters
+ for ( k = 0; k < p->nWords * 64; k++ )
+ {
+ pData = (unsigned char *)Ssw_RarPatSim( p, k );
+ for ( i = 0; i < p->nGroups; i++ )
+ Ssw_RarAddToBinPat( p, i, pData[i] );
+ }
+
+ // for each pattern
+ for ( k = 0; k < p->nWords * 64; k++ )
+ {
+ pData = (unsigned char *)Ssw_RarPatSim( p, k );
+ // find the cost of its values
+ p->pPatCosts[k] = 0.0;
+ for ( i = 0; i < p->nGroups; i++ )
+ {
+ Value = Ssw_RarGetBinPat( p, i, pData[i] );
+ assert( Value > 0 );
+ p->pPatCosts[k] += 1.0/(Value*Value);
+ }
+ // print the result
+//printf( "%3d : %9.6f\n", k, p->pPatCosts[k] );
+ }
+
+ // choose as many as there are words
+ Vec_IntClear( vInits );
+ for ( i = 0; i < p->nWords; i++ )
+ {
+ // select the best
+ int iPatBest = -1;
+ double iCostBest = -ABC_INFINITY;
+ for ( k = 0; k < p->nWords * 64; k++ )
+ if ( iCostBest < p->pPatCosts[k] )
+ {
+ iCostBest = p->pPatCosts[k];
+ iPatBest = k;
+ }
+ // remove from costs
+ assert( iPatBest >= 0 );
+ p->pPatCosts[iPatBest] = -ABC_INFINITY;
+ // set the flops
+ pPattern = (unsigned *)Ssw_RarPatSim( p, iPatBest );
+ for ( k = 0; k < Aig_ManRegNum(p->pAig); k++ )
+ Vec_IntPush( vInits, Abc_InfoHasBit(pPattern, k) );
+//printf( "Best pattern %5d\n", iPatBest );
+ Vec_IntPush( p->vPatBests, iPatBest );
+ }
+ assert( Vec_IntSize(vInits) == Aig_ManRegNum(p->pAig) * p->nWords );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Ssw_RarFindStartingState( Aig_Man_t * pAig, Abc_Cex_t * pCex )
+{
+ Vec_Int_t * vInit;
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i, iBit;
+ // assign register outputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( pCex->pData, i );
+ // simulate the timeframes
+ iBit = pCex->nRegs;
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(pAig)->fMarkB = 1;
+ Saig_ManForEachPi( pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( pCex->pData, iBit++ );
+ Saig_ManForEachLiLo( pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ }
+ assert( iBit == pCex->nBits );
+ // check that the output failed as expected -- cannot check because it is not an SRM!
+// pObj = Aig_ManPo( pAig, pCex->iPo );
+// if ( pObj->fMarkB != 1 )
+// printf( "The counter-example does not refine the output.\n" );
+ // record the new pattern
+ vInit = Vec_IntAlloc( Saig_ManRegNum(pAig) );
+ Saig_ManForEachLo( pAig, pObj, i )
+ {
+//printf( "%d", pObj->fMarkB );
+ Vec_IntPush( vInit, pObj->fMarkB );
+ }
+//printf( "\n" );
+ Aig_ManCleanMarkB( pAig );
+ return vInit;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarCheckTrivial( Aig_Man_t * pAig, int fVerbose )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Saig_ManForEachPo( pAig, pObj, i )
+ {
+ if ( pAig->nConstrs && i >= Saig_ManPoNum(pAig) - pAig->nConstrs )
+ return 0;
+ if ( pObj->fPhase )
+ {
+ ABC_FREE( pAig->pSeqModel );
+ pAig->pSeqModel = Abc_CexAlloc( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), 1 );
+ pAig->pSeqModel->iPo = i;
+ if ( fVerbose )
+ printf( "Output %d is trivally SAT in frame 0. \n", i );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform sequential simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSimulate( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fVerbose )
+{
+ int fTryBmc = 0;
+ int fMiter = 1;
+ Ssw_RarMan_t * p;
+ int r, f, clk, clkTotal = clock();
+ int nTimeToStop = time(NULL) + TimeOut;
+ int RetValue = -1;
+ int iFrameFail = -1;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManConstrNum(pAig) == 0 );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ return -1;
+ // check trivially SAT miters
+ if ( fMiter && Ssw_RarCheckTrivial( pAig, fVerbose ) )
+ return 0;
+ if ( fVerbose )
+ printf( "Rarity simulation with %d words, %d frames, %d rounds, %d seed, and %d sec timeout.\n",
+ nWords, nFrames, nRounds, nRandSeed, TimeOut );
+ // reset random numbers
+ Ssw_RarManPrepareRandom( nRandSeed );
+
+ // create manager
+ p = Ssw_RarManStart( pAig, nWords, nFrames, nBinSize, fVerbose );
+ p->vInits = Vec_IntStart( Aig_ManRegNum(pAig) * nWords );
+
+ // perform simulation rounds
+ for ( r = 0; r < nRounds; r++ )
+ {
+ clk = clock();
+ if ( fTryBmc )
+ {
+ Aig_Man_t * pNewAig = Saig_ManDupWithPhase( pAig, p->vInits );
+ Saig_BmcPerform( pNewAig, 0, 100, 2000, 3, 0, 0, 1 /*fVerbose*/, 0, &iFrameFail );
+// if ( pNewAig->pSeqModel != NULL )
+// printf( "BMC has found a counter-example in frame %d.\n", iFrameFail );
+ Aig_ManStop( pNewAig );
+ }
+ // simulate
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Ssw_RarManSimulate( p, f ? NULL : p->vInits, 0, 0 );
+ if ( fMiter && Ssw_RarManCheckNonConstOutputs(p) )
+ {
+ if ( fVerbose ) printf( "\n" );
+// printf( "Simulation asserted a PO in frame f: %d <= f < %d.\n", r * nFrames, (r+1) * nFrames );
+ Ssw_RarManPrepareRandom( nRandSeed );
+ ABC_FREE( pAig->pSeqModel );
+ pAig->pSeqModel = Ssw_RarDeriveCex( p, r * p->nFrames + f, p->iFailPo, p->iFailPat, fVerbose );
+ RetValue = 0;
+ goto finish;
+ }
+ // check timeout
+ if ( TimeOut && time(NULL) > nTimeToStop )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Reached timeout (%d seconds).\n", TimeOut );
+ goto finish;
+ }
+ }
+ // get initialization patterns
+ Ssw_RarTransferPatterns( p, p->vInits );
+ // printout
+ if ( fVerbose )
+ {
+// printf( "Round %3d: ", r );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ printf( "." );
+ }
+ }
+finish:
+ if ( r == nRounds && f == nFrames )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Simulation did not assert POs in the first %d frames. ", nRounds * nFrames );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ // cleanup
+ Ssw_RarManStop( p );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Perform sequential simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSimulateGia( Gia_Man_t * p, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fVerbose )
+{
+ Aig_Man_t * pAig;
+ int RetValue;
+ pAig = Gia_ManToAigSimple( p );
+ RetValue = Ssw_RarSimulate( pAig, nFrames, nWords, nBinSize, nRounds, nRandSeed, TimeOut, fVerbose );
+ // save counter-example
+ Abc_CexFree( p->pCexSeq );
+ p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSignalFilter( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fMiter, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ Ssw_RarMan_t * p;
+ int r, f, i, k, clkTotal = clock();
+ int nTimeToStop = time(NULL) + TimeOut;
+ int RetValue = -1;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManConstrNum(pAig) == 0 );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ return -1;
+ // check trivially SAT miters
+ if ( fMiter && Ssw_RarCheckTrivial( pAig, 1 ) )
+ return 0;
+ if ( fVerbose )
+ printf( "Rarity equiv filtering with %d words, %d frames, %d rounds, %d seed, and %d sec timeout.\n",
+ nWords, nFrames, nRounds, nRandSeed, TimeOut );
+ // reset random numbers
+ Ssw_RarManPrepareRandom( nRandSeed );
+
+ // create manager
+ p = Ssw_RarManStart( pAig, nWords, nFrames, nBinSize, fVerbose );
+ // compute starting state if needed
+ assert( p->vInits == NULL );
+ if ( pCex )
+ {
+ p->vInits = Ssw_RarFindStartingState( pAig, pCex );
+ printf( "Beginning simulation from the state derived using the counter-example.\n" );
+ }
+ else
+ p->vInits = Vec_IntStart( Aig_ManRegNum(pAig) );
+ // duplicate the array
+ for ( i = 1; i < nWords; i++ )
+ for ( k = 0; k < Aig_ManRegNum(pAig); k++ )
+ Vec_IntPush( p->vInits, Vec_IntEntry(p->vInits, k) );
+ assert( Vec_IntSize(p->vInits) == Aig_ManRegNum(pAig) * nWords );
+
+ // create trivial equivalence classes with all nodes being candidates for constant 1
+ if ( pAig->pReprs == NULL )
+ p->ppClasses = Ssw_ClassesPrepareSimple( pAig, fLatchOnly, 0 );
+ else
+ p->ppClasses = Ssw_ClassesPrepareFromReprs( pAig );
+ Ssw_ClassesSetData( p->ppClasses, p, Ssw_RarManObjHashWord, Ssw_RarManObjIsConst, Ssw_RarManObjsAreEqual );
+ // print the stats
+ if ( fVerbose )
+ {
+ printf( "Initial : " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ // refine classes using BMC
+ for ( r = 0; r < nRounds; r++ )
+ {
+ // start filtering equivalence classes
+ if ( Ssw_ClassesCand1Num(p->ppClasses) == 0 && Ssw_ClassesClassNum(p->ppClasses) == 0 )
+ {
+ printf( "All equivalences are refined away.\n" );
+ break;
+ }
+ // simulate
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Ssw_RarManSimulate( p, f ? NULL : p->vInits, 1, !r && !f );
+ if ( fMiter && Ssw_RarManCheckNonConstOutputs(p) )
+ {
+ if ( !fVerbose )
+ printf( "\r" );
+// printf( "Simulation asserted a PO in frame f: %d <= f < %d.\n", r * nFrames, (r+1) * nFrames );
+ Ssw_RarManPrepareRandom( nRandSeed );
+ Abc_CexFree( pAig->pSeqModel );
+ pAig->pSeqModel = Ssw_RarDeriveCex( p, r * p->nFrames + f, p->iFailPo, p->iFailPat, 1 );
+ RetValue = 0;
+ goto finish;
+ }
+ // check timeout
+ if ( TimeOut && time(NULL) > nTimeToStop )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Reached timeout (%d seconds).\n", TimeOut );
+ goto finish;
+ }
+ }
+ // get initialization patterns
+ Ssw_RarTransferPatterns( p, p->vInits );
+ // printout
+ if ( fVerbose )
+ {
+ printf( "Round %3d: ", r );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ else
+ {
+ printf( "." );
+ }
+ }
+finish:
+ // report
+ if ( r == nRounds && f == nFrames )
+ {
+ if ( !fVerbose )
+ printf( "\r" );
+ printf( "Simulation did not assert POs in the first %d frames. ", nRounds * nFrames );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ // cleanup
+ Ssw_RarManStop( p );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSignalFilterGia( Gia_Man_t * p, int nFrames, int nWords, int nBinSize, int nRounds, int nRandSeed, int TimeOut, int fMiter, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ Aig_Man_t * pAig;
+ int RetValue;
+ pAig = Gia_ManToAigSimple( p );
+ if ( p->pReprs != NULL )
+ {
+ Gia_ManReprToAigRepr2( pAig, p );
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ }
+ RetValue = Ssw_RarSignalFilter( pAig, nFrames, nWords, nBinSize, nRounds, nRandSeed, TimeOut, fMiter, pCex, fLatchOnly, fVerbose );
+ Gia_ManReprFromAigRepr( pAig, p );
+ // save counter-example
+ Abc_CexFree( p->pCexSeq );
+ p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+ return RetValue;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswRarity2.c b/src/proof/ssw/sswRarity2.c
new file mode 100644
index 00000000..ac22b0d5
--- /dev/null
+++ b/src/proof/ssw/sswRarity2.c
@@ -0,0 +1,517 @@
+/**CFile****************************************************************
+
+ FileName [sswRarity.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Rarity-driven refinement of equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswRarity.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_RarMan_t_ Ssw_RarMan_t;
+struct Ssw_RarMan_t_
+{
+ // parameters
+ int nWords; // the number of words to simulate
+ int nFrames; // the number of frames to simulate
+ int nBinSize; // the number of flops in one group
+ int fVerbose; // the verbosiness flag
+ int nGroups; // the number of flop groups
+ // internal data
+ Aig_Man_t * pAig; // AIG with equivalence classes
+ Ssw_Cla_t * ppClasses; // equivalence classes
+ Ssw_Sml_t * pSml; // simulation manager
+ Vec_Ptr_t * vSimInfo; // simulation info from pSml manager
+ Vec_Int_t * vInits; // initial state
+ // rarity data
+ int * pRarity; // occur counts for patterns in groups
+ int * pGroupValues; // occur counts in each group
+ double * pPatCosts; // pattern costs
+
+};
+
+static inline int Ssw_RarGetBinPat( Ssw_RarMan_t * p, int iBin, int iPat )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ return p->pRarity[iBin * (1 << p->nBinSize) + iPat];
+}
+static inline void Ssw_RarSetBinPat( Ssw_RarMan_t * p, int iBin, int iPat, int Value )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ p->pRarity[iBin * (1 << p->nBinSize) + iPat] = Value;
+}
+static inline void Ssw_RarAddToBinPat( Ssw_RarMan_t * p, int iBin, int iPat )
+{
+ assert( iBin >= 0 && iBin < Aig_ManRegNum(p->pAig) / p->nBinSize );
+ assert( iPat >= 0 && iPat < (1 << p->nBinSize) );
+ p->pRarity[iBin * (1 << p->nBinSize) + iPat]++;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Ssw_RarMan_t * Ssw_RarManStart( Aig_Man_t * pAig, int nWords, int nFrames, int nBinSize, int fVerbose )
+{
+ Ssw_RarMan_t * p;
+ if ( Aig_ManRegNum(pAig) < nBinSize || nBinSize <= 0 )
+ return NULL;
+ p = ABC_CALLOC( Ssw_RarMan_t, 1 );
+ p->pAig = pAig;
+ p->nWords = nWords;
+ p->nFrames = nFrames;
+ p->nBinSize = nBinSize;
+ p->fVerbose = fVerbose;
+ p->nGroups = Aig_ManRegNum(pAig) / nBinSize;
+ p->pRarity = ABC_CALLOC( int, (1 << nBinSize) * p->nGroups );
+ p->pGroupValues = ABC_CALLOC( int, p->nGroups );
+ p->pPatCosts = ABC_CALLOC( double, p->nWords * 32 );
+ p->pSml = Ssw_SmlStart( pAig, 0, nFrames, nWords );
+ p->vSimInfo = Ssw_SmlSimDataPointers( p->pSml );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Ssw_RarManStop( Ssw_RarMan_t * p )
+{
+ if ( p->pSml ) Ssw_SmlStop( p->pSml );
+ if ( p->ppClasses ) Ssw_ClassesStop( p->ppClasses );
+ Vec_PtrFreeP( &p->vSimInfo );
+ Vec_IntFreeP( &p->vInits );
+ ABC_FREE( p->pGroupValues );
+ ABC_FREE( p->pPatCosts );
+ ABC_FREE( p->pRarity );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Updates rarity counters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Ssw_RarUpdateCounters( Ssw_RarMan_t * p )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pData;
+ int i, k;
+/*
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ {
+ pData = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjId(pObj) ) + p->nWords * (p->nFrames - 1);
+ Extra_PrintBinary( stdout, pData, 32 ); printf( "\n" );
+ }
+*/
+ for ( k = 0; k < p->nWords * 32; k++ )
+ {
+ for ( i = 0; i < p->nGroups; i++ )
+ p->pGroupValues[i] = 0;
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ {
+ pData = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjId(pObj) ) + p->nWords * (p->nFrames - 1);
+ if ( Abc_InfoHasBit(pData, k) && i / p->nBinSize < p->nGroups )
+ p->pGroupValues[i / p->nBinSize] |= (1 << (i % p->nBinSize));
+ }
+ for ( i = 0; i < p->nGroups; i++ )
+ Ssw_RarAddToBinPat( p, i, p->pGroupValues[i] );
+ }
+/*
+ for ( i = 0; i < p->nGroups; i++ )
+ {
+ for ( k = 0; k < (1 << p->nBinSize); k++ )
+ printf( "%d ", Ssw_RarGetBinPat(p, i, k) );
+ printf( "\n" );
+ }
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Select best patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Ssw_RarTransferPatterns( Ssw_RarMan_t * p, Vec_Int_t * vInits )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pData;
+ int i, k, Value;
+
+ // for each pattern
+ for ( k = 0; k < p->nWords * 32; k++ )
+ {
+ for ( i = 0; i < p->nGroups; i++ )
+ p->pGroupValues[i] = 0;
+ // compute its group values
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ {
+ pData = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjId(pObj) ) + p->nWords * (p->nFrames - 1);
+ if ( Abc_InfoHasBit(pData, k) && i / p->nBinSize < p->nGroups )
+ p->pGroupValues[i / p->nBinSize] |= (1 << (i % p->nBinSize));
+ }
+ // find the cost of its values
+ p->pPatCosts[k] = 0.0;
+ for ( i = 0; i < p->nGroups; i++ )
+ {
+ Value = Ssw_RarGetBinPat( p, i, p->pGroupValues[i] );
+ assert( Value > 0 );
+ p->pPatCosts[k] += 1.0/(Value*Value);
+ }
+ // print the result
+// printf( "%3d : %9.6f\n", k, p->pPatCosts[k] );
+ }
+
+ // choose as many as there are words
+ Vec_IntClear( vInits );
+ for ( i = 0; i < p->nWords; i++ )
+ {
+ // select the best
+ int iPatBest = -1;
+ double iCostBest = -ABC_INFINITY;
+ for ( k = 0; k < p->nWords * 32; k++ )
+ if ( iCostBest < p->pPatCosts[k] )
+ {
+ iCostBest = p->pPatCosts[k];
+ iPatBest = k;
+ }
+ // remove from costs
+ assert( iPatBest >= 0 );
+ p->pPatCosts[iPatBest] = -ABC_INFINITY;
+ // set the flops
+ Saig_ManForEachLi( p->pAig, pObj, k )
+ {
+ pData = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjId(pObj) ) + p->nWords * (p->nFrames - 1);
+ Vec_IntPush( vInits, Abc_InfoHasBit(pData, iPatBest) );
+ }
+//printf( "Best pattern %5d\n", iPatBest );
+ }
+ assert( Vec_IntSize(vInits) == Aig_ManRegNum(p->pAig) * p->nWords );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Ssw_RarFindStartingState( Aig_Man_t * pAig, Abc_Cex_t * pCex )
+{
+ Vec_Int_t * vInit;
+ Aig_Obj_t * pObj, * pObjLi;
+ int f, i, iBit;
+ // assign register outputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( pCex->pData, i );
+ // simulate the timeframes
+ iBit = pCex->nRegs;
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // set the PI simulation information
+ Aig_ManConst1(pAig)->fMarkB = 1;
+ Saig_ManForEachPi( pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( pCex->pData, iBit++ );
+ Saig_ManForEachLiLo( pAig, pObjLi, pObj, i )
+ pObj->fMarkB = pObjLi->fMarkB;
+ // simulate internal nodes
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // assign the COs
+ Aig_ManForEachPo( pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
+ }
+ assert( iBit == pCex->nBits );
+ // check that the output failed as expected -- cannot check because it is not an SRM!
+// pObj = Aig_ManPo( pAig, pCex->iPo );
+// if ( pObj->fMarkB != 1 )
+// printf( "The counter-example does not refine the output.\n" );
+ // record the new pattern
+ vInit = Vec_IntAlloc( Saig_ManRegNum(pAig) );
+ Saig_ManForEachLo( pAig, pObj, i )
+ Vec_IntPush( vInit, pObj->fMarkB );
+ return vInit;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Perform sequential simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSimulate2( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int TimeOut, int fVerbose )
+{
+ int fMiter = 1;
+ Ssw_RarMan_t * p;
+ int r, clk, clkTotal = clock();
+ int nTimeToStop = time(NULL) + TimeOut;
+ int RetValue = -1;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManConstrNum(pAig) == 0 );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ return -1;
+ if ( fVerbose )
+ printf( "Simulating %d words through %d frames with %d binsize, %d rounds, and %d sec timeout.\n",
+ nWords, nFrames, nBinSize, nRounds, TimeOut );
+ // reset random numbers
+ Aig_ManRandom( 1 );
+
+ // create manager
+ p = Ssw_RarManStart( pAig, nWords, nFrames, nBinSize, fVerbose );
+ p->vInits = Vec_IntStart( Aig_ManRegNum(pAig) * nWords );
+ Ssw_SmlInitializeSpecial( p->pSml, p->vInits );
+
+ // perform simulation rounds
+ for ( r = 0; r < nRounds; r++ )
+ {
+ clk = clock();
+ // simulate
+ Ssw_SmlSimulateOne( p->pSml );
+ if ( fMiter && Ssw_SmlCheckNonConstOutputs(p->pSml) )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Simulation asserted a PO in frame f: %d <= f < %d.\n", r * nFrames, (r+1) * nFrames );
+ RetValue = 0;
+ break;
+ }
+ // get initialization patterns
+ Ssw_RarUpdateCounters( p );
+ Ssw_RarTransferPatterns( p, p->vInits );
+ Ssw_SmlInitializeSpecial( p->pSml, p->vInits );
+ // printout
+ if ( fVerbose )
+ {
+// printf( "Round %3d: ", r );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ printf( "." );
+ }
+ // check timeout
+ if ( TimeOut && time(NULL) > nTimeToStop )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Reached timeout (%d seconds).\n", TimeOut );
+ break;
+ }
+ }
+ if ( r == nRounds )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Simulation did not assert POs in the first %d frames. ", nRounds * nFrames );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ // cleanup
+ Ssw_RarManStop( p );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSignalFilter2( Aig_Man_t * pAig, int nFrames, int nWords, int nBinSize, int nRounds, int TimeOut, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ int fMiter = 0;
+ Ssw_RarMan_t * p;
+ int r, i, k, clkTotal = clock();
+ int nTimeToStop = time(NULL) + TimeOut;
+ int RetValue = -1;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManConstrNum(pAig) == 0 );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ return -1;
+ if ( fVerbose )
+ printf( "Filtering equivs with %d words through %d frames with %d binsize, %d rounds, and %d sec timeout.\n",
+ nWords, nFrames, nBinSize, nRounds, TimeOut );
+ // reset random numbers
+ Aig_ManRandom( 1 );
+
+ // create manager
+ p = Ssw_RarManStart( pAig, nWords, nFrames, nBinSize, fVerbose );
+ // compute starting state if needed
+ assert( p->vInits == NULL );
+ if ( pCex )
+ p->vInits = Ssw_RarFindStartingState( pAig, pCex );
+ else
+ p->vInits = Vec_IntStart( Aig_ManRegNum(pAig) );
+ // duplicate the array
+ for ( i = 1; i < nWords; i++ )
+ for ( k = 0; k < Aig_ManRegNum(pAig); k++ )
+ Vec_IntPush( p->vInits, Vec_IntEntry(p->vInits, k) );
+ assert( Vec_IntSize(p->vInits) == Aig_ManRegNum(pAig) * nWords );
+ // initialize simulation manager
+ Ssw_SmlInitializeSpecial( p->pSml, p->vInits );
+
+ // create trivial equivalence classes with all nodes being candidates for constant 1
+ if ( pAig->pReprs == NULL )
+ p->ppClasses = Ssw_ClassesPrepareSimple( pAig, fLatchOnly, 0 );
+ else
+ p->ppClasses = Ssw_ClassesPrepareFromReprs( pAig );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, NULL, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
+ // print the stats
+ if ( fVerbose )
+ {
+ printf( "Initial : " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ // refine classes using BMC
+ for ( r = 0; r < nRounds; r++ )
+ {
+ // start filtering equivalence classes
+ if ( Ssw_ClassesCand1Num(p->ppClasses) == 0 && Ssw_ClassesClassNum(p->ppClasses) == 0 )
+ {
+ printf( "All equivalences are refined away.\n" );
+ break;
+ }
+ // simulate
+ Ssw_SmlSimulateOne( p->pSml );
+ if ( fMiter && Ssw_SmlCheckNonConstOutputs(p->pSml) )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Simulation asserted a PO in frame f: %d <= f < %d.\n", r * nFrames, (r+1) * nFrames );
+ RetValue = 0;
+ break;
+ }
+ // check equivalence classes
+ Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ Ssw_ClassesRefine( p->ppClasses, 1 );
+ // printout
+ if ( fVerbose )
+ {
+ printf( "Round %3d: ", r );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ // get initialization patterns
+ Ssw_RarUpdateCounters( p );
+ Ssw_RarTransferPatterns( p, p->vInits );
+ Ssw_SmlInitializeSpecial( p->pSml, p->vInits );
+ // check timeout
+ if ( TimeOut && time(NULL) > nTimeToStop )
+ {
+ if ( fVerbose ) printf( "\n" );
+ printf( "Reached timeout (%d seconds).\n", TimeOut );
+ break;
+ }
+ }
+ if ( r == nRounds )
+ {
+ printf( "Simulation did not assert POs in the first %d frames. ", nRounds * nFrames );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ }
+ // cleanup
+ Ssw_RarManStop( p );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filter equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_RarSignalFilterGia2( Gia_Man_t * p, int nFrames, int nWords, int nBinSize, int nRounds, int TimeOut, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
+{
+ Aig_Man_t * pAig;
+ int RetValue;
+ pAig = Gia_ManToAigSimple( p );
+ if ( p->pReprs != NULL )
+ {
+ Gia_ManReprToAigRepr2( pAig, p );
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ }
+ RetValue = Ssw_RarSignalFilter2( pAig, nFrames, nWords, nBinSize, nRounds, TimeOut, pCex, fLatchOnly, fVerbose );
+ Gia_ManReprFromAigRepr( pAig, p );
+ Aig_ManStop( pAig );
+ return RetValue;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswSat.c b/src/proof/ssw/sswSat.c
new file mode 100644
index 00000000..7d371cac
--- /dev/null
+++ b/src/proof/ssw/sswSat.c
@@ -0,0 +1,306 @@
+/**CFile****************************************************************
+
+ FileName [sswSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Runs equivalence test for the two nodes.]
+
+ Description [Both nodes should be regular and different from each other.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
+{
+ int nBTLimit = p->pPars->nBTLimit;
+ int pLits[3], nLits, RetValue, RetValue1, clk;//, status;
+ p->nSatCalls++;
+ p->pMSat->nSolverCalls++;
+
+ // sanity checks
+ assert( !Aig_IsComplement(pOld) );
+ assert( !Aig_IsComplement(pNew) );
+ assert( pOld != pNew );
+ assert( p->pMSat != NULL );
+
+ // if the nodes do not have SAT variables, allocate them
+ Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
+ Ssw_CnfNodeAddToSolver( p->pMSat, pNew );
+
+ // solve under assumptions
+ // A = 1; B = 0 OR A = 1; B = 1
+ nLits = 2;
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase == pNew->fPhase );
+ if ( p->iOutputLit > -1 )
+ pLits[nLits++] = p->iOutputLit;
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
+
+ if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pMSat->pSat);
+ assert( RetValue != 0 );
+ }
+
+clk = clock();
+ RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
+ (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+p->timeSat += clock() - clk;
+ if ( RetValue1 == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ if ( nLits == 2 )
+ {
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+/*
+ if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pMSat->pSat);
+ assert( RetValue != 0 );
+ }
+*/
+ }
+ p->nSatCallsUnsat++;
+ }
+ else if ( RetValue1 == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatCallsSat++;
+ return 0;
+ }
+ else // if ( RetValue1 == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatFailsReal++;
+ return -1;
+ }
+
+ // if the old node was constant 0, we already know the answer
+ if ( pOld == Aig_ManConst1(p->pFrames) )
+ {
+ p->nSatProof++;
+ return 1;
+ }
+
+ // solve under assumptions
+ // A = 0; B = 1 OR A = 0; B = 0
+ nLits = 2;
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase ^ pNew->fPhase );
+ if ( p->iOutputLit > -1 )
+ pLits[nLits++] = p->iOutputLit;
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+
+ if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pMSat->pSat);
+ assert( RetValue != 0 );
+ }
+
+clk = clock();
+ RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
+ (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+p->timeSat += clock() - clk;
+ if ( RetValue1 == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ if ( nLits == 2 )
+ {
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+/*
+ if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pMSat->pSat);
+ assert( RetValue != 0 );
+ }
+*/
+ }
+ p->nSatCallsUnsat++;
+ }
+ else if ( RetValue1 == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatCallsSat++;
+ return 0;
+ }
+ else // if ( RetValue1 == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatFailsReal++;
+ return -1;
+ }
+ // return SAT proof
+ p->nSatProof++;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constrains two nodes to be equivalent in the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
+{
+ int pLits[2], RetValue, fComplNew;
+ Aig_Obj_t * pTemp;
+
+ // sanity checks
+ assert( Aig_Regular(pOld) != Aig_Regular(pNew) );
+ assert( p->pPars->fConstrs || Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) );
+
+ // move constant to the old node
+ if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) )
+ {
+ assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) );
+ pTemp = pOld;
+ pOld = pNew;
+ pNew = pTemp;
+ }
+
+ // move complement to the new node
+ if ( Aig_IsComplement(pOld) )
+ {
+ pOld = Aig_Regular(pOld);
+ pNew = Aig_Not(pNew);
+ }
+ assert( p->pMSat != NULL );
+
+ // if the nodes do not have SAT variables, allocate them
+ Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pNew) );
+
+ // transform the new node
+ fComplNew = Aig_IsComplement( pNew );
+ pNew = Aig_Regular( pNew );
+
+ // consider the constant 1 case
+ if ( pOld == Aig_ManConst1(p->pFrames) )
+ {
+ // add constraint A = 1 ----> A
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ }
+ RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 1 );
+ assert( RetValue );
+ }
+ else
+ {
+ // add constraint A = B ----> (A v !B)(!A v B)
+
+ // (A v !B)
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), !fComplNew );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+
+ // (!A v B)
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constrains one node in the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj )
+{
+ int RetValue, Lit;
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pPoObj) );
+ // add constraint A = 1 ----> A
+ Lit = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_ObjFanin0(pPoObj)), !Aig_ObjFaninC0(pPoObj) );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_ObjFanin0(pPoObj)->fPhase ) Lit = lit_neg( Lit );
+ }
+ RetValue = sat_solver_addclause( p->pMSat->pSat, &Lit, &Lit + 1 );
+ assert( RetValue );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswSemi.c b/src/proof/ssw/sswSemi.c
new file mode 100644
index 00000000..74305adf
--- /dev/null
+++ b/src/proof/ssw/sswSemi.c
@@ -0,0 +1,322 @@
+/**CFile****************************************************************
+
+ FileName [sswSemi.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Semiformal for equivalence clases.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSemi.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_Sem_t_ Ssw_Sem_t; // BMC manager
+
+struct Ssw_Sem_t_
+{
+ // parameters
+ int nConfMaxStart; // the starting conflict limit
+ int nConfMax; // the intermediate conflict limit
+ int nFramesSweep; // the number of frames to sweep
+ int fVerbose; // prints output statistics
+ // equivalences considered
+ Ssw_Man_t * pMan; // SAT sweeping manager
+ Vec_Ptr_t * vTargets; // the nodes that are watched
+ // storage for patterns
+ int nPatternsAlloc; // the max number of interesting states
+ int nPatterns; // the number of patterns
+ Vec_Ptr_t * vPatterns; // storage for the interesting states
+ Vec_Int_t * vHistory; // what state and how many steps
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sem_t * Ssw_SemManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose )
+{
+ Ssw_Sem_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // create interpolation manager
+ p = ABC_ALLOC( Ssw_Sem_t, 1 );
+ memset( p, 0, sizeof(Ssw_Sem_t) );
+ p->nConfMaxStart = nConfMax;
+ p->nConfMax = nConfMax;
+ p->nFramesSweep = Abc_MaxInt( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames );
+ p->fVerbose = fVerbose;
+ // equivalences considered
+ p->pMan = pMan;
+ p->vTargets = Vec_PtrAlloc( Saig_ManPoNum(p->pMan->pAig) );
+ Saig_ManForEachPo( p->pMan->pAig, pObj, i )
+ Vec_PtrPush( p->vTargets, Aig_ObjFanin0(pObj) );
+ // storage for patterns
+ p->nPatternsAlloc = 512;
+ p->nPatterns = 1;
+ p->vPatterns = Vec_PtrAllocSimInfo( Aig_ManRegNum(p->pMan->pAig), Abc_BitWordNum(p->nPatternsAlloc) );
+ Vec_PtrCleanSimInfo( p->vPatterns, 0, Abc_BitWordNum(p->nPatternsAlloc) );
+ p->vHistory = Vec_IntAlloc( 100 );
+ Vec_IntPush( p->vHistory, 0 );
+ // update arrays of the manager
+ assert( 0 );
+/*
+ ABC_FREE( p->pMan->pNodeToFrames );
+ Vec_IntFree( p->pMan->vSatVars );
+ p->pMan->pNodeToFrames = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep );
+ p->pMan->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) );
+*/
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SemManStop( Ssw_Sem_t * p )
+{
+ Vec_PtrFree( p->vTargets );
+ Vec_PtrFree( p->vPatterns );
+ Vec_IntFree( p->vHistory );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SemCheckTargets( Ssw_Sem_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i )
+ if ( !Ssw_ObjIsConst1Cand(p->pMan->pAig, pObj) )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManFilterBmcSavePattern( Ssw_Sem_t * p )
+{
+ unsigned * pInfo;
+ Aig_Obj_t * pObj;
+ int i;
+ if ( p->nPatterns >= p->nPatternsAlloc )
+ return;
+ Saig_ManForEachLo( p->pMan->pAig, pObj, i )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vPatterns, i );
+ if ( Abc_InfoHasBit( p->pMan->pPatWords, Saig_ManPiNum(p->pMan->pAig) + i ) )
+ Abc_InfoSetBit( pInfo, p->nPatterns );
+ }
+ p->nPatterns++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManFilterBmc( Ssw_Sem_t * pBmc, int iPat, int fCheckTargets )
+{
+ Ssw_Man_t * p = pBmc->pMan;
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ unsigned * pInfo;
+ int i, f, clk, RetValue, fFirst = 0;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * 3 );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( pBmc->vPatterns, i );
+ pObjNew = Aig_NotCond( Aig_ManConst1(p->pFrames), !Abc_InfoHasBit(pInfo, iPat) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+ }
+
+ // sweep internal nodes
+ RetValue = pBmc->nFramesSweep;
+ for ( f = 0; f < pBmc->nFramesSweep; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ if ( Ssw_ManSweepNode( p, pObj, f, 1, NULL ) )
+ {
+ Ssw_ManFilterBmcSavePattern( pBmc );
+ if ( fFirst == 0 )
+ {
+ fFirst = 1;
+ pBmc->nConfMax *= 10;
+ }
+ }
+ if ( f > 0 && p->pMSat->pSat->stats.conflicts >= pBmc->nConfMax )
+ {
+ RetValue = -1;
+ break;
+ }
+ }
+ // quit if this is the last timeframe
+ if ( p->pMSat->pSat->stats.conflicts >= pBmc->nConfMax )
+ {
+ RetValue += f + 1;
+ break;
+ }
+ if ( fCheckTargets && Ssw_SemCheckTargets( pBmc ) )
+ break;
+ // transfer latch input to the latch outputs
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );
+ }
+//printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts );
+ }
+ if ( fFirst )
+ pBmc->nConfMax /= 10;
+
+ // cleanup
+ Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if one of the targets has failed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_FilterUsingSemi( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose )
+{
+ Ssw_Sem_t * p;
+ int RetValue, Frames, Iter, clk = clock();
+ p = Ssw_SemManStart( pMan, nConfMax, fVerbose );
+ if ( fCheckTargets && Ssw_SemCheckTargets( p ) )
+ {
+ assert( 0 );
+ Ssw_SemManStop( p );
+ return 1;
+ }
+ if ( fVerbose )
+ {
+ printf( "AIG : C = %6d. Cl = %6d. Nodes = %6d. ConfMax = %6d. FramesMax = %6d.\n",
+ Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
+ Aig_ManNodeNum(p->pMan->pAig), p->nConfMax, p->nFramesSweep );
+ }
+ RetValue = 0;
+ for ( Iter = 0; Iter < p->nPatterns; Iter++ )
+ {
+clk = clock();
+ pMan->pMSat = Ssw_SatStart( 0 );
+ Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets );
+ if ( fVerbose )
+ {
+ printf( "%3d : C = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ",
+ Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
+ Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pMSat->pSat->stats.conflicts, p->nPatterns,
+ p->pMan->nSatFailsReal? "f" : " " );
+ ABC_PRT( "T", clock() - clk );
+ }
+ Ssw_ManCleanup( p->pMan );
+ if ( fCheckTargets && Ssw_SemCheckTargets( p ) )
+ {
+ printf( "Target is hit!!!\n" );
+ RetValue = 1;
+ }
+ if ( p->nPatterns >= p->nPatternsAlloc )
+ break;
+ }
+ Ssw_SemManStop( p );
+
+ pMan->nStrangers = 0;
+ pMan->nSatCalls = 0;
+ pMan->nSatProof = 0;
+ pMan->nSatFailsReal = 0;
+ pMan->nSatCallsUnsat = 0;
+ pMan->nSatCallsSat = 0;
+ pMan->timeSimSat = 0;
+ pMan->timeSat = 0;
+ pMan->timeSatSat = 0;
+ pMan->timeSatUnsat = 0;
+ pMan->timeSatUndec = 0;
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswSim.c b/src/proof/ssw/sswSim.c
new file mode 100644
index 00000000..9ce89a71
--- /dev/null
+++ b/src/proof/ssw/sswSim.c
@@ -0,0 +1,1405 @@
+/**CFile****************************************************************
+
+ FileName [sswSim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Sequential simulator used by the inductive prover.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSim.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// simulation manager
+struct Ssw_Sml_t_
+{
+ Aig_Man_t * pAig; // the original AIG manager
+ int nPref; // the number of timeframes in the prefix
+ int nFrames; // the number of timeframes
+ int nWordsFrame; // the number of words in each timeframe
+ int nWordsTotal; // the total number of words at a node
+ int nWordsPref; // the number of word in the prefix
+ int fNonConstOut; // have seen a non-const-0 output during simulation
+ int nSimRounds; // statistics
+ int timeSim; // statistics
+ unsigned pData[0]; // simulation data for the nodes
+};
+
+static inline unsigned * Ssw_ObjSim( Ssw_Sml_t * p, int Id ) { return p->pData + p->nWordsTotal * Id; }
+static inline unsigned Ssw_ObjRandomSim() { return Aig_ManRandom(0); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash value of the node using its simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ static int s_SPrimes[128] = {
+ 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
+ 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
+ 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
+ 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
+ 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
+ 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
+ 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
+ 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
+ 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
+ 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
+ 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
+ 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
+ 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
+ };
+ unsigned * pSims;
+ unsigned uHash;
+ int i;
+// assert( p->nWordsTotal <= 128 );
+ uHash = 0;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ uHash ^= pSims[i] * s_SPrimes[i & 0x7F];
+ return uHash;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation infos are equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ pSims0 = Ssw_ObjSim(p, pObj0->Id);
+ pSims1 = Ssw_ObjSim(p, pObj1->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims0[i] != pSims1[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the node appears to be constant 1 candidate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj )
+{
+ return pObj->fPhase == pObj->fMarkB;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the nodes appear equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ return (pObj0->fPhase == pObj1->fPhase) == (pObj0->fMarkB == pObj1->fMarkB);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of 1s in the XOR of simulation data.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeNotEquWeight( Ssw_Sml_t * p, int Left, int Right )
+{
+ unsigned * pSimL, * pSimR;
+ int k, Counter = 0;
+ pSimL = Ssw_ObjSim( p, Left );
+ pSimR = Ssw_ObjSim( p, Right );
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ Counter += Aig_WordCountOnes( pSimL[k] ^ pSimR[k] );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo, Aig_Obj_t * pCand )
+{
+ unsigned * pSimLi, * pSimLo, * pSimCand;
+ int k;
+ assert( pObjLo->fPhase == 0 );
+ // pObjLi->fPhase may be 1, but the LI simulation data is not complemented!
+ pSimCand = Ssw_ObjSim( p, Aig_Regular(pCand)->Id );
+ pSimLi = Ssw_ObjSim( p, pObjLi->Id );
+ pSimLo = Ssw_ObjSim( p, pObjLo->Id );
+ if ( Aig_Regular(pCand)->fPhase ^ Aig_IsComplement(pCand) )
+ {
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ if ( ~pSimCand[k] & (pSimLi[k] ^ pSimLo[k]) )
+ return 0;
+ }
+ else
+ {
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ if ( pSimCand[k] & (pSimLi[k] ^ pSimLo[k]) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of 1s in the implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlCountXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo, Aig_Obj_t * pCand )
+{
+ unsigned * pSimLi, * pSimLo, * pSimCand;
+ int k, Counter = 0;
+ assert( pObjLo->fPhase == 0 );
+ // pObjLi->fPhase may be 1, but the LI simulation data is not complemented!
+ pSimCand = Ssw_ObjSim( p, Aig_Regular(pCand)->Id );
+ pSimLi = Ssw_ObjSim( p, pObjLi->Id );
+ pSimLo = Ssw_ObjSim( p, pObjLo->Id );
+ if ( Aig_Regular(pCand)->fPhase ^ Aig_IsComplement(pCand) )
+ {
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ Counter += Aig_WordCountOnes(~pSimCand[k] & ~(pSimLi[k] ^ pSimLo[k]));
+ }
+ else
+ {
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ Counter += Aig_WordCountOnes(pSimCand[k] & ~(pSimLi[k] ^ pSimLo[k]));
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of 1s in the implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlCountEqual( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo )
+{
+ unsigned * pSimLi, * pSimLo;
+ int k, Counter = 0;
+ assert( pObjLo->fPhase == 0 );
+ // pObjLi->fPhase may be 1, but the LI simulation data is not complemented!
+ pSimLi = Ssw_ObjSim( p, pObjLi->Id );
+ pSimLo = Ssw_ObjSim( p, pObjLo->Id );
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ Counter += Aig_WordCountOnes( ~(pSimLi[k] ^ pSimLo[k]) );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeIsZero( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeIsZeroFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int f )
+{
+ unsigned * pSims = Ssw_ObjSim(p, pObj->Id);
+ return pSims[f] == 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of one's in the patten the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeCountOnesReal( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i, Counter = 0;
+ pSims = Ssw_ObjSim(p, Aig_Regular(pObj)->Id);
+ if ( Aig_Regular(pObj)->fPhase ^ Aig_IsComplement(pObj) )
+ {
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ Counter += Aig_WordCountOnes( ~pSims[i] );
+ }
+ else
+ {
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ Counter += Aig_WordCountOnes( pSims[i] );
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of one's in the patten the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeCountOnesRealVec( Ssw_Sml_t * p, Vec_Ptr_t * vObjs )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pSims, uWord;
+ int i, k, Counter = 0;
+ if ( Vec_PtrSize(vObjs) == 0 )
+ return 0;
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ {
+ uWord = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, vObjs, pObj, k )
+ {
+ pSims = Ssw_ObjSim(p, Aig_Regular(pObj)->Id);
+ if ( Aig_Regular(pObj)->fPhase ^ Aig_IsComplement(pObj) )
+ uWord |= ~pSims[i];
+ else
+ uWord |= pSims[i];
+ }
+ Counter += Aig_WordCountOnes( uWord );
+ }
+ return Counter;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Generated const 0 pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePattern0( Ssw_Man_t * p, int fInit )
+{
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+}
+
+/**Function*************************************************************
+
+ Synopsis [[Generated const 1 pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit )
+{
+ Aig_Obj_t * pObj;
+ int i, k, nTruePis;
+ memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords );
+ if ( !fInit )
+ return;
+ // clear the state bits to correspond to all-0 initial state
+ nTruePis = Saig_ManPiNum(p->pAig);
+ k = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Abc_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the counter-example from the successful pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Ssw_SmlCheckOutputSavePattern( Ssw_Sml_t * p, Aig_Obj_t * pObjPo )
+{
+ Aig_Obj_t * pFanin, * pObjPi;
+ unsigned * pSims;
+ int i, k, BestPat, * pModel;
+ // find the word of the pattern
+ pFanin = Aig_ObjFanin0(pObjPo);
+ pSims = Ssw_ObjSim(p, pFanin->Id);
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ break;
+ assert( i < p->nWordsTotal );
+ // find the bit of the pattern
+ for ( k = 0; k < 32; k++ )
+ if ( pSims[i] & (1 << k) )
+ break;
+ assert( k < 32 );
+ // determine the best pattern
+ BestPat = i * 32 + k;
+ // fill in the counter-example data
+ pModel = ABC_ALLOC( int, Aig_ManPiNum(p->pAig)+1 );
+ Aig_ManForEachPi( p->pAig, pObjPi, i )
+ {
+ pModel[i] = Abc_InfoHasBit(Ssw_ObjSim(p, pObjPi->Id), BestPat);
+// printf( "%d", pModel[i] );
+ }
+ pModel[Aig_ManPiNum(p->pAig)] = pObjPo->Id;
+// printf( "\n" );
+ return pModel;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the one of the output is already non-constant 0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Ssw_SmlCheckOutput( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ // make sure the reference simulation pattern does not detect the bug
+ pObj = Aig_ManPo( p->pAig, 0 );
+ assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( !Ssw_SmlObjIsConstWord( p, Aig_ObjFanin0(pObj) ) )
+ {
+ // create the counter-example from this pattern
+ return Ssw_SmlCheckOutputSavePattern( p, pObj );
+ }
+ }
+ return NULL;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Assigns random patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignRandom( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i, f;
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ pSims[i] = Ssw_ObjRandomSim();
+ // set the first bit 0 in each frame
+ assert( p->nWordsFrame * p->nFrames == p->nWordsTotal );
+ for ( f = 0; f < p->nFrames; f++ )
+ pSims[p->nWordsFrame*f] <<= 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns random patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignRandomFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims;
+ int i;
+ assert( iFrame < p->nFrames );
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = Ssw_ObjRandomSim();
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame )
+{
+ unsigned * pSims;
+ int i;
+ assert( iFrame < p->nFrames );
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = fConst1? ~(unsigned)0 : 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlObjAssignConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame, int iWord )
+{
+ unsigned * pSims;
+ assert( iFrame < p->nFrames );
+ assert( iWord < p->nWordsFrame );
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ pSims[iWord] = fConst1? ~(unsigned)0 : 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame )
+{
+ unsigned * pSims;
+ assert( iFrame < p->nFrames );
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ pSims[iWord] = Word;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings distance-1 simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignDist1( Ssw_Sml_t * p, unsigned * pPat )
+{
+ Aig_Obj_t * pObj;
+ int f, i, k, Limit, nTruePis;
+ assert( p->nFrames > 0 );
+ if ( p->nFrames == 1 )
+ {
+ // copy the PI info
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Abc_InfoHasBit(pPat, i), 0 );
+ // flip one bit
+ Limit = Abc_MinInt( Aig_ManPiNum(p->pAig), p->nWordsTotal * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Abc_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 );
+ }
+ else
+ {
+ int fUseDist1 = 0;
+
+ // copy the PI info for each frame
+ nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig);
+ for ( f = 0; f < p->nFrames; f++ )
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Abc_InfoHasBit(pPat, nTruePis * f + i), f );
+ // copy the latch info
+ k = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Abc_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 );
+// assert( p->pFrames == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pFrames) );
+
+ // flip one bit of the last frame
+ if ( fUseDist1 ) //&& p->nFrames == 2 )
+ {
+ Limit = Abc_MinInt( nTruePis, p->nWordsFrame * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Abc_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ) + p->nWordsFrame*(p->nFrames-1), i+1 );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings distance-1 simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat )
+{
+ Aig_Obj_t * pObj;
+ int f, i, Limit;
+ assert( p->nFrames > 0 );
+
+ // copy the pattern into the primary inputs
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Abc_InfoHasBit(pPat, i), 0 );
+
+ // set distance one PIs for the first frame
+ Limit = Abc_MinInt( Saig_ManPiNum(p->pAig), p->nWordsFrame * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Abc_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 );
+
+ // create random info for the remaining timeframes
+ for ( f = 1; f < p->nFrames; f++ )
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandomFrame( p, pObj, f );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeSimulate( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims, * pSims0, * pSims1;
+ int fCompl, fCompl0, fCompl1, i;
+ assert( iFrame < p->nFrames );
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsNode(pObj) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
+ pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
+ pSims1 = Ssw_ObjSim(p, Aig_ObjFanin1(pObj)->Id) + p->nWordsFrame * iFrame;
+ // get complemented attributes of the children using their random info
+ fCompl = pObj->fPhase;
+ fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
+ fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj));
+ // simulate
+ if ( fCompl0 && fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] | pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~(pSims0[i] | pSims1[i]);
+ }
+ else if ( fCompl0 && !fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] | ~pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (~pSims0[i] & pSims1[i]);
+ }
+ else if ( !fCompl0 && fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (~pSims0[i] | pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] & ~pSims1[i]);
+ }
+ else // if ( !fCompl0 && !fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~(pSims0[i] & pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] & pSims1[i]);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodesCompareInFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int iFrame0, int iFrame1 )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ assert( iFrame0 < p->nFrames );
+ assert( iFrame1 < p->nFrames );
+ assert( !Aig_IsComplement(pObj0) );
+ assert( !Aig_IsComplement(pObj1) );
+ assert( iFrame0 == 0 || p->nWordsFrame < p->nWordsTotal );
+ assert( iFrame1 == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims0 = Ssw_ObjSim(p, pObj0->Id) + p->nWordsFrame * iFrame0;
+ pSims1 = Ssw_ObjSim(p, pObj1->Id) + p->nWordsFrame * iFrame1;
+ // compare
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ if ( pSims0[i] != pSims1[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeCopyFanin( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims, * pSims0;
+ int fCompl, fCompl0, i;
+ assert( iFrame < p->nFrames );
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsPo(pObj) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
+ pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
+ // get complemented attributes of the children using their random info
+ fCompl = pObj->fPhase;
+ fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
+ // copy information as it is
+ if ( fCompl0 )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~pSims0[i];
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = pSims0[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeTransferNext( Ssw_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ assert( iFrame < p->nFrames );
+ assert( !Aig_IsComplement(pOut) );
+ assert( !Aig_IsComplement(pIn) );
+ assert( Aig_ObjIsPo(pOut) );
+ assert( Aig_ObjIsPi(pIn) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims0 = Ssw_ObjSim(p, pOut->Id) + p->nWordsFrame * iFrame;
+ pSims1 = Ssw_ObjSim(p, pIn->Id) + p->nWordsFrame * (iFrame+1);
+ // copy information as it is
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims1[i] = pSims0[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeTransferFirst( Ssw_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ assert( !Aig_IsComplement(pOut) );
+ assert( !Aig_IsComplement(pIn) );
+ assert( Aig_ObjIsPo(pOut) );
+ assert( Aig_ObjIsPi(pIn) );
+ assert( p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims0 = Ssw_ObjSim(p, pOut->Id) + p->nWordsFrame * (p->nFrames-1);
+ pSims1 = Ssw_ObjSim(p, pIn->Id);
+ // copy information as it is
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims1[i] = pSims0[i];
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Assings random simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlInitialize( Ssw_Sml_t * p, int fInit )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ if ( fInit )
+ {
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) <= Aig_ManPiNum(p->pAig) );
+ // assign random info for primary inputs
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ // assign the initial state for the latches
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, 0, 0 );
+ }
+ else
+ {
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings random simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlInitializeSpecial( Ssw_Sml_t * p, Vec_Int_t * vInit )
+{
+ Aig_Obj_t * pObj;
+ int Entry, i, nRegs;
+ nRegs = Aig_ManRegNum(p->pAig);
+ assert( nRegs > 0 );
+ assert( nRegs <= Aig_ManPiNum(p->pAig) );
+ assert( Vec_IntSize(vInit) == nRegs * p->nWordsFrame );
+ // assign random info for primary inputs
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ // assign the initial state for the latches
+ Vec_IntForEachEntry( vInit, Entry, i )
+ Ssw_SmlObjAssignConstWord( p, Saig_ManLo(p->pAig, i % nRegs), Entry, 0, i / nRegs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings random simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlReinitialize( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i;
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ // assign random info for primary inputs
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ // copy simulation info into the inputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_SmlNodeTransferFirst( p, pObjLi, pObjLo );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check if any of the POs becomes non-constant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlCheckNonConstOutputs( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( p->pAig->nConstrs && i >= Saig_ManPoNum(p->pAig) - p->pAig->nConstrs )
+ return 0;
+ if ( !Ssw_SmlNodeIsZero(p, pObj) )
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates AIG manager.]
+
+ Description [Assumes that the PI simulation info is attached.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSimulateOne( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int f, i, clk;
+clk = clock();
+ for ( f = 0; f < p->nFrames; f++ )
+ {
+ // simulate the nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ Ssw_SmlNodeSimulate( p, pObj, f );
+ // copy simulation info into outputs
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, f );
+ // copy simulation info into outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, f );
+ // quit if this is the last timeframe
+ if ( f == p->nFrames - 1 )
+ break;
+ // copy simulation info into the inputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, f );
+ }
+p->timeSim += clock() - clk;
+p->nSimRounds++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts simulation information to be not normallized.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlUnnormalize( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pSims;
+ int i, k;
+ // convert constant 1
+ pSims = Ssw_ObjSim( p, 0 );
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~pSims[i];
+ // convert internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, k )
+ {
+ if ( pObj->fPhase == 0 )
+ continue;
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~pSims[i];
+ }
+ // PIs/POs are always stored in their natural state
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates AIG manager.]
+
+ Description [Assumes that the PI simulation info is attached.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSimulateOneDyn_rec( Ssw_Sml_t * p, Aig_Obj_t * pObj, int f, int * pVisited, int nVisCounter )
+{
+// if ( Aig_ObjIsTravIdCurrent(p->pAig, pObj) )
+// return;
+// Aig_ObjSetTravIdCurrent(p->pAig, pObj);
+ if ( pVisited[p->nFrames*pObj->Id+f] == nVisCounter )
+ return;
+ pVisited[p->nFrames*pObj->Id+f] = nVisCounter;
+ if ( Saig_ObjIsPi( p->pAig, pObj ) || Aig_ObjIsConst1(pObj) )
+ return;
+ if ( Saig_ObjIsLo( p->pAig, pObj ) )
+ {
+ if ( f == 0 )
+ return;
+ Ssw_SmlSimulateOneDyn_rec( p, Saig_ObjLoToLi(p->pAig, pObj), f-1, pVisited, nVisCounter );
+ Ssw_SmlNodeTransferNext( p, Saig_ObjLoToLi(p->pAig, pObj), pObj, f-1 );
+ return;
+ }
+ if ( Saig_ObjIsLi( p->pAig, pObj ) )
+ {
+ Ssw_SmlSimulateOneDyn_rec( p, Aig_ObjFanin0(pObj), f, pVisited, nVisCounter );
+ Ssw_SmlNodeCopyFanin( p, pObj, f );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_SmlSimulateOneDyn_rec( p, Aig_ObjFanin0(pObj), f, pVisited, nVisCounter );
+ Ssw_SmlSimulateOneDyn_rec( p, Aig_ObjFanin1(pObj), f, pVisited, nVisCounter );
+ Ssw_SmlNodeSimulate( p, pObj, f );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates AIG manager.]
+
+ Description [Assumes that the PI simulation info is attached.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, clk;
+clk = clock();
+ // simulate the nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ Ssw_SmlNodeSimulate( p, pObj, 0 );
+ // copy simulation info into outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, 0 );
+ // copy simulation info into the inputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, 0 );
+p->timeSim += clock() - clk;
+p->nSimRounds++;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame )
+{
+ Ssw_Sml_t * p;
+ p = (Ssw_Sml_t *)ABC_ALLOC( char, sizeof(Ssw_Sml_t) + sizeof(unsigned) * Aig_ManObjNumMax(pAig) * (nPref + nFrames) * nWordsFrame );
+ memset( p, 0, sizeof(Ssw_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame );
+ p->pAig = pAig;
+ p->nPref = nPref;
+ p->nFrames = nPref + nFrames;
+ p->nWordsFrame = nWordsFrame;
+ p->nWordsTotal = (nPref + nFrames) * nWordsFrame;
+ p->nWordsPref = nPref * nWordsFrame;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlClean( Ssw_Sml_t * p )
+{
+ memset( p->pData, 0, sizeof(unsigned) * Aig_ManObjNumMax(p->pAig) * p->nWordsTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Get simulation data.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Ssw_SmlSimDataPointers( Ssw_Sml_t * p )
+{
+ Vec_Ptr_t * vSimInfo;
+ Aig_Obj_t * pObj;
+ int i;
+ vSimInfo = Vec_PtrStart( Aig_ManObjNumMax(p->pAig) );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ Vec_PtrWriteEntry( vSimInfo, i, Ssw_ObjSim(p, i) );
+ return vSimInfo;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlStop( Ssw_Sml_t * p )
+{
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs simulation of the uninitialized circuit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords )
+{
+ Ssw_Sml_t * p;
+ p = Ssw_SmlStart( pAig, 0, 1, nWords );
+ Ssw_SmlInitialize( p, 0 );
+ Ssw_SmlSimulateOne( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs simulation of the initialized circuit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords )
+{
+ Ssw_Sml_t * p;
+ p = Ssw_SmlStart( pAig, nPref, nFrames, nWords );
+ Ssw_SmlInitialize( p, 1 );
+ Ssw_SmlSimulateOne( p );
+ p->fNonConstOut = Ssw_SmlCheckNonConstOutputs( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs next round of sequential simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlResimulateSeq( Ssw_Sml_t * p )
+{
+ Ssw_SmlReinitialize( p );
+ Ssw_SmlSimulateOne( p );
+ p->fNonConstOut = Ssw_SmlCheckNonConstOutputs( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of frames simulated in the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNumFrames( Ssw_Sml_t * p )
+{
+ return p->nFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the total number of simulation words.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNumWordsTotal( Ssw_Sml_t * p )
+{
+ return p->nWordsTotal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the pointer to the simulation info of the node.]
+
+ Description [The simulation info is normalized unless procedure
+ Ssw_SmlUnnormalize() is called in advance.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ return Ssw_ObjSim( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates sequential counter-example from the simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p )
+{
+ Abc_Cex_t * pCex;
+ Aig_Obj_t * pObj;
+ unsigned * pSims;
+ int iPo, iFrame, iBit, i, k;
+
+ // make sure the simulation manager has it
+ assert( p->fNonConstOut );
+
+ // find the first output that failed
+ iPo = -1;
+ iBit = -1;
+ iFrame = -1;
+ Saig_ManForEachPo( p->pAig, pObj, iPo )
+ {
+ if ( Ssw_SmlNodeIsZero(p, pObj) )
+ continue;
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ {
+ iFrame = i / p->nWordsFrame;
+ iBit = 32 * (i % p->nWordsFrame) + Aig_WordFindFirstBit( pSims[i] );
+ break;
+ }
+ break;
+ }
+ assert( iPo < Aig_ManPoNum(p->pAig)-Aig_ManRegNum(p->pAig) );
+ assert( iFrame < p->nFrames );
+ assert( iBit < 32 * p->nWordsFrame );
+
+ // allocate the counter example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = iFrame;
+
+ // copy the bit data
+ Saig_ManForEachLo( p->pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ if ( Abc_InfoHasBit( pSims, iBit ) )
+ Abc_InfoSetBit( pCex->pData, k );
+ }
+ for ( i = 0; i <= iFrame; i++ )
+ {
+ Saig_ManForEachPi( p->pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ if ( Abc_InfoHasBit( pSims, 32 * p->nWordsFrame * i + iBit ) )
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * i + k );
+ }
+ }
+ // verify the counter example
+ if ( !Saig_ManVerifyCex( p->pAig, pCex ) )
+ {
+ printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" );
+ Abc_CexFree( pCex );
+ pCex = NULL;
+ }
+ return pCex;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswSimSat.c b/src/proof/ssw/sswSimSat.c
new file mode 100644
index 00000000..4c094a2d
--- /dev/null
+++ b/src/proof/ssw/sswSimSat.c
@@ -0,0 +1,123 @@
+/**CFile****************************************************************
+
+ FileName [sswSimSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Performs resimulation using counter-examples.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSimSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Handle the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t * pObj;
+ int i, RetValue1, RetValue2, clk = clock();
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = Abc_InfoHasBit( p->pPatWords, i );
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // if repr is given, perform refinement
+ if ( pRepr )
+ {
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
+ // make sure refinement happened
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ assert( RetValue1 );
+ if ( RetValue1 == 0 )
+ printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" );
+ }
+ else
+ {
+ assert( RetValue2 );
+ if ( RetValue2 == 0 )
+ printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" );
+ }
+ }
+p->timeSimSat += clock() - clk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Handle the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // set the PI simulation information
+ Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
+ // simulate internal nodes
+ Ssw_SmlSimulateOne( p->pSml );
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // make sure refinement happened
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ assert( RetValue1 );
+ if ( RetValue1 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" );
+ }
+ else
+ {
+ assert( RetValue2 );
+ if ( RetValue2 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" );
+ }
+p->timeSimSat += clock() - clk;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswSweep.c b/src/proof/ssw/sswSweep.c
new file mode 100644
index 00000000..e2a4f65d
--- /dev/null
+++ b/src/proof/ssw/sswSweep.c
@@ -0,0 +1,435 @@
+/**CFile****************************************************************
+
+ FileName [sswSweep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [One round of SAT sweeping.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSweep.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "src/misc/bar/bar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Retrives value of the PI in the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ int fUseNoBoundary = 0;
+ Aig_Obj_t * pObjFraig;
+ int Value;
+// assert( Aig_ObjIsPi(pObj) );
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ if ( fUseNoBoundary )
+ {
+ Value = Ssw_CnfGetNodeValue( p->pMSat, Aig_Regular(pObjFraig) );
+ Value ^= Aig_IsComplement(pObjFraig);
+ }
+ else
+ {
+ int nVarNum = Ssw_ObjSatNum( p->pMSat, Aig_Regular(pObjFraig) );
+ Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pMSat->pSat, nVarNum ));
+ }
+
+// Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum )));
+// Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pObjFraig)->fPhase ) Value ^= 1;
+ }
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CheckConstraints( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObj2;
+ int nConstrPairs, i;
+ int Counter = 0;
+ nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
+ assert( (nConstrPairs & 1) == 0 );
+ for ( i = 0; i < nConstrPairs; i += 2 )
+ {
+ pObj = Aig_ManPo( p->pFrames, i );
+ pObj2 = Aig_ManPo( p->pFrames, i+1 );
+ if ( Ssw_NodesAreEquiv( p, Aig_ObjFanin0(pObj), Aig_ObjFanin0(pObj2) ) != 1 )
+ {
+ Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
+ Counter++;
+ }
+ }
+ printf( "Total constraints = %d. Added constraints = %d.\n", nConstrPairs/2, Counter );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePatternAigPhase( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ if ( Aig_ObjPhaseReal( Ssw_ObjFrame(p, pObj, f) ) )
+ Abc_InfoSetBit( p->pPatWords, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
+ Abc_InfoSetBit( p->pPatWords, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves one counter-example into internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAddPatternDyn( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pInfo;
+ int i, nVarNum;
+ // iterate through the PIs of the frames
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i )
+ {
+ assert( Aig_ObjIsPi(pObj) );
+ nVarNum = Ssw_ObjSatNum( p->pMSat, pObj );
+ assert( nVarNum > 0 );
+ if ( sat_solver_var_value( p->pMSat->pSat, nVarNum ) )
+ {
+ pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
+ Abc_InfoSetBit( pInfo, p->nPatterns );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc, Vec_Int_t * vPairs )
+{
+ Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
+ int RetValue, clk;
+ // get representative of this class
+ pObjRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pObjRepr == NULL )
+ return 0;
+ // get the fraiged node
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ // get the fraiged representative
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
+ // check if constant 0 pattern distinquishes these nodes
+ assert( pObjFraig != NULL && pObjReprFraig != NULL );
+ assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) );
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return 0;
+ // add constraints on demand
+ if ( !fBmc && p->pPars->fDynamic )
+ {
+clk = clock();
+ Ssw_ManLoadSolver( p, pObjRepr, pObj );
+ p->nRecycleCalls++;
+p->timeMarkCones += clock() - clk;
+ }
+ // call equivalence checking
+ if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ else
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
+ if ( RetValue == 1 ) // proved equivalent
+ {
+ pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
+ Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
+ return 0;
+ }
+ if ( vPairs )
+ {
+ Vec_IntPush( vPairs, pObjRepr->Id );
+ Vec_IntPush( vPairs, pObj->Id );
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+ Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ return 1;
+ }
+ // disproved the equivalence
+ if ( !fBmc && p->pPars->fDynamic )
+ {
+ Ssw_SmlAddPatternDyn( p );
+ p->nPatterns++;
+ return 1;
+ }
+ else
+ Ssw_SmlSavePatternAig( p, f );
+ if ( !p->pPars->fConstrs )
+ Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
+ else
+ Ssw_ManResimulateBit( p, pObj, pObjRepr );
+ assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
+ if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
+ {
+ printf( "Ssw_ManSweepNode(): Failed to refine representative.\n" );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepBmc( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ int i, f, clk;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 1, NULL );
+ }
+ // quit if this is the last timeframe
+ if ( f == p->pPars->nFramesK - 1 )
+ break;
+ // transfer latch input to the latch outputs
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjFrame( p, pObjLi, f );
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
+ }
+ }
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return p->fRefined;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Generates AIG with the following nodes put into seq miters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManDumpEquivMiter( Aig_Man_t * p, Vec_Int_t * vPairs, int Num )
+{
+ FILE * pFile;
+ char pBuffer[16];
+ Aig_Man_t * pNew;
+ sprintf( pBuffer, "equiv%03d.aig", Num );
+ pFile = fopen( pBuffer, "w" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file %s for writing.\n", pBuffer );
+ return;
+ }
+ fclose( pFile );
+ pNew = Saig_ManCreateEquivMiter( p, vPairs );
+ Ioa_WriteAiger( pNew, pBuffer, 0, 0 );
+ Aig_ManStop( pNew );
+ printf( "AIG with %4d disproved equivs is dumped into file \"%s\".\n", Vec_IntSize(vPairs)/2, pBuffer );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweep( Ssw_Man_t * p )
+{
+ static int Counter;
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObj2, * pObjNew;
+ int nConstrPairs, clk, i, f;
+ Vec_Int_t * vDisproved;
+
+ // perform speculative reduction
+clk = clock();
+ // create timeframes
+ p->pFrames = Ssw_FramesWithClasses( p );
+ // add constants
+ nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
+ assert( (nConstrPairs & 1) == 0 );
+ for ( i = 0; i < nConstrPairs; i += 2 )
+ {
+ pObj = Aig_ManPo( p->pFrames, i );
+ pObj2 = Aig_ManPo( p->pFrames, i+1 );
+ Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
+ }
+ // build logic cones for register inputs
+ for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
+ {
+ pObj = Aig_ManPo( p->pFrames, nConstrPairs + i );
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pObj) );//
+ }
+ sat_solver_simplify( p->pMSat->pSat );
+
+ // map constants and PIs of the last frame
+ f = p->pPars->nFramesK;
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+p->timeReduce += clock() - clk;
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ Ssw_ClassesClearRefined( p->ppClasses );
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
+ vDisproved = p->pPars->fEquivDump? Vec_IntAlloc(1000) : NULL;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, i, NULL );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, vDisproved );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, vDisproved );
+ }
+ }
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ if ( p->pPars->fEquivDump )
+ Ssw_ManDumpEquivMiter( p->pAig, vDisproved, Counter++ );
+ Vec_IntFreeP( &vDisproved );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/ssw/sswUnique.c b/src/proof/ssw/sswUnique.c
new file mode 100644
index 00000000..b5f6a853
--- /dev/null
+++ b/src/proof/ssw/sswUnique.c
@@ -0,0 +1,197 @@
+/**CFile****************************************************************
+
+ FileName [sswSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [On-demand uniqueness constraints.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of signal correspondence with constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_UniqueRegisterPairInfo( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObjLo, * pObj0, * pObj1;
+ int i, RetValue, Counter;
+ if ( p->vDiffPairs == NULL )
+ p->vDiffPairs = Vec_IntAlloc( Saig_ManRegNum(p->pAig) );
+ Vec_IntClear( p->vDiffPairs );
+ Saig_ManForEachLo( p->pAig, pObjLo, i )
+ {
+ pObj0 = Ssw_ObjFrame( p, pObjLo, 0 );
+ pObj1 = Ssw_ObjFrame( p, pObjLo, 1 );
+ if ( pObj0 == pObj1 )
+ Vec_IntPush( p->vDiffPairs, 0 );
+ else if ( pObj0 == Aig_Not(pObj1) )
+ Vec_IntPush( p->vDiffPairs, 1 );
+// else
+// Vec_IntPush( p->vDiffPairs, 1 );
+ else if ( Aig_ObjPhaseReal(pObj0) != Aig_ObjPhaseReal(pObj1) )
+ Vec_IntPush( p->vDiffPairs, 1 );
+ else
+ {
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObj0), Aig_Regular(pObj1) );
+ Vec_IntPush( p->vDiffPairs, RetValue!=1 );
+ }
+ }
+ assert( Vec_IntSize(p->vDiffPairs) == Saig_ManRegNum(p->pAig) );
+ // count the number of ones
+ Counter = 0;
+ Vec_IntForEachEntry( p->vDiffPairs, RetValue, i )
+ Counter += RetValue;
+// printf( "The number of different register pairs = %d.\n", Counter );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if uniqueness constraints can be added.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj, int fVerbose )
+{
+ Aig_Obj_t * ppObjs[2], * pTemp;
+ int i, k, Value0, Value1, RetValue, fFeasible;
+
+ assert( p->pPars->nFramesK > 1 );
+ assert( p->vDiffPairs && Vec_IntSize(p->vDiffPairs) == Saig_ManRegNum(p->pAig) );
+
+ // compute the first support in terms of LOs
+ ppObjs[0] = pRepr;
+ ppObjs[1] = pObj;
+ Aig_SupportNodes( p->pAig, ppObjs, 2, p->vCommon );
+ // keep only LOs
+ RetValue = Vec_PtrSize( p->vCommon );
+ fFeasible = 0;
+ k = 0;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vCommon, pTemp, i )
+ {
+ assert( Aig_ObjIsPi(pTemp) );
+ if ( !Saig_ObjIsLo(p->pAig, pTemp) )
+ continue;
+ assert( Aig_ObjPioNum(pTemp) > 0 );
+ Vec_PtrWriteEntry( p->vCommon, k++, pTemp );
+ if ( Vec_IntEntry(p->vDiffPairs, Aig_ObjPioNum(pTemp) - Saig_ManPiNum(p->pAig)) )
+ fFeasible = 1;
+ }
+ Vec_PtrShrink( p->vCommon, k );
+
+ if ( fVerbose )
+ printf( "Node = %5d : Supp = %3d. Regs = %3d. Feasible = %s. ",
+ Aig_ObjId(pObj), RetValue, Vec_PtrSize(p->vCommon),
+ fFeasible? "yes": "no " );
+
+ // check the current values
+ RetValue = 1;
+ Vec_PtrForEachEntry( Aig_Obj_t *, p->vCommon, pTemp, i )
+ {
+ Value0 = Ssw_ManGetSatVarValue( p, pTemp, 0 );
+ Value1 = Ssw_ManGetSatVarValue( p, pTemp, 1 );
+ if ( Value0 != Value1 )
+ RetValue = 0;
+ if ( fVerbose )
+ printf( "%d", Value0 ^ Value1 );
+ }
+ if ( fVerbose )
+ printf( "\n" );
+
+ return RetValue && fFeasible;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the output of the uniqueness constraint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 )
+{
+ Aig_Obj_t * pObj, * pObj1New, * pObj2New, * pMiter, * pTotal;
+ int i, pLits[2];
+// int RetValue;
+ assert( Vec_PtrSize(vCommon) > 0 );
+ // generate the constraint
+ pTotal = Aig_ManConst0(p->pFrames);
+ Vec_PtrForEachEntry( Aig_Obj_t *, vCommon, pObj, i )
+ {
+ assert( Saig_ObjIsLo(p->pAig, pObj) );
+ pObj1New = Ssw_ObjFrame( p, pObj, f1 );
+ pObj2New = Ssw_ObjFrame( p, pObj, f2 );
+ pMiter = Aig_Exor( p->pFrames, pObj1New, pObj2New );
+ pTotal = Aig_Or( p->pFrames, pTotal, pMiter );
+ }
+ if ( Aig_ObjIsConst1(Aig_Regular(pTotal)) )
+ {
+// printf( "Skipped\n" );
+ return 0;
+ }
+ // create CNF
+ Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pTotal) );
+ // add output constraint
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) );
+/*
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
+ assert( RetValue );
+ // simplify the solver
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pSat);
+ assert( RetValue != 0 );
+ }
+*/
+ assert( p->iOutputLit == -1 );
+ p->iOutputLit = pLits[0];
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+