diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
commit | 8014f25f6db719fa62336f997963532a14c568f6 (patch) | |
tree | c691ee91a3a2d452a2bd24ac89a8c717beaa7af7 /src/proof/ssw | |
parent | c44cc5de9429e6b4f1c05045fcf43c9cb96437b5 (diff) | |
download | abc-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.make | 20 | ||||
-rw-r--r-- | src/proof/ssw/ssw.h | 142 | ||||
-rw-r--r-- | src/proof/ssw/sswAig.c | 259 | ||||
-rw-r--r-- | src/proof/ssw/sswBmc.c | 224 | ||||
-rw-r--r-- | src/proof/ssw/sswClass.c | 1170 | ||||
-rw-r--r-- | src/proof/ssw/sswCnf.c | 428 | ||||
-rw-r--r-- | src/proof/ssw/sswConstr.c | 714 | ||||
-rw-r--r-- | src/proof/ssw/sswCore.c | 522 | ||||
-rw-r--r-- | src/proof/ssw/sswDyn.c | 489 | ||||
-rw-r--r-- | src/proof/ssw/sswFilter.c | 493 | ||||
-rw-r--r-- | src/proof/ssw/sswInt.h | 302 | ||||
-rw-r--r-- | src/proof/ssw/sswIslands.c | 598 | ||||
-rw-r--r-- | src/proof/ssw/sswLcorr.c | 336 | ||||
-rw-r--r-- | src/proof/ssw/sswMan.c | 218 | ||||
-rw-r--r-- | src/proof/ssw/sswPairs.c | 477 | ||||
-rw-r--r-- | src/proof/ssw/sswPart.c | 141 | ||||
-rw-r--r-- | src/proof/ssw/sswRarity.c | 1158 | ||||
-rw-r--r-- | src/proof/ssw/sswRarity2.c | 517 | ||||
-rw-r--r-- | src/proof/ssw/sswSat.c | 306 | ||||
-rw-r--r-- | src/proof/ssw/sswSemi.c | 322 | ||||
-rw-r--r-- | src/proof/ssw/sswSim.c | 1405 | ||||
-rw-r--r-- | src/proof/ssw/sswSimSat.c | 123 | ||||
-rw-r--r-- | src/proof/ssw/sswSweep.c | 435 | ||||
-rw-r--r-- | src/proof/ssw/sswUnique.c | 197 |
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 + |