From 69bbfa98564efc7a8b865f06b01c0e404ac1e658 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 15 Sep 2012 23:27:46 -0700 Subject: Created new abstraction package from the code that was all over the place. --- src/aig/gia/gia.h | 61 -- src/aig/gia/giaAbs.c | 746 ----------------- src/aig/gia/giaAbs.h | 89 -- src/aig/gia/giaAbsGla.c | 1958 ------------------------------------------- src/aig/gia/giaAbsGla2.c | 1899 ----------------------------------------- src/aig/gia/giaAbsIter.c | 149 ---- src/aig/gia/giaAbsOut.c | 461 ---------- src/aig/gia/giaAbsPth.c | 199 ----- src/aig/gia/giaAbsRef.c | 1001 ---------------------- src/aig/gia/giaAbsRef.h | 67 -- src/aig/gia/giaAbsRef2.c | 916 -------------------- src/aig/gia/giaAbsRef2.h | 67 -- src/aig/gia/giaAbsVta.c | 1799 --------------------------------------- src/aig/gia/giaDup.c | 257 ------ src/aig/gia/giaMan.c | 150 +--- src/aig/gia/module.make | 9 - src/aig/saig/module.make | 13 +- src/aig/saig/saig.h | 26 - src/aig/saig/saigAbs.c | 133 --- src/aig/saig/saigAbsCba.c | 874 ------------------- src/aig/saig/saigAbsPba.c | 374 --------- src/aig/saig/saigAbsStart.c | 310 ------- src/aig/saig/saigAbsVfa.c | 329 -------- src/aig/saig/saigSimExt.c | 556 ------------ src/aig/saig/saigSimExt2.c | 481 ----------- src/base/abci/abc.c | 482 +---------- src/base/io/io.c | 1 + src/opt/nwk/nwkAig.c | 2 +- src/proof/abs/abs.c | 52 ++ src/proof/abs/abs.h | 131 +++ src/proof/abs/absDup.c | 445 ++++++++++ src/proof/abs/absGla.c | 1899 +++++++++++++++++++++++++++++++++++++++++ src/proof/abs/absGlaOld.c | 1957 ++++++++++++++++++++++++++++++++++++++++++ src/proof/abs/absIter.c | 147 ++++ src/proof/abs/absOldCex.c | 872 +++++++++++++++++++ src/proof/abs/absOldRef.c | 369 ++++++++ src/proof/abs/absOldSat.c | 986 ++++++++++++++++++++++ src/proof/abs/absOldSim.c | 477 +++++++++++ src/proof/abs/absOut.c | 458 ++++++++++ src/proof/abs/absPth.c | 199 +++++ src/proof/abs/absRef.c | 1001 ++++++++++++++++++++++ src/proof/abs/absRef.h | 67 ++ src/proof/abs/absRef2.c | 916 ++++++++++++++++++++ src/proof/abs/absRef2.h | 67 ++ src/proof/abs/absUtil.c | 257 ++++++ src/proof/abs/absVta.c | 1765 ++++++++++++++++++++++++++++++++++++++ src/proof/abs/module.make | 15 + 47 files changed, 12096 insertions(+), 13393 deletions(-) delete mode 100644 src/aig/gia/giaAbs.c delete mode 100644 src/aig/gia/giaAbs.h delete mode 100644 src/aig/gia/giaAbsGla.c delete mode 100644 src/aig/gia/giaAbsGla2.c delete mode 100644 src/aig/gia/giaAbsIter.c delete mode 100644 src/aig/gia/giaAbsOut.c delete mode 100644 src/aig/gia/giaAbsPth.c delete mode 100644 src/aig/gia/giaAbsRef.c delete mode 100644 src/aig/gia/giaAbsRef.h delete mode 100644 src/aig/gia/giaAbsRef2.c delete mode 100644 src/aig/gia/giaAbsRef2.h delete mode 100644 src/aig/gia/giaAbsVta.c delete mode 100644 src/aig/saig/saigAbs.c delete mode 100644 src/aig/saig/saigAbsCba.c delete mode 100644 src/aig/saig/saigAbsPba.c delete mode 100644 src/aig/saig/saigAbsStart.c delete mode 100644 src/aig/saig/saigAbsVfa.c delete mode 100644 src/aig/saig/saigSimExt.c delete mode 100644 src/aig/saig/saigSimExt2.c create mode 100644 src/proof/abs/abs.c create mode 100644 src/proof/abs/abs.h create mode 100644 src/proof/abs/absDup.c create mode 100644 src/proof/abs/absGla.c create mode 100644 src/proof/abs/absGlaOld.c create mode 100644 src/proof/abs/absIter.c create mode 100644 src/proof/abs/absOldCex.c create mode 100644 src/proof/abs/absOldRef.c create mode 100644 src/proof/abs/absOldSat.c create mode 100644 src/proof/abs/absOldSim.c create mode 100644 src/proof/abs/absOut.c create mode 100644 src/proof/abs/absPth.c create mode 100644 src/proof/abs/absRef.c create mode 100644 src/proof/abs/absRef.h create mode 100644 src/proof/abs/absRef2.c create mode 100644 src/proof/abs/absRef2.h create mode 100644 src/proof/abs/absUtil.c create mode 100644 src/proof/abs/absVta.c create mode 100644 src/proof/abs/module.make (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index a00b7111..7670445a 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -33,17 +33,14 @@ #include "misc/vec/vec.h" #include "misc/util/utilCex.h" -#include "giaAbs.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// - ABC_NAMESPACE_HEADER_START - #define GIA_NONE 0x1FFFFFFF #define GIA_VOID 0x0FFFFFFF @@ -208,41 +205,6 @@ struct Gia_ParSim_t_ int iOutFail; // index of the failed output }; -// abstraction parameters -typedef struct Gia_ParVta_t_ Gia_ParVta_t; -struct Gia_ParVta_t_ -{ - int nFramesMax; // maximum frames - int nFramesStart; // starting frame - int nFramesPast; // overlap frames - int nConfLimit; // conflict limit - int nLearnedMax; // max number of learned clauses - int nLearnedStart; // max number of learned clauses - int nLearnedDelta; // delta increase of learned clauses - int nLearnedPerce; // percentage of clauses to leave - int nTimeOut; // timeout in seconds - int nRatioMin; // stop when less than this % of object is abstracted - int nRatioMax; // restart when the number of abstracted object is more than this - int fUseTermVars; // use terminal variables - int fUseRollback; // use rollback to the starting number of frames - int fPropFanout; // propagate fanout implications - int fAddLayer; // refinement strategy by adding layers - int fUseSkip; // skip proving intermediate timeframes - int fUseSimple; // use simple CNF construction - int fSkipHash; // skip hashing CNF while unrolling - int fUseFullProof; // use full proof for UNSAT cores - int fDumpVabs; // dumps the abstracted model - int fDumpMabs; // dumps the original AIG with abstraction map - int fCallProver; // calls the prover - char * pFileVabs; // dumps the abstracted model into this file - int fVerbose; // verbose flag - int fVeryVerbose; // print additional information - int iFrame; // the number of frames covered - int iFrameProved; // the number of frames proved - int nFramesNoChange; // the number of last frames without changes - int nFramesNoChangeLim; // the number of last frames without changes to dump abstraction -}; - static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); } static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; } static inline int Gia_WordHasOnePair( unsigned uWord ) { return Gia_WordHasOneBit(uWord & (uWord>>1) & 0x55555555); } @@ -717,26 +679,6 @@ static inline int Gia_ObjLutFanin( Gia_Man_t * p, int Id, int i ) { re /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== giaAbs.c ===========================================================*/ -extern void Gia_ManCexAbstractionStart( Gia_Man_t * p, Gia_ParAbs_t * pPars ); -Gia_Man_t * Gia_ManCexAbstractionDerive( Gia_Man_t * pGia ); -int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ); -extern int Gia_ManPbaPerform( Gia_Man_t * pGia, int nStart, int nFrames, int nConfLimit, int nTimeLimit, int fVerbose, int * piFrame ); -extern int Gia_ManCbaPerform( Gia_Man_t * pGia, void * pPars ); -extern int Gia_ManGlaCbaPerform( Gia_Man_t * pGia, void * pPars, int fNaiveCnf ); -extern int Gia_ManGlaPbaPerform( Gia_Man_t * pGia, void * pPars, int fNewSolver ); -extern Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta ); -extern Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames ); -extern Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla ); -extern Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla ); -extern int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla ); -extern int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla ); -/*=== giaAbsGla.c ===========================================================*/ -extern int Gia_GlaPerform( Gia_Man_t * p, Gia_ParVta_t * pPars, int fStartVta ); -extern int Ga2_ManPerform( Gia_Man_t * p, Gia_ParVta_t * pPars ); -/*=== giaAbsVta.c ===========================================================*/ -extern void Gia_VtaSetDefaultParams( Gia_ParVta_t * p ); -extern int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars ); /*=== giaAiger.c ===========================================================*/ extern int Gia_FileSize( char * pFileName ); extern Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipStrash, int fCheck ); @@ -800,9 +742,6 @@ extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, i extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes ); -extern Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses ); -extern Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses ); -extern void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes ); extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ); /*=== giaEnable.c ==========================================================*/ extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose ); diff --git a/src/aig/gia/giaAbs.c b/src/aig/gia/giaAbs.c deleted file mode 100644 index c5acfa2a..00000000 --- a/src/aig/gia/giaAbs.c +++ /dev/null @@ -1,746 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbs.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Counter-example-guided abstraction refinement.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAig.h" -#include "aig/saig/saig.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [This procedure sets default parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ) -{ - memset( p, 0, sizeof(Gia_ParAbs_t) ); - p->Algo = 0; // algorithm: CBA - p->nFramesMax = 10; // timeframes for PBA - p->nConfMax = 10000; // conflicts for PBA - p->fDynamic = 1; // dynamic unfolding for PBA - p->fConstr = 0; // use constraints - p->nFramesBmc = 250; // timeframes for BMC - p->nConfMaxBmc = 5000; // conflicts for BMC - p->nStableMax = 1000000; // the number of stable frames to quit - p->nRatio = 10; // ratio of flops to quit - p->nBobPar = 1000000; // the number of frames before trying to quit - p->fUseBdds = 0; // use BDDs to refine abstraction - p->fUseDprove = 0; // use 'dprove' to refine abstraction - p->fUseStart = 1; // use starting frame - p->fVerbose = 0; // verbose output - p->fVeryVerbose= 0; // printing additional information - p->Status = -1; // the problem status - p->nFramesDone = -1; // the number of rames covered -} - -/**Function************************************************************* - - Synopsis [Transform flop list into flop map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops ) -{ - Vec_Int_t * vFlopClasses; - int i, Entry; - vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) ); - Vec_IntForEachEntry( vFlops, Entry, i ) - Vec_IntWriteEntry( vFlopClasses, Entry, 1 ); - return vFlopClasses; -} - -/**Function************************************************************* - - Synopsis [Transform flop map into flop list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses ) -{ - Vec_Int_t * vFlops; - int i, Entry; - vFlops = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vFlopClasses, Entry, i ) - if ( Entry ) - Vec_IntPush( vFlops, i ); - return vFlops; -} - - -/**Function************************************************************* - - Synopsis [Starts abstraction by computing latch map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManCexAbstractionStart( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) -{ - Vec_Int_t * vFlops; - Aig_Man_t * pNew; - if ( pGia->vFlopClasses != NULL ) - { - printf( "Gia_ManCexAbstractionStart(): Abstraction latch map is present but will be rederived.\n" ); - Vec_IntFreeP( &pGia->vFlopClasses ); - } - pNew = Gia_ManToAig( pGia, 0 ); - vFlops = Saig_ManCexAbstractionFlops( pNew, pPars ); - pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; - Aig_ManStop( pNew ); - if ( vFlops ) - { - pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); - Vec_IntFree( vFlops ); - } -} - -/**Function************************************************************* - - Synopsis [Refines abstraction using the latch map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ) -{ - Aig_Man_t * pNew; - Vec_Int_t * vFlops; - if ( pGia->vFlopClasses == NULL ) - { - printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" ); - return -1; - } - pNew = Gia_ManToAig( pGia, 0 ); - vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); - if ( !Saig_ManCexRefineStep( pNew, vFlops, pGia->vFlopClasses, pCex, nFfToAddMax, fTryFour, fSensePath, fVerbose ) ) - { - pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; - Vec_IntFree( vFlops ); - Aig_ManStop( pNew ); - return 0; - } - Vec_IntFree( pGia->vFlopClasses ); - pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); - Vec_IntFree( vFlops ); - Aig_ManStop( pNew ); - return -1; -} - - - -/**Function************************************************************* - - Synopsis [Transform flop list into flop map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_ManFlopsSelect( Vec_Int_t * vFlops, Vec_Int_t * vFlopsNew ) -{ - Vec_Int_t * vSelected; - int i, Entry; - vSelected = Vec_IntAlloc( Vec_IntSize(vFlopsNew) ); - Vec_IntForEachEntry( vFlopsNew, Entry, i ) - Vec_IntPush( vSelected, Vec_IntEntry(vFlops, Entry) ); - return vSelected; -} - -/**Function************************************************************* - - Synopsis [Adds flops that should be present in the abstraction.] - - Description [The second argument (vAbsFfsToAdd) is the array of numbers - of previously abstrated flops (flops replaced by PIs in the abstracted model) - that should be present in the abstraction as real flops.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManFlopsAddToClasses( Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd ) -{ - Vec_Int_t * vMapEntries; - int i, Entry, iFlopNum; - // map previously abstracted flops into their original numbers - vMapEntries = Vec_IntAlloc( Vec_IntSize(vFlopClasses) ); - Vec_IntForEachEntry( vFlopClasses, Entry, i ) - if ( Entry == 0 ) - Vec_IntPush( vMapEntries, i ); - // add these flops as real flops - Vec_IntForEachEntry( vAbsFfsToAdd, Entry, i ) - { - iFlopNum = Vec_IntEntry( vMapEntries, Entry ); - assert( Vec_IntEntry( vFlopClasses, iFlopNum ) == 0 ); - Vec_IntWriteEntry( vFlopClasses, iFlopNum, 1 ); - } - Vec_IntFree( vMapEntries ); -} - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManCbaPerform( Gia_Man_t * pGia, void * pPars ) -{ - Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars; - Gia_Man_t * pAbs; - Aig_Man_t * pAig, * pOrig; - Vec_Int_t * vAbsFfsToAdd, * vAbsFfsToAddBest; - // check if flop classes are given - if ( pGia->vFlopClasses == NULL ) - { - Abc_Print( 0, "Initial flop map is not given. Trivial abstraction is assumed.\n" ); - pGia->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) ); - } - // derive abstraction - pAbs = Gia_ManDupAbsFlops( pGia, pGia->vFlopClasses ); - pAig = Gia_ManToAigSimple( pAbs ); - Gia_ManStop( pAbs ); - // refine abstraction using CBA - vAbsFfsToAdd = Saig_ManCbaPerform( pAig, Gia_ManPiNum(pGia), p ); - if ( vAbsFfsToAdd == NULL ) // found true CEX - { - assert( pAig->pSeqModel != NULL ); - printf( "Refinement did not happen. Discovered a true counter-example.\n" ); - printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManCiNum(pAig), Gia_ManPiNum(pGia) ); - // derive new counter-example - pOrig = Gia_ManToAigSimple( pGia ); - pGia->pCexSeq = Saig_ManCexRemap( pOrig, pAig, pAig->pSeqModel ); - Aig_ManStop( pOrig ); - Aig_ManStop( pAig ); - return 0; - } - // select the most useful flops among those to be added - if ( p->nFfToAddMax > 0 && Vec_IntSize(vAbsFfsToAdd) > p->nFfToAddMax ) - { - // compute new flops - Aig_Man_t * pAigBig = Gia_ManToAigSimple( pGia ); - vAbsFfsToAddBest = Saig_ManCbaFilterFlops( pAigBig, pAig->pSeqModel, pGia->vFlopClasses, vAbsFfsToAdd, p->nFfToAddMax ); - Aig_ManStop( pAigBig ); - assert( Vec_IntSize(vAbsFfsToAddBest) == p->nFfToAddMax ); - if ( p->fVerbose ) - printf( "Filtering flops based on cost (%d -> %d).\n", Vec_IntSize(vAbsFfsToAdd), Vec_IntSize(vAbsFfsToAddBest) ); - // update - Vec_IntFree( vAbsFfsToAdd ); - vAbsFfsToAdd = vAbsFfsToAddBest; - - } - Aig_ManStop( pAig ); - // update flop classes - Gia_ManFlopsAddToClasses( pGia->vFlopClasses, vAbsFfsToAdd ); - Vec_IntFree( vAbsFfsToAdd ); - if ( p->fVerbose ) - Gia_ManPrintStats( pGia, 0, 0 ); - return -1; -} - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManPbaPerform( Gia_Man_t * pGia, int nStart, int nFrames, int nConfLimit, int nTimeLimit, int fVerbose, int * piFrame ) -{ - Gia_Man_t * pAbs; - Aig_Man_t * pAig, * pOrig; - Vec_Int_t * vFlops, * vFlopsNew, * vSelected; - int RetValue; - if ( pGia->vFlopClasses == NULL ) - { - printf( "Gia_ManPbaPerform(): Abstraction flop map is missing.\n" ); - return 0; - } - // derive abstraction - pAbs = Gia_ManDupAbsFlops( pGia, pGia->vFlopClasses ); - // refine abstraction using PBA - pAig = Gia_ManToAigSimple( pAbs ); - Gia_ManStop( pAbs ); - vFlopsNew = Saig_ManPbaDerive( pAig, Gia_ManPiNum(pGia), nStart, nFrames, nConfLimit, nTimeLimit, fVerbose, piFrame ); - // derive new classes - if ( pAig->pSeqModel == NULL ) - { - // check if there is no timeout - if ( vFlopsNew != NULL ) - { - // the problem is UNSAT - vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); - vSelected = Gia_ManFlopsSelect( vFlops, vFlopsNew ); - Vec_IntFree( pGia->vFlopClasses ); - pGia->vFlopClasses = Saig_ManFlops2Classes( Gia_ManRegNum(pGia), vSelected ); - Vec_IntFree( vSelected ); - - Vec_IntFree( vFlopsNew ); - Vec_IntFree( vFlops ); - } - RetValue = -1; - } - else if ( vFlopsNew == NULL ) - { - // found real counter-example - assert( pAig->pSeqModel != NULL ); - printf( "Refinement did not happen. Discovered a true counter-example.\n" ); - printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManCiNum(pAig), Gia_ManPiNum(pGia) ); - // derive new counter-example - pOrig = Gia_ManToAigSimple( pGia ); - pGia->pCexSeq = Saig_ManCexRemap( pOrig, pAig, pAig->pSeqModel ); - Aig_ManStop( pOrig ); - RetValue = 0; - } - else - { - // found counter-eample for the abstracted model - // update flop classes - Vec_Int_t * vAbsFfsToAdd = vFlopsNew; - Gia_ManFlopsAddToClasses( pGia->vFlopClasses, vAbsFfsToAdd ); - Vec_IntFree( vAbsFfsToAdd ); - RetValue = -1; - } - Aig_ManStop( pAig ); - if ( fVerbose ) - Gia_ManPrintStats( pGia, 0, 0 ); - return RetValue; -} - - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManGlaCbaPerform( Gia_Man_t * pGia, void * pPars, int fNaiveCnf ) -{ - extern Vec_Int_t * Aig_Gla1ManPerform( Aig_Man_t * pAig, Vec_Int_t * vGateClassesOld, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fNaiveCnf, int fVerbose, int * piFrame ); - Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars; - Vec_Int_t * vGateClasses, * vGateClassesOld = NULL; - Aig_Man_t * pAig; - - // check if flop classes are given - if ( pGia->vGateClasses == NULL ) - Abc_Print( 0, "Initial gate map is not given. Abstraction begins from scratch.\n" ); - else - { - Abc_Print( 0, "Initial gate map is given. Abstraction refines this map.\n" ); - vGateClassesOld = pGia->vGateClasses; pGia->vGateClasses = NULL; - fNaiveCnf = 1; - } - - // perform abstraction - p->iFrame = -1; - pAig = Gia_ManToAigSimple( pGia ); - assert( vGateClassesOld == NULL || Vec_IntSize(vGateClassesOld) == Aig_ManObjNumMax(pAig) ); - vGateClasses = Aig_Gla1ManPerform( pAig, vGateClassesOld, p->nStart, p->nFramesMax, p->nConfLimit, p->nTimeOut, fNaiveCnf, p->fVerbose, &p->iFrame ); - Aig_ManStop( pAig ); - - // update the map - Vec_IntFreeP( &vGateClassesOld ); - pGia->vGateClasses = vGateClasses; - if ( p->fVerbose ) - Gia_ManPrintStats( pGia, 0, 0 ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManGlaPbaPerform( Gia_Man_t * pGia, void * pPars, int fNewSolver ) -{ - extern Vec_Int_t * Aig_Gla2ManPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fSkipRand, int fVerbose ); - extern Vec_Int_t * Aig_Gla3ManPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fSkipRand, int fVerbose ); - Saig_ParBmc_t * p = (Saig_ParBmc_t *)pPars; - Vec_Int_t * vGateClasses; - Gia_Man_t * pGiaAbs; - Aig_Man_t * pAig; - - // check if flop classes are given - if ( pGia->vGateClasses == NULL ) - { - Abc_Print( 0, "Initial gate map is not given. Abstraction begins from scratch.\n" ); - pAig = Gia_ManToAigSimple( pGia ); - } - else - { - Abc_Print( 0, "Initial gate map is given. Abstraction refines this map.\n" ); - pGiaAbs = Gia_ManDupAbsGates( pGia, pGia->vGateClasses ); - pAig = Gia_ManToAigSimple( pGiaAbs ); - Gia_ManStop( pGiaAbs ); - } - - // perform abstraction - if ( fNewSolver ) - vGateClasses = Aig_Gla3ManPerform( pAig, p->nStart, p->nFramesMax, p->nConfLimit, p->nTimeOut, p->fSkipRand, p->fVerbose ); - else - vGateClasses = Aig_Gla2ManPerform( pAig, p->nStart, p->nFramesMax, p->nConfLimit, p->nTimeOut, p->fSkipRand, p->fVerbose ); - Aig_ManStop( pAig ); - - // update the BMC depth - if ( vGateClasses ) - p->iFrame = p->nFramesMax; - - // update the abstraction map (hint: AIG and GIA have one-to-one obj ID match) - if ( pGia->vGateClasses && vGateClasses ) - { - Gia_Obj_t * pObj; - int i, Counter = 0; - Gia_ManForEachObj1( pGia, pObj, i ) - { - if ( !~pObj->Value ) - continue; - if ( !Vec_IntEntry(pGia->vGateClasses, i) ) - continue; - // this obj was abstracted before - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(pGia, pObj) ); - // if corresponding AIG object is not abstracted, remove abstraction - if ( !Vec_IntEntry(vGateClasses, Abc_Lit2Var(pObj->Value)) ) - { - Vec_IntWriteEntry( pGia->vGateClasses, i, 0 ); - Counter++; - } - } - Vec_IntFree( vGateClasses ); - if ( p->fVerbose ) - Abc_Print( 1, "Repetition of abstraction removed %d entries from the old abstraction map.\n", Counter ); - } - else - { - Vec_IntFreeP( &pGia->vGateClasses ); - pGia->vGateClasses = vGateClasses; - } - // clean up the abstraction map - if ( pGia->vGateClasses ) - { - pGiaAbs = Gia_ManDupAbsGates( pGia, pGia->vGateClasses ); - Gia_ManStop( pGiaAbs ); - } - if ( p->fVerbose ) - Gia_ManPrintStats( pGia, 0, 0 ); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [Converting VTA vector to GLA vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta ) -{ - Gia_Obj_t * pObj; - Vec_Int_t * vGla; - int nObjMask, nObjs = Gia_ManObjNum(p); - int i, Entry, nFrames = Vec_IntEntry( vVta, 0 ); - assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) ); - // get the bitmask - nObjMask = (1 << Abc_Base2Log(nObjs)) - 1; - assert( nObjs <= nObjMask ); - // go through objects - vGla = Vec_IntStart( nObjs ); - Vec_IntForEachEntryStart( vVta, Entry, i, nFrames+2 ) - { - pObj = Gia_ManObj( p, (Entry & nObjMask) ); - assert( Gia_ObjIsRo(p, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsConst0(pObj) ); - Vec_IntAddToEntry( vGla, (Entry & nObjMask), 1 ); - } - Vec_IntWriteEntry( vGla, 0, nFrames ); - return vGla; -} - -/**Function************************************************************* - - Synopsis [Converting GLA vector to VTA vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames ) -{ - Vec_Int_t * vVta; - int nObjBits, nObjMask, nObjs = Gia_ManObjNum(p); - int i, k, j, Entry, Counter, nGlaSize; - //. get the GLA size - nGlaSize = Vec_IntSum(vGla); - // get the bitmask - nObjBits = Abc_Base2Log(nObjs); - nObjMask = (1 << Abc_Base2Log(nObjs)) - 1; - assert( nObjs <= nObjMask ); - // go through objects - vVta = Vec_IntAlloc( 1000 ); - Vec_IntPush( vVta, nFrames ); - Counter = nFrames + 2; - for ( i = 0; i <= nFrames; i++, Counter += i * nGlaSize ) - Vec_IntPush( vVta, Counter ); - for ( i = 0; i < nFrames; i++ ) - for ( k = 0; k <= i; k++ ) - Vec_IntForEachEntry( vGla, Entry, j ) - if ( Entry ) - Vec_IntPush( vVta, (k << nObjBits) | j ); - Counter = Vec_IntEntry(vVta, nFrames+1); - assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) ); - return vVta; -} - -/**Function************************************************************* - - Synopsis [Converting GLA vector to FLA vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_FlaConvertToGla_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla ) -{ - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pObj); - Vec_IntWriteEntry( vGla, Gia_ObjId(p, pObj), 1 ); - if ( Gia_ObjIsRo(p, pObj) ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); - Gia_FlaConvertToGla_rec( p, Gia_ObjFanin1(pObj), vGla ); -} - -/**Function************************************************************* - - Synopsis [Converting FLA vector to GLA vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla ) -{ - Vec_Int_t * vGla; - Gia_Obj_t * pObj; - int i; - // mark const0 and relevant CI objects - Gia_ManIncrementTravId( p ); - Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p)); - Gia_ManForEachPi( p, pObj, i ) - Gia_ObjSetTravIdCurrent(p, pObj); - Gia_ManForEachRo( p, pObj, i ) - if ( !Vec_IntEntry(vFla, i) ) - Gia_ObjSetTravIdCurrent(p, pObj); - // label all objects reachable from the PO and selected flops - vGla = Vec_IntStart( Gia_ManObjNum(p) ); - Vec_IntWriteEntry( vGla, 0, 1 ); - Gia_ManForEachPo( p, pObj, i ) - Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); - Gia_ManForEachRi( p, pObj, i ) - if ( Vec_IntEntry(vFla, i) ) - Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); - return vGla; -} - -/**Function************************************************************* - - Synopsis [Converting GLA vector to FLA vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla ) -{ - Vec_Int_t * vFla; - Gia_Obj_t * pObj; - int i; - vFla = Vec_IntStart( Gia_ManRegNum(p) ); - Gia_ManForEachRo( p, pObj, i ) - if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) - Vec_IntWriteEntry( vFla, i, 1 ); - return vFla; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManGlaPurify( Gia_Man_t * p, int nPurifyRatio, int fVerbose ) -{ - int i, Entry, CountUpTo, CountAll, CountRem, * pCounts; - int nFrames = Vec_IntEntry( p->vGateClasses, 0 ); - if ( nFrames < 2 ) - { - printf( "Gate-level abstraction is missing object count information.\n" ); - return; - } - // collect info - CountAll = 0; - pCounts = ABC_CALLOC( int, nFrames + 1 ); - assert( Vec_IntSize(p->vGateClasses) == Gia_ManObjNum(p) ); - for ( i = 0; i < Gia_ManObjNum(p); i++ ) - { - Entry = Vec_IntEntry( p->vGateClasses, i ); - assert( Entry >= 0 && Entry <= nFrames ); - if ( Entry == 0 ) - continue; - CountAll++; - pCounts[Entry]++; - } - // print entries - CountUpTo = 0; - for ( i = 0; i <= nFrames; i++ ) - printf( "%d=%d(%d) ", i, pCounts[i], CountUpTo += pCounts[i] ); - printf( "\n" ); - // removing entries appearing only ones - CountRem = 0; - for ( i = 0; i < Gia_ManObjNum(p); i++ ) - { - if ( Vec_IntEntry( p->vGateClasses, i ) == 0 ) - continue; - if ( Vec_IntEntry( p->vGateClasses, i ) <= nPurifyRatio ) - { - CountRem++; - Vec_IntWriteEntry( p->vGateClasses, i, 0 ); - } - } - printf( "Removed %d entries appearing less or equal than %d times (out of %d).\n", CountRem, nPurifyRatio, CountAll ); - ABC_FREE( pCounts ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla ) -{ - Gia_Obj_t * pObj; - int i, Count = 0; - Gia_ManForEachRo( p, pObj, i ) - if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) - Count++; - return Count; -} -int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla ) -{ - Gia_Obj_t * pObj; - int i, Count = 0; - Gia_ManForEachAnd( p, pObj, i ) - if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) - Count++; - return Count; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbs.h b/src/aig/gia/giaAbs.h deleted file mode 100644 index 366a4d8a..00000000 --- a/src/aig/gia/giaAbs.h +++ /dev/null @@ -1,89 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbs.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef ABC__aig__gia__giaAbs_h -#define ABC__aig__gia__giaAbs_h - - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - - - -ABC_NAMESPACE_HEADER_START - - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -// abstraction parameters -typedef struct Gia_ParAbs_t_ Gia_ParAbs_t; -struct Gia_ParAbs_t_ -{ - int Algo; // the algorithm to be used - int nFramesMax; // timeframes for PBA - int nConfMax; // conflicts for PBA - int fDynamic; // dynamic unfolding for PBA - int fConstr; // use constraints - int nFramesBmc; // timeframes for BMC - int nConfMaxBmc; // conflicts for BMC - int nStableMax; // the number of stable frames to quit - int nRatio; // ratio of flops to quit - int TimeOut; // approximate timeout in seconds - int TimeOutVT; // approximate timeout in seconds - int nBobPar; // Bob's parameter - int fUseBdds; // use BDDs to refine abstraction - int fUseDprove; // use 'dprove' to refine abstraction - int fUseStart; // use starting frame - int fVerbose; // verbose output - int fVeryVerbose; // printing additional information - int Status; // the problem status - int nFramesDone; // the number of frames covered -}; - -extern void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - - - - -ABC_NAMESPACE_HEADER_END - - - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/gia/giaAbsGla.c b/src/aig/gia/giaAbsGla.c deleted file mode 100644 index 0ebb8db7..00000000 --- a/src/aig/gia/giaAbsGla.c +++ /dev/null @@ -1,1958 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsGla.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Gate-level abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsGla.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAig.h" -#include "giaAbsRef.h" -#include "sat/cnf/cnf.h" -#include "sat/bsat/satSolver2.h" -#include "base/main/main.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rfn_Obj_t_ Rfn_Obj_t; // refinement object -struct Rfn_Obj_t_ -{ - unsigned Value : 1; // value - unsigned fVisit : 1; // visited - unsigned fPPi : 1; // PPI - unsigned Prio : 16; // priority - unsigned Sign : 12; // traversal signature -}; - -typedef struct Gla_Obj_t_ Gla_Obj_t; // abstraction object -struct Gla_Obj_t_ -{ - int iGiaObj; // corresponding GIA obj - unsigned fAbs : 1; // belongs to abstraction - unsigned fCompl0 : 1; // compl bit of the first fanin - unsigned fConst : 1; // object attribute - unsigned fPi : 1; // object attribute - unsigned fPo : 1; // object attribute - unsigned fRo : 1; // object attribute - unsigned fRi : 1; // object attribute - unsigned fAnd : 1; // object attribute - unsigned fMark : 1; // nearby object - unsigned nFanins : 23; // fanin count - int Fanins[4]; // fanins - Vec_Int_t vFrames; // variables in each timeframe -}; - -typedef struct Gla_Man_t_ Gla_Man_t; // manager -struct Gla_Man_t_ -{ - // user data - Gia_Man_t * pGia0; // starting AIG manager - Gia_Man_t * pGia; // working AIG manager - Gia_ParVta_t* pPars; // parameters - // internal data - Vec_Int_t * vAbs; // abstracted objects - Gla_Obj_t * pObjRoot; // the primary output - Gla_Obj_t * pObjs; // objects - unsigned * pObj2Obj; // mapping of GIA obj into GLA obj - int nObjs; // the number of objects - int nAbsOld; // previous abstraction -// int nAbsNew; // previous abstraction -// int nLrnOld; // the number of bytes -// int nLrnNew; // the number of bytes - // other data - int nCexes; // the number of counter-examples - int nObjAdded; // total number of objects added - int nSatVars; // the number of SAT variables - Cnf_Dat_t * pCnf; // CNF derived for the nodes - sat_solver2 * pSat; // incremental SAT solver - Vec_Int_t * vTemp; // temporary array - Vec_Int_t * vAddedNew; // temporary array - Vec_Int_t * vObjCounts; // object counters - Vec_Int_t * vCoreCounts; // counts how many times each object appears in the core - Vec_Int_t * vProofIds; // counts how many times each object appears in the core - int nProofIds; // proof ID counter - // refinement - Vec_Int_t * pvRefis; // vectors of each object - // refinement manager - Gia_Man_t * pGia2; - Rnm_Man_t * pRnm; - // statistics - clock_t timeInit; - clock_t timeSat; - clock_t timeUnsat; - clock_t timeCex; - clock_t timeOther; -}; - -// declarations -static Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis ); -static int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame ); -static int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame ); - -// object procedures -static inline int Gla_ObjId( Gla_Man_t * p, Gla_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } -static inline Gla_Obj_t * Gla_ManObj( Gla_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; } -static inline Gia_Obj_t * Gla_ManGiaObj( Gla_Man_t * p, Gla_Obj_t * pObj ) { return Gia_ManObj( p->pGia, pObj->iGiaObj ); } -static inline int Gla_ObjSatValue( Gla_Man_t * p, int iGia, int f ) { return Gla_ManCheckVar(p, p->pObj2Obj[iGia], f) ? sat_solver2_var_value( p->pSat, Gla_ManGetVar(p, p->pObj2Obj[iGia], f) ) : 0; } - -static inline Rfn_Obj_t * Gla_ObjRef( Gla_Man_t * p, Gia_Obj_t * pObj, int f ) { return (Rfn_Obj_t *)Vec_IntGetEntryP( &(p->pvRefis[Gia_ObjId(p->pGia, pObj)]), f ); } -static inline void Gla_ObjClearRef( Rfn_Obj_t * p ) { *((int *)p) = 0; } - - -// iterator through abstracted objects -#define Gla_ManForEachObj( p, pObj ) \ - for ( pObj = p->pObjs + 1; pObj < p->pObjs + p->nObjs; pObj++ ) -#define Gla_ManForEachObjAbs( p, pObj, i ) \ - for ( i = 0; i < Vec_IntSize(p->vAbs) && ((pObj = Gla_ManObj(p, Vec_IntEntry(p->vAbs, i))),1); i++) -#define Gla_ManForEachObjAbsVec( vVec, p, pObj, i ) \ - for ( i = 0; i < Vec_IntSize(vVec) && ((pObj = Gla_ManObj(p, Vec_IntEntry(vVec, i))),1); i++) - -// iterator through fanins of an abstracted object -#define Gla_ObjForEachFanin( p, pObj, pFanin, i ) \ - for ( i = 0; (i < (int)pObj->nFanins) && ((pFanin = Gla_ManObj(p, pObj->Fanins[i])),1); i++ ) - -// some lessons learned from debugging mismatches between GIA and mapped CNF -// - inputs/output of AND-node may be PPIs (have SAT vars), but the node is not included in the abstraction -// - some logic node can be a PPI of one LUT and an internal node of another LUT - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Prepares CEX and vMap for refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_GlaPrepareCexAndMap( Gla_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMap ) -{ - Abc_Cex_t * pCex; - Vec_Int_t * vMap; - Gla_Obj_t * pObj, * pFanin; - Gia_Obj_t * pGiaObj; - int f, i, k; - // find PIs and PPIs - vMap = Vec_IntAlloc( 1000 ); - Gla_ManForEachObjAbs( p, pObj, i ) - { - assert( pObj->fConst || pObj->fRo || pObj->fAnd ); - Gla_ObjForEachFanin( p, pObj, pFanin, k ) - if ( !pFanin->fAbs ) - Vec_IntPush( vMap, pFanin->iGiaObj ); - } - Vec_IntUniqify( vMap ); - // derive counter-example - pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 ); - pCex->iFrame = p->pPars->iFrame; - for ( f = 0; f <= p->pPars->iFrame; f++ ) - Gia_ManForEachObjVec( vMap, p->pGia, pGiaObj, k ) - if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pGiaObj), f ) ) - Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k ); - *pvMap = vMap; - *ppCex = pCex; -} - -/**Function************************************************************* - - Synopsis [Derives counter-example using current assignments.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gla_ManDeriveCex( Gla_Man_t * p, Vec_Int_t * vPis ) -{ - Abc_Cex_t * pCex; - Gia_Obj_t * pObj; - int i, f; - pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); - pCex->iPo = 0; - pCex->iFrame = p->pPars->iFrame; - Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) - { - if ( !Gia_ObjIsPi(p->pGia, pObj) ) - continue; - assert( Gia_ObjIsPi(p->pGia, pObj) ); - for ( f = 0; f <= pCex->iFrame; f++ ) - if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) ); - } - return pCex; -} - -/**Function************************************************************* - - Synopsis [Collects GIA abstraction objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManCollectInternal_rec( Gia_Man_t * p, Gia_Obj_t * pGiaObj, Vec_Int_t * vRoAnds ) -{ - if ( Gia_ObjIsTravIdCurrent(p, pGiaObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pGiaObj); - assert( Gia_ObjIsAnd(pGiaObj) ); - Gla_ManCollectInternal_rec( p, Gia_ObjFanin0(pGiaObj), vRoAnds ); - Gla_ManCollectInternal_rec( p, Gia_ObjFanin1(pGiaObj), vRoAnds ); - Vec_IntPush( vRoAnds, Gia_ObjId(p, pGiaObj) ); -} -void Gla_ManCollect( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vCos, Vec_Int_t * vRoAnds ) -{ - Gla_Obj_t * pObj, * pFanin; - Gia_Obj_t * pGiaObj; - int i, k; - - // collect COs - Vec_IntPush( vCos, Gia_ObjId(p->pGia, Gia_ManPo(p->pGia, 0)) ); - // collect fanins of abstracted objects - Gla_ManForEachObjAbs( p, pObj, i ) - { - assert( pObj->fConst || pObj->fRo || pObj->fAnd ); - if ( pObj->fRo ) - { - pGiaObj = Gia_ObjRoToRi( p->pGia, Gia_ManObj(p->pGia, pObj->iGiaObj) ); - Vec_IntPush( vCos, Gia_ObjId(p->pGia, pGiaObj) ); - } - Gla_ObjForEachFanin( p, pObj, pFanin, k ) - if ( !pFanin->fAbs ) - Vec_IntPush( (pFanin->fPi ? vPis : vPPis), pFanin->iGiaObj ); - } - Vec_IntUniqify( vPis ); - Vec_IntUniqify( vPPis ); - Vec_IntSort( vCos, 0 ); - // sorting PIs/PPIs/COs leads to refinements that are more "well-aligned"... - - // mark const/PIs/PPIs - Gia_ManIncrementTravId( p->pGia ); - Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); - Gia_ManForEachObjVec( vPis, p->pGia, pGiaObj, i ) - Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); - Gia_ManForEachObjVec( vPPis, p->pGia, pGiaObj, i ) - Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); - // mark and add ROs first - Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i ) - { - if ( i == 0 ) continue; - pGiaObj = Gia_ObjRiToRo( p->pGia, pGiaObj ); - Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); - Vec_IntPush( vRoAnds, Gia_ObjId(p->pGia, pGiaObj) ); - } - // collect nodes between PIs/PPIs/ROs and COs - Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i ) - Gla_ManCollectInternal_rec( p->pGia, Gia_ObjFanin0(pGiaObj), vRoAnds ); -} - -/**Function************************************************************* - - Synopsis [Drive implications of the given node towards primary outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManRefSetAndPropFanout_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign ) -{ - int i;//, Id = Gia_ObjId(p->pGia, pObj); - Rfn_Obj_t * pRef0, * pRef1, * pRef = Gla_ObjRef( p, pObj, f ); - Gia_Obj_t * pFanout; - int k; - if ( (int)pRef->Sign != Sign ) - return; - assert( pRef->fVisit == 0 ); - pRef->fVisit = 1; - if ( pRef->fPPi ) - { - assert( (int)pRef->Prio > 0 ); - for ( i = p->pPars->iFrame; i >= 0; i-- ) - if ( !Gla_ObjRef(p, pObj, i)->fVisit ) - Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign ); - Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); - return; - } - if ( (Gia_ObjIsCo(pObj) && f == p->pPars->iFrame) || Gia_ObjIsPo(p->pGia, pObj) ) - return; - if ( Gia_ObjIsRi(p->pGia, pObj) ) - { - pFanout = Gia_ObjRiToRo(p->pGia, pObj); - if ( !Gla_ObjRef(p, pFanout, f+1)->fVisit ) - Gia_ManRefSetAndPropFanout_rec( p, pFanout, f+1, vSelect, Sign ); - return; - } - assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); - Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k ) - { -// Rfn_Obj_t * pRefF = Gla_ObjRef(p, pFanout, f); - if ( Gla_ObjRef(p, pFanout, f)->fVisit ) - continue; - if ( Gia_ObjIsCo(pFanout) ) - { - Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign ); - continue; - } - assert( Gia_ObjIsAnd(pFanout) ); - pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pFanout), f ); - pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pFanout), f ); - if ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRef0->fVisit) || - ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRef1->fVisit) || - ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRef0->fVisit) && - ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRef1->fVisit) ) ) - Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign ); - } -} - -/**Function************************************************************* - - Synopsis [Selects assignments to be refined.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManRefSelect_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign ) -{ - int i;//, Id = Gia_ObjId(p->pGia, pObj); - Rfn_Obj_t * pRef = Gla_ObjRef( p, pObj, f ); -// assert( (int)pRef->Sign == Sign ); - if ( pRef->fVisit ) - return; - if ( p->pPars->fPropFanout ) - Gia_ManRefSetAndPropFanout_rec( p, pObj, f, vSelect, Sign ); - else - pRef->fVisit = 1; - if ( pRef->fPPi ) - { - assert( (int)pRef->Prio > 0 ); - if ( p->pPars->fPropFanout ) - { - for ( i = p->pPars->iFrame; i >= 0; i-- ) - if ( !Gla_ObjRef(p, pObj, i)->fVisit ) - Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign ); - } - else - { - Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); - Vec_IntAddToEntry( p->vObjCounts, f, 1 ); - } - return; - } - if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) - return; - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect, Sign ); - return; - } - if ( Gia_ObjIsAnd(pObj) ) - { - Rfn_Obj_t * pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); - Rfn_Obj_t * pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f ); - if ( pRef->Value == 1 ) - { - if ( pRef0->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); - if ( pRef1->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); - } - else // select one value - { - if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - { - if ( pRef0->Prio <= pRef1->Prio ) // choice - { - if ( pRef0->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); - } - else - { - if ( pRef1->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); - } - } - else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) - { - if ( pRef0->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); - } - else if ( (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - { - if ( pRef1->Prio > 0 ) - Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); - } - else assert( 0 ); - } - } - else assert( 0 ); -} - - -/**Function************************************************************* - - Synopsis [Performs refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManVerifyUsingTerSim( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vRoAnds, Vec_Int_t * vCos, Vec_Int_t * vRes ) -{ - Gia_Obj_t * pObj; - int i, f; -// Gia_ManForEachObj( p->pGia, pObj, i ) -// assert( Gia_ObjTerSimGetC(pObj) ); - for ( f = 0; f <= p->pPars->iFrame; f++ ) - { - Gia_ObjTerSimSet0( Gia_ManConst0(p->pGia) ); - Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) - { - if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) - Gia_ObjTerSimSetX( pObj ); - Gia_ManForEachObjVec( vRes, p->pGia, pObj, i ) - if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - - Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - Gia_ObjTerSimAnd( pObj ); - else if ( f == 0 ) - Gia_ObjTerSimSet0( pObj ); - else - Gia_ObjTerSimRo( p->pGia, pObj ); - } - Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) - Gia_ObjTerSimCo( pObj ); - } - pObj = Gia_ManPo( p->pGia, 0 ); - if ( !Gia_ObjTerSimGet1(pObj) ) - Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); - // clear - Gia_ObjTerSimSetC( Gia_ManConst0(p->pGia) ); - Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) - Gia_ObjTerSimSetC( pObj ); - Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) - Gia_ObjTerSimSetC( pObj ); - Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) - Gia_ObjTerSimSetC( pObj ); - Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) - Gia_ObjTerSimSetC( pObj ); -} - - -/**Function************************************************************* - - Synopsis [Performs refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gla_ManRefinement( Gla_Man_t * p ) -{ - Abc_Cex_t * pCex; - Vec_Int_t * vMap, * vVec; - Gia_Obj_t * pObj; - int i; - Gia_GlaPrepareCexAndMap( p, &pCex, &vMap ); - vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 0, 1 ); - Abc_CexFree( pCex ); - if ( Vec_IntSize(vVec) == 0 ) - { - Vec_IntFree( vVec ); - Abc_CexFreeP( &p->pGia->pCexSeq ); - p->pGia->pCexSeq = Gla_ManDeriveCex( p, vMap ); - Vec_IntFree( vMap ); - return NULL; - } - Vec_IntFree( vMap ); - // remap them into GLA objects - Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) - Vec_IntWriteEntry( vVec, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] ); - p->nObjAdded += Vec_IntSize(vVec); - return vVec; -} - -/**Function************************************************************* - - Synopsis [Performs refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gla_ManRefinement2( Gla_Man_t * p ) -{ - int fVerify = 1; - static int Sign = 0; - Vec_Int_t * vPis, * vPPis, * vCos, * vRoAnds, * vSelect = NULL; - Rfn_Obj_t * pRef, * pRef0, * pRef1; - Gia_Obj_t * pObj; - int i, f; - Sign++; - - // compute PIs and pseudo-PIs - vCos = Vec_IntAlloc( 1000 ); - vPis = Vec_IntAlloc( 1000 ); - vPPis = Vec_IntAlloc( 1000 ); - vRoAnds = Vec_IntAlloc( 1000 ); - Gla_ManCollect( p, vPis, vPPis, vCos, vRoAnds ); - -/* - // check how many pseudo PIs have variables - Gla_ManForEachObjAbsVec( vPis, p, pGla, i ) - { - Abc_Print( 1, " %5d : ", Gla_ObjId(p, pGla) ); - for ( f = 0; f <= p->pPars->iFrame; f++ ) - Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) ); - Abc_Print( 1, "\n" ); - } - - // check how many pseudo PIs have variables - Gla_ManForEachObjAbsVec( vPPis, p, pGla, i ) - { - Abc_Print( 1, "%5d : ", Gla_ObjId(p, pGla) ); - for ( f = 0; f <= p->pPars->iFrame; f++ ) - Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) ); - Abc_Print( 1, "\n" ); - } -*/ - // propagate values - for ( f = 0; f <= p->pPars->iFrame; f++ ) - { - // constant - pRef = Gla_ObjRef( p, Gia_ManConst0(p->pGia), f ); Gla_ObjClearRef( pRef ); - pRef->Value = 0; - pRef->Prio = 0; - pRef->Sign = Sign; - // primary input - Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) - { -// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) ); - pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); - pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ); - pRef->Prio = 0; - pRef->Sign = Sign; - assert( pRef->fVisit == 0 ); - } - // primary input - Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) - { -// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) ); - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); - pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); - pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ); - pRef->Prio = i+1; - pRef->fPPi = 1; - pRef->Sign = Sign; - assert( pRef->fVisit == 0 ); - } - // internal nodes - Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) - { - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); - pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f == 0 ) - { - pRef->Value = 0; - pRef->Prio = 0; - pRef->Sign = Sign; - } - else - { - pRef0 = Gla_ObjRef( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); - pRef->Value = pRef0->Value; - pRef->Prio = pRef0->Prio; - pRef->Sign = Sign; - } - continue; - } - assert( Gia_ObjIsAnd(pObj) ); - pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); - pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f ); - pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj)) & (pRef1->Value ^ Gia_ObjFaninC1(pObj)); - - if ( p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] != ~0 && - Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) && - (int)pRef->Value != Gla_ObjSatValue(p, Gia_ObjId(p->pGia, pObj), f) ) - { - Abc_Print( 1, "Object has value mismatch " ); - Gia_ObjPrint( p->pGia, pObj ); - } - - if ( pRef->Value == 1 ) - pRef->Prio = Abc_MaxInt( pRef0->Prio, pRef1->Prio ); - else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - pRef->Prio = Abc_MinInt( pRef0->Prio, pRef1->Prio ); // choice - else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) - pRef->Prio = pRef0->Prio; - else - pRef->Prio = pRef1->Prio; - assert( pRef->fVisit == 0 ); - pRef->Sign = Sign; - } - // output nodes - Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) - { - pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); - pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); - pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj)); - pRef->Prio = pRef0->Prio; - assert( pRef->fVisit == 0 ); - pRef->Sign = Sign; - } - } - - // make sure the output value is 1 - pObj = Gia_ManPo( p->pGia, 0 ); - pRef = Gla_ObjRef( p, pObj, p->pPars->iFrame ); - if ( pRef->Value != 1 ) - Abc_Print( 1, "\nCounter-example verification has failed!!!\n" ); - - // check the CEX - if ( pRef->Prio == 0 ) - { - p->pGia->pCexSeq = Gla_ManDeriveCex( p, vPis ); - Vec_IntFree( vPis ); - Vec_IntFree( vPPis ); - Vec_IntFree( vRoAnds ); - Vec_IntFree( vCos ); - return NULL; - } - - // select objects - vSelect = Vec_IntAlloc( 100 ); - Vec_IntFill( p->vObjCounts, p->pPars->iFrame+1, 0 ); - Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), p->pPars->iFrame, vSelect, Sign ); - Vec_IntUniqify( vSelect ); - -/* - for ( f = 0; f < p->pPars->iFrame; f++ ) - printf( "%2d", Vec_IntEntry(p->vObjCounts, f) ); - printf( "\n" ); -*/ - if ( fVerify ) - Gla_ManVerifyUsingTerSim( p, vPis, vPPis, vRoAnds, vCos, vSelect ); - - // remap them into GLA objects - Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) - Vec_IntWriteEntry( vSelect, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] ); - - Vec_IntFree( vPis ); - Vec_IntFree( vPPis ); - Vec_IntFree( vRoAnds ); - Vec_IntFree( vCos ); - - p->nObjAdded += Vec_IntSize(vSelect); - return vSelect; -} - - -/**Function************************************************************* - - Synopsis [Adds clauses for the given obj in the given frame.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManCollectFanins( Gla_Man_t * p, Gla_Obj_t * pGla, int iObj, Vec_Int_t * vFanins ) -{ - int i, nClauses, iFirstClause, * pLit; - nClauses = p->pCnf->pObj2Count[pGla->iGiaObj]; - iFirstClause = p->pCnf->pObj2Clause[pGla->iGiaObj]; - Vec_IntClear( vFanins ); - for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) - for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ ) - if ( lit_var(*pLit) != iObj ) - Vec_IntPushUnique( vFanins, lit_var(*pLit) ); - assert( Vec_IntSize( vFanins ) <= 4 ); - Vec_IntSort( vFanins, 0 ); -} - - -/**Function************************************************************* - - Synopsis [Duplicates AIG while decoupling nodes duplicated in the mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDupMapped_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Man_t * pNew ) -{ - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pObj); - assert( Gia_ObjIsAnd(pObj) ); - Gia_ManDupMapped_rec( p, Gia_ObjFanin0(pObj), pNew ); - Gia_ManDupMapped_rec( p, Gia_ObjFanin1(pObj), pNew ); - pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); - Vec_IntPush( pNew->vLutConfigs, Gia_ObjId(p, pObj) ); -} -Gia_Man_t * Gia_ManDupMapped( Gia_Man_t * p, Vec_Int_t * vMapping ) -{ - Gia_Man_t * pNew; - Gia_Obj_t * pObj, * pFanin; - int i, k, * pMapping, * pObj2Obj; - // start new manager - pNew = Gia_ManStart( Gia_ManObjNum(p) ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - // start mapping - Gia_ManFillValue( p ); - pObj2Obj = ABC_FALLOC( int, Gia_ManObjNum(p) ); - pObj2Obj[0] = 0; - // create reverse mapping and attach it to the node - pNew->vLutConfigs = Vec_IntAlloc( Gia_ManObjNum(p) * 4 / 3 ); - Vec_IntPush( pNew->vLutConfigs, 0 ); - Gia_ManForEachObj1( p, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - { - int Offset = Vec_IntEntry(vMapping, Gia_ObjId(p, pObj)); - if ( Offset == 0 ) - continue; - pMapping = Vec_IntEntryP( vMapping, Offset ); - Gia_ManIncrementTravId( p ); - for ( k = 1; k <= 4; k++ ) - { - if ( pMapping[k] == -1 ) - continue; - pFanin = Gia_ManObj(p, pMapping[k]); - Gia_ObjSetTravIdCurrent( p, pFanin ); - pFanin->Value = pObj2Obj[pMapping[k]]; - assert( ~pFanin->Value ); - } - assert( !Gia_ObjIsTravIdCurrent(p, pObj) ); - assert( !~pObj->Value ); - Gia_ManDupMapped_rec( p, pObj, pNew ); - pObj2Obj[i] = pObj->Value; - assert( ~pObj->Value ); - } - else if ( Gia_ObjIsCi(pObj) ) - { - pObj2Obj[i] = Gia_ManAppendCi( pNew ); - Vec_IntPush( pNew->vLutConfigs, i ); - } - else if ( Gia_ObjIsCo(pObj) ) - { - Gia_ObjFanin0(pObj)->Value = pObj2Obj[Gia_ObjFaninId0p(p, pObj)]; - assert( ~Gia_ObjFanin0(pObj)->Value ); - pObj2Obj[i] = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Vec_IntPush( pNew->vLutConfigs, i ); - } - } - assert( Vec_IntSize(pNew->vLutConfigs) == Gia_ManObjNum(pNew) ); - Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); - // map original AIG into the new AIG - Gia_ManForEachObj( p, pObj, i ) - pObj->Value = pObj2Obj[i]; - ABC_FREE( pObj2Obj ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gla_Man_t * Gla_ManStart( Gia_Man_t * pGia0, Gia_ParVta_t * pPars ) -{ - Gla_Man_t * p; - Aig_Man_t * pAig; - Gia_Obj_t * pObj; - Gla_Obj_t * pGla; - Vec_Int_t * vMappingNew; - int i, k, Offset, * pMapping, * pLits, * pObj2Count, * pObj2Clause; - - // start - p = ABC_CALLOC( Gla_Man_t, 1 ); - p->pGia0 = pGia0; - p->pPars = pPars; - p->vAbs = Vec_IntAlloc( 100 ); - p->vTemp = Vec_IntAlloc( 100 ); - p->vAddedNew = Vec_IntAlloc( 100 ); - p->vObjCounts = Vec_IntAlloc( 100 ); - - // internal data - pAig = Gia_ManToAigSimple( pGia0 ); - p->pCnf = Cnf_DeriveOther( pAig, 1 ); - Aig_ManStop( pAig ); - // create working GIA - p->pGia = Gia_ManDupMapped( pGia0, p->pCnf->vMapping ); - if ( pPars->fPropFanout ) - Gia_ManStaticFanoutStart( p->pGia ); - - // derive new gate map - assert( pGia0->vGateClasses != 0 ); - p->pGia->vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) ); - p->vCoreCounts = Vec_IntStart( Gia_ManObjNum(p->pGia) ); - p->vProofIds = Vec_IntAlloc(0); - // update p->pCnf->vMapping, p->pCnf->pObj2Count, p->pCnf->pObj2Clause - // (here are not updating p->pCnf->pVarNums because it is not needed) - vMappingNew = Vec_IntStart( Gia_ManObjNum(p->pGia) ); - pObj2Count = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) ); - pObj2Clause = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) ); - Gia_ManForEachObj( pGia0, pObj, i ) - { - // skip internal nodes not used in the mapping - if ( !~pObj->Value ) - continue; - // replace positive literal by variable - assert( !Abc_LitIsCompl(pObj->Value) ); - pObj->Value = Abc_Lit2Var(pObj->Value); - assert( (int)pObj->Value < Gia_ManObjNum(p->pGia) ); - // update arrays - pObj2Count[pObj->Value] = p->pCnf->pObj2Count[i]; - pObj2Clause[pObj->Value] = p->pCnf->pObj2Clause[i]; - if ( Vec_IntEntry(pGia0->vGateClasses, i) ) - Vec_IntWriteEntry( p->pGia->vGateClasses, pObj->Value, 1 ); - // update mappings - Offset = Vec_IntEntry(p->pCnf->vMapping, i); - Vec_IntWriteEntry( vMappingNew, pObj->Value, Vec_IntSize(vMappingNew) ); - pMapping = Vec_IntEntryP(p->pCnf->vMapping, Offset); - Vec_IntPush( vMappingNew, pMapping[0] ); - for ( k = 1; k <= 4; k++ ) - { - if ( pMapping[k] == -1 ) - Vec_IntPush( vMappingNew, -1 ); - else - { - assert( ~Gia_ManObj(pGia0, pMapping[k])->Value ); - Vec_IntPush( vMappingNew, Gia_ManObj(pGia0, pMapping[k])->Value ); - } - } - } - // update mapping after the offset (currently not being done because it is not used) - Vec_IntFree( p->pCnf->vMapping ); p->pCnf->vMapping = vMappingNew; - ABC_FREE( p->pCnf->pObj2Count ); p->pCnf->pObj2Count = pObj2Count; - ABC_FREE( p->pCnf->pObj2Clause ); p->pCnf->pObj2Clause = pObj2Clause; - - - // count the number of variables - p->nObjs = 1; - Gia_ManForEachObj( p->pGia, pObj, i ) - if ( p->pCnf->pObj2Count[i] >= 0 ) - pObj->Value = p->nObjs++; - else - pObj->Value = ~0; - - // re-express CNF using new variable IDs - pLits = p->pCnf->pClauses[0]; - for ( i = 0; i < p->pCnf->nLiterals; i++ ) - { - // find the original AIG object - pObj = Gia_ManObj( pGia0, lit_var(pLits[i]) ); - assert( ~pObj->Value ); - // find the working AIG object - pObj = Gia_ManObj( p->pGia, pObj->Value ); - assert( ~pObj->Value ); - // express literal in terms of LUT variables - pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) ); - } - - // create objects - p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs ); - p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) ); -// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) ); - Gia_ManForEachObj( p->pGia, pObj, i ) - { - p->pObj2Obj[i] = pObj->Value; - if ( !~pObj->Value ) - continue; - pGla = Gla_ManObj( p, pObj->Value ); - pGla->iGiaObj = i; - pGla->fCompl0 = Gia_ObjFaninC0(pObj); - pGla->fConst = Gia_ObjIsConst0(pObj); - pGla->fPi = Gia_ObjIsPi(p->pGia, pObj); - pGla->fPo = Gia_ObjIsPo(p->pGia, pObj); - pGla->fRi = Gia_ObjIsRi(p->pGia, pObj); - pGla->fRo = Gia_ObjIsRo(p->pGia, pObj); - pGla->fAnd = Gia_ObjIsAnd(pObj); - if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) - continue; - if ( Gia_ObjIsCo(pObj) ) - { - pGla->nFanins = 1; - pGla->Fanins[0] = Gia_ObjFanin0(pObj)->Value; - continue; - } - if ( Gia_ObjIsAnd(pObj) ) - { -// Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp ); -// pGla->nFanins = Vec_IntSize( p->vTemp ); -// memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) ); - Offset = Vec_IntEntry( p->pCnf->vMapping, i ); - pMapping = Vec_IntEntryP( p->pCnf->vMapping, Offset ); - pGla->nFanins = 0; - for ( k = 1; k <= 4; k++ ) - if ( pMapping[k] != -1 ) - pGla->Fanins[ pGla->nFanins++ ] = Gia_ManObj(p->pGia, pMapping[k])->Value; - continue; - } - assert( Gia_ObjIsRo(p->pGia, pObj) ); - pGla->nFanins = 1; - pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value; - pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) ); - } - p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value ); - // abstraction - assert( p->pGia->vGateClasses != NULL ); - Gla_ManForEachObj( p, pGla ) - { - if ( Vec_IntEntry( p->pGia->vGateClasses, pGla->iGiaObj ) == 0 ) - continue; - pGla->fAbs = 1; - Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); - } - // other - p->pSat = sat_solver2_new(); - if ( pPars->fUseFullProof ) - p->pSat->pPrf1 = Vec_SetAlloc( 20 ); -// p->pSat->fVerbose = p->pPars->fVerbose; -// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax ); - p->pSat->nLearntStart = p->pPars->nLearnedStart; - p->pSat->nLearntDelta = p->pPars->nLearnedDelta; - p->pSat->nLearntRatio = p->pPars->nLearnedPerce; - p->pSat->nLearntMax = p->pSat->nLearntStart; - p->nSatVars = 1; - // start the refinement manager -// p->pGia2 = Gia_ManDup( p->pGia ); - p->pRnm = Rnm_ManStart( p->pGia ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gla_Man_t * Gla_ManStart2( Gia_Man_t * pGia, Gia_ParVta_t * pPars ) -{ - Gla_Man_t * p; - Aig_Man_t * pAig; - Gia_Obj_t * pObj; - Gla_Obj_t * pGla; - int i, * pLits; - // start - p = ABC_CALLOC( Gla_Man_t, 1 ); - p->pGia = pGia; - p->pPars = pPars; - p->vAbs = Vec_IntAlloc( 100 ); - p->vTemp = Vec_IntAlloc( 100 ); - p->vAddedNew = Vec_IntAlloc( 100 ); - // internal data - pAig = Gia_ManToAigSimple( p->pGia ); - p->pCnf = Cnf_DeriveOther( pAig, 1 ); - Aig_ManStop( pAig ); - // count the number of variables - p->nObjs = 1; - Gia_ManForEachObj( p->pGia, pObj, i ) - if ( p->pCnf->pObj2Count[i] >= 0 ) - pObj->Value = p->nObjs++; - else - pObj->Value = ~0; - // re-express CNF using new variable IDs - pLits = p->pCnf->pClauses[0]; - for ( i = 0; i < p->pCnf->nLiterals; i++ ) - { - pObj = Gia_ManObj( p->pGia, lit_var(pLits[i]) ); - assert( ~pObj->Value ); - pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) ); - } - // create objects - p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs ); - p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) ); -// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) ); - Gia_ManForEachObj( p->pGia, pObj, i ) - { - p->pObj2Obj[i] = pObj->Value; - if ( !~pObj->Value ) - continue; - pGla = Gla_ManObj( p, pObj->Value ); - pGla->iGiaObj = i; - pGla->fCompl0 = Gia_ObjFaninC0(pObj); - pGla->fConst = Gia_ObjIsConst0(pObj); - pGla->fPi = Gia_ObjIsPi(p->pGia, pObj); - pGla->fPo = Gia_ObjIsPo(p->pGia, pObj); - pGla->fRi = Gia_ObjIsRi(p->pGia, pObj); - pGla->fRo = Gia_ObjIsRo(p->pGia, pObj); - pGla->fAnd = Gia_ObjIsAnd(pObj); - if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) - continue; - if ( Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ) - { - Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp ); - pGla->nFanins = Vec_IntSize( p->vTemp ); - memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) ); - continue; - } - assert( Gia_ObjIsRo(p->pGia, pObj) ); - pGla->nFanins = 1; - pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value; - pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) ); - } - p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value ); - // abstraction - assert( pGia->vGateClasses != NULL ); - Gla_ManForEachObj( p, pGla ) - { - if ( Vec_IntEntry( pGia->vGateClasses, pGla->iGiaObj ) == 0 ) - continue; - pGla->fAbs = 1; - Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); - } - // other - p->pSat = sat_solver2_new(); - p->nSatVars = 1; - return p; -} - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManStop( Gla_Man_t * p ) -{ - Gla_Obj_t * pGla; - int i; - - if ( p->pPars->fVerbose ) - Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n", - sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat), - sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); - - // stop the refinement manager -// Gia_ManStopP( &p->pGia2 ); - Rnm_ManStop( p->pRnm, 0 ); - - if ( p->pvRefis ) - for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ ) - ABC_FREE( p->pvRefis[i].pArray ); - Gla_ManForEachObj( p, pGla ) - ABC_FREE( pGla->vFrames.pArray ); - Cnf_DataFree( p->pCnf ); - if ( p->pGia0 != NULL ) - Gia_ManStop( p->pGia ); -// Gia_ManStaticFanoutStart( p->pGia0 ); - sat_solver2_delete( p->pSat ); - Vec_IntFreeP( &p->vObjCounts ); - Vec_IntFreeP( &p->vAddedNew ); - Vec_IntFreeP( &p->vCoreCounts ); - Vec_IntFreeP( &p->vProofIds ); - Vec_IntFreeP( &p->vTemp ); - Vec_IntFreeP( &p->vAbs ); - ABC_FREE( p->pvRefis ); - ABC_FREE( p->pObj2Obj ); - ABC_FREE( p->pObjs ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_GlaAbsCount( Gla_Man_t * p, int fRo, int fAnd ) -{ - Gla_Obj_t * pObj; - int i, Counter = 0; - if ( fRo ) - Gla_ManForEachObjAbs( p, pObj, i ) - Counter += (pObj->fRo && pObj->fAbs); - else if ( fAnd ) - Gla_ManForEachObjAbs( p, pObj, i ) - Counter += (pObj->fAnd && pObj->fAbs); - else - Gla_ManForEachObjAbs( p, pObj, i ) - Counter += (pObj->fAbs); - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Derives new abstraction map.] - - Description [Returns 1 if node contains abstracted leaf on the path.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gla_ManTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla, int nUsageCount ) -{ - int Value0, Value1; - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return 1; - Gia_ObjSetTravIdCurrent(p, pObj); - if ( Gia_ObjIsCi(pObj) ) - return 0; - assert( Gia_ObjIsAnd(pObj) ); - Value0 = Gla_ManTranslate_rec( p, Gia_ObjFanin0(pObj), vGla, nUsageCount ); - Value1 = Gla_ManTranslate_rec( p, Gia_ObjFanin1(pObj), vGla, nUsageCount ); - if ( Value0 || Value1 ) - Vec_IntAddToEntry( vGla, Gia_ObjId(p, pObj), nUsageCount ); - return Value0 || Value1; -} -Vec_Int_t * Gla_ManTranslate( Gla_Man_t * p ) -{ - Vec_Int_t * vGla, * vGla2; - Gla_Obj_t * pObj, * pFanin; - Gia_Obj_t * pGiaObj; - int i, k, nUsageCount; - vGla = Vec_IntStart( Gia_ManObjNum(p->pGia) ); - Gla_ManForEachObjAbs( p, pObj, i ) - { - nUsageCount = Vec_IntEntry(p->vCoreCounts, pObj->iGiaObj); - assert( nUsageCount >= 0 ); - if ( nUsageCount == 0 ) - nUsageCount++; - pGiaObj = Gla_ManGiaObj( p, pObj ); - if ( Gia_ObjIsConst0(pGiaObj) || Gia_ObjIsRo(p->pGia, pGiaObj) ) - { - Vec_IntWriteEntry( vGla, pObj->iGiaObj, nUsageCount ); - continue; - } - assert( Gia_ObjIsAnd(pGiaObj) ); - Gia_ManIncrementTravId( p->pGia ); - Gla_ObjForEachFanin( p, pObj, pFanin, k ) - Gia_ObjSetTravIdCurrent( p->pGia, Gla_ManGiaObj(p, pFanin) ); - Gla_ManTranslate_rec( p->pGia, pGiaObj, vGla, nUsageCount ); - } - Vec_IntWriteEntry( vGla, 0, p->pPars->iFrame+1 ); - if ( p->pGia->vLutConfigs ) // use mapping from new to old - { - vGla2 = Vec_IntStart( Gia_ManObjNum(p->pGia0) ); - for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ ) - if ( Vec_IntEntry(vGla, i) ) - Vec_IntWriteEntry( vGla2, Vec_IntEntry(p->pGia->vLutConfigs, i), Vec_IntEntry(vGla, i) ); - Vec_IntFree( vGla ); - return vGla2; - } - return vGla; -} - - -/**Function************************************************************* - - Synopsis [Collect pseudo-PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis ) -{ - Vec_Int_t * vPPis; - Gla_Obj_t * pObj, * pFanin; - int i, k; - vPPis = Vec_IntAlloc( 1000 ); - if ( vPis ) - Vec_IntClear( vPis ); - Gla_ManForEachObjAbs( p, pObj, i ) - { - assert( pObj->fConst || pObj->fRo || pObj->fAnd ); - Gla_ObjForEachFanin( p, pObj, pFanin, k ) - if ( !pFanin->fPi && !pFanin->fAbs ) - Vec_IntPush( vPPis, pObj->Fanins[k] ); - else if ( vPis && pFanin->fPi && !pFanin->fAbs ) - Vec_IntPush( vPis, pObj->Fanins[k] ); - } - Vec_IntUniqify( vPPis ); - Vec_IntReverseOrder( vPPis ); - if ( vPis ) - Vec_IntUniqify( vPis ); - return vPPis; -} -int Gla_ManCountPPis( Gla_Man_t * p ) -{ - Vec_Int_t * vPPis = Gla_ManCollectPPis( p, NULL ); - int RetValue = Vec_IntSize( vPPis ); - Vec_IntFree( vPPis ); - return RetValue; -} -void Gla_ManExplorePPis( Gla_Man_t * p, Vec_Int_t * vPPis ) -{ - static int Round = 0; - Gla_Obj_t * pObj, * pFanin; - int i, j, k, Count; - if ( (Round++ % 5) == 0 ) - return; - j = 0; - Gla_ManForEachObjAbsVec( vPPis, p, pObj, i ) - { - assert( pObj->fAbs == 0 ); - Count = 0; - Gla_ObjForEachFanin( p, pObj, pFanin, k ) - Count += pFanin->fAbs; - if ( Count == 0 || ((Round & 1) && Count == 1) ) - continue; - Vec_IntWriteEntry( vPPis, j++, Gla_ObjId(p, pObj) ); - } -// printf( "\n%d -> %d\n", Vec_IntSize(vPPis), j ); - Vec_IntShrink( vPPis, j ); -} - - -/**Function************************************************************* - - Synopsis [Adds CNF for the given timeframe.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame ) -{ - Gla_Obj_t * pGla = Gla_ManObj( p, iObj ); - int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame ); - assert( !pGla->fPo && !pGla->fRi ); - return (iVar > 0); -} -int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame ) -{ - Gla_Obj_t * pGla = Gla_ManObj( p, iObj ); - int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame ); - assert( !pGla->fPo && !pGla->fRi ); - if ( iVar == 0 ) - { - Vec_IntSetEntry( &pGla->vFrames, iFrame, (iVar = p->nSatVars++) ); - // remember the change - Vec_IntPush( p->vAddedNew, iObj ); - Vec_IntPush( p->vAddedNew, iFrame ); - } - return iVar; -} -void Gla_ManAddClauses( Gla_Man_t * p, int iObj, int iFrame, Vec_Int_t * vLits ) -{ - Gla_Obj_t * pGlaObj = Gla_ManObj( p, iObj ); - int iVar, iVar1, iVar2; - if ( pGlaObj->fConst ) - { - iVar = Gla_ManGetVar( p, iObj, iFrame ); - sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj ); - } - else if ( pGlaObj->fRo ) - { - assert( pGlaObj->nFanins == 1 ); - if ( iFrame == 0 ) - { - iVar = Gla_ManGetVar( p, iObj, iFrame ); - sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj ); - } - else - { - iVar1 = Gla_ManGetVar( p, iObj, iFrame ); - iVar2 = Gla_ManGetVar( p, pGlaObj->Fanins[0], iFrame-1 ); - sat_solver2_add_buffer( p->pSat, iVar1, iVar2, pGlaObj->fCompl0, 0, iObj ); - } - } - else if ( pGlaObj->fAnd ) - { - int i, RetValue, nClauses, iFirstClause, * pLit; - nClauses = p->pCnf->pObj2Count[pGlaObj->iGiaObj]; - iFirstClause = p->pCnf->pObj2Clause[pGlaObj->iGiaObj]; - for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) - { - Vec_IntClear( vLits ); - for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ ) - { - iVar = Gla_ManGetVar( p, lit_var(*pLit), iFrame ); - Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); - } - RetValue = sat_solver2_addclause( p->pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits), iObj ); - } - } - else assert( 0 ); -} -void Gia_GlaAddToCounters( Gla_Man_t * p, Vec_Int_t * vCore ) -{ - Gla_Obj_t * pGla; - int i; - Gla_ManForEachObjAbsVec( vCore, p, pGla, i ) - Vec_IntAddToEntry( p->vCoreCounts, pGla->iGiaObj, 1 ); -} -void Gia_GlaAddToAbs( Gla_Man_t * p, Vec_Int_t * vAbsAdd, int fCheck ) -{ - Gla_Obj_t * pGla; - int i, k = 0; - Gla_ManForEachObjAbsVec( vAbsAdd, p, pGla, i ) - { - if ( fCheck ) - { - assert( pGla->fAbs == 0 ); - if ( p->pSat->pPrf2 ) - Vec_IntWriteEntry( p->vProofIds, Gla_ObjId(p, pGla), p->nProofIds++ ); - } - if ( pGla->fAbs ) - continue; - pGla->fAbs = 1; - Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); - // filter clauses to remove those contained in the abstraction - Vec_IntWriteEntry( vAbsAdd, k++, Gla_ObjId(p, pGla) ); - } - Vec_IntShrink( vAbsAdd, k ); -} -void Gia_GlaAddTimeFrame( Gla_Man_t * p, int f ) -{ - Gla_Obj_t * pObj; - int i; - Gla_ManForEachObjAbs( p, pObj, i ) - Gla_ManAddClauses( p, Gla_ObjId(p, pObj), f, p->vTemp ); - sat_solver2_simplify( p->pSat ); -} -void Gia_GlaAddOneSlice( Gla_Man_t * p, int fCur, Vec_Int_t * vCore ) -{ - int f, i, iGlaObj; - for ( f = fCur; f >= 0; f-- ) - Vec_IntForEachEntry( vCore, iGlaObj, i ) - Gla_ManAddClauses( p, iGlaObj, f, p->vTemp ); - sat_solver2_simplify( p->pSat ); -} -void Gla_ManRollBack( Gla_Man_t * p ) -{ - int i, iObj, iFrame; - Vec_IntForEachEntryDouble( p->vAddedNew, iObj, iFrame, i ) - { - assert( Vec_IntEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame ) > 0 ); - Vec_IntWriteEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame, 0 ); - } - Vec_IntForEachEntryStart( p->vAbs, iObj, i, p->nAbsOld ) - { - assert( Gla_ManObj( p, iObj )->fAbs == 1 ); - Gla_ManObj( p, iObj )->fAbs = 0; - } - Vec_IntShrink( p->vAbs, p->nAbsOld ); -} - - - - - -/**Function************************************************************* - - Synopsis [Finds the set of clauses involved in the UNSAT core.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gla_ManGetOutLit( Gla_Man_t * p, int f ) -{ - Gla_Obj_t * pFanin = Gla_ManObj( p, p->pObjRoot->Fanins[0] ); - int iSat = Vec_IntEntry( &pFanin->vFrames, f ); - assert( iSat > 0 ); - if ( f == 0 && pFanin->fRo && !p->pObjRoot->fCompl0 ) - return -1; - return Abc_Var2Lit( iSat, p->pObjRoot->fCompl0 ); -} -Vec_Int_t * Gla_ManUnsatCore( Gla_Man_t * p, int f, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls ) -{ - Vec_Int_t * vCore = NULL; - int nConfPrev = pSat->stats.conflicts; - int RetValue, iLit = Gla_ManGetOutLit( p, f ); - clock_t clk = clock(); - if ( piRetValue ) - *piRetValue = 1; - // consider special case when PO points to the flop - // this leads to immediate conflict in the first timeframe - if ( iLit == -1 ) - { - vCore = Vec_IntAlloc( 1 ); - Vec_IntPush( vCore, p->pObjRoot->Fanins[0] ); - return vCore; - } - // solve the problem - RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( pnConfls ) - *pnConfls = (int)pSat->stats.conflicts - nConfPrev; - if ( RetValue == l_Undef ) - { - if ( piRetValue ) - *piRetValue = -1; - return NULL; - } - if ( RetValue == l_True ) - { - if ( piRetValue ) - *piRetValue = 0; - return NULL; - } - if ( fVerbose ) - { -// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev ); -// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts ); -// Abc_PrintTime( 1, "Time", clock() - clk ); - } - assert( RetValue == l_False ); - // derive the UNSAT core - clk = clock(); - vCore = (Vec_Int_t *)Sat_ProofCore( pSat ); - if ( vCore ) - Vec_IntSort( vCore, 1 ); - if ( fVerbose ) - { -// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) ); -// Abc_PrintTime( 1, "Time", clock() - clk ); - } - return vCore; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gla_ManAbsPrintFrame( Gla_Man_t * p, int nCoreSize, int nFrames, int nConfls, int nCexes, clock_t Time ) -{ - if ( Abc_FrameIsBatchMode() && nCoreSize <= 0 ) - return; - Abc_Print( 1, "%4d :", nFrames-1 ); - Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Gia_GlaAbsCount(p, 0, 0) / (p->nObjs - Gia_ManPoNum(p->pGia) + Gia_ManCoNum(p->pGia) + 1)) ); - Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 0) ); - Abc_Print( 1, "%5d", Gla_ManCountPPis(p) ); - Abc_Print( 1, "%5d", Gia_GlaAbsCount(p, 1, 0) ); - Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 1) ); - Abc_Print( 1, "%8d", nConfls ); - if ( nCexes == 0 ) - Abc_Print( 1, "%5c", '-' ); - else - Abc_Print( 1, "%5d", nCexes ); -// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) ); - Abc_PrintInt( sat_solver2_nvars(p->pSat) ); - Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); - Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); -// Abc_Print( 1, " %6d", nCoreSize > 0 ? nCoreSize : 0 ); - Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); - Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) ); -// Abc_PrintInt( p->nAbsNew ); -// Abc_PrintInt( p->nLrnNew ); -// Abc_Print( 1, "%4.1f MB", 4.0 * p->nLrnNew * Abc_BitWordNum(p->nAbsNew) / (1<<20) ); - Abc_Print( 1, "%s", (nCoreSize > 0 && nCexes > 0) ? "\n" : "\r" ); - fflush( stdout ); -} -void Gla_ManReportMemory( Gla_Man_t * p ) -{ - Gla_Obj_t * pGla; - double memTot = 0; - double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t); - double memSat = sat_solver2_memory( p->pSat, 1 ); - double memPro = sat_solver2_memory_proof( p->pSat ); - double memMap = p->nObjs * sizeof(Gla_Obj_t) + Gia_ManObjNum(p->pGia) * sizeof(int); - double memRef = Rnm_ManMemoryUsage( p->pRnm ); - double memOth = sizeof(Gla_Man_t); - for ( pGla = p->pObjs; pGla < p->pObjs + p->nObjs; pGla++ ) - memMap += Vec_IntCap(&pGla->vFrames) * sizeof(int); - memOth += Vec_IntCap(p->vAddedNew) * sizeof(int); - memOth += Vec_IntCap(p->vTemp) * sizeof(int); - memOth += Vec_IntCap(p->vAbs) * sizeof(int); - memTot = memAig + memSat + memPro + memMap + memRef + memOth; - ABC_PRMP( "Memory: AIG ", memAig, memTot ); - ABC_PRMP( "Memory: SAT ", memSat, memTot ); - ABC_PRMP( "Memory: Proof ", memPro, memTot ); - ABC_PRMP( "Memory: Map ", memMap, memTot ); - ABC_PRMP( "Memory: Refine ", memRef, memTot ); - ABC_PRMP( "Memory: Other ", memOth, memTot ); - ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); -} - - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_GlaSendAbsracted( Gla_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); - Gia_Man_t * pAbs; - Vec_Int_t * vGateClasses; - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Sending abstracted model...\n" ); - // create abstraction (value of p->pGia is not used here) - vGateClasses = Gla_ManTranslate( p ); - pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses ); - Vec_IntFreeP( &vGateClasses ); - // send it out - Gia_ManToBridgeAbsNetlist( stdout, pAbs ); - Gia_ManStop( pAbs ); -} -void Gia_GlaSendCancel( Gla_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeBadAbs( FILE * pFile ); - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Cancelling previously sent model...\n" ); - Gia_ManToBridgeBadAbs( stdout ); -} - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_GlaDumpAbsracted( Gla_Man_t * p, int fVerbose ) -{ - char * pFileNameDef = "glabs.aig"; - char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef; - Gia_Man_t * pAbs; - Vec_Int_t * vGateClasses; - if ( fVerbose ) - Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); - // create abstraction - vGateClasses = Gla_ManTranslate( p ); - pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses ); - Vec_IntFreeP( &vGateClasses ); - // write into file - Gia_WriteAiger( pAbs, pFileName, 0, 0 ); - Gia_ManStop( pAbs ); -} - - -/**Function************************************************************* - - Synopsis [Performs gate-level abstraction] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_GlaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars, int fStartVta ) -{ - extern int Gia_VtaPerformInt( Gia_Man_t * pAig, Gia_ParVta_t * pPars ); - extern void Ga2_ManDumpStats( Gia_Man_t * pGia, Gia_ParVta_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN ); - Gla_Man_t * p; - Vec_Int_t * vPPis, * vCore;//, * vCore2 = NULL; - Abc_Cex_t * pCex = NULL; - int f, i, iPrev, nConfls, Status, nVarsOld = 0, nCoreSize, fOneIsSent = 0, RetValue = -1; - clock_t clk2, clk = clock(); - // preconditions - assert( Gia_ManPoNum(pAig) == 1 ); - assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax ); - if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) - { - if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) - { - printf( "Sequential miter is trivially UNSAT.\n" ); - return 1; - } - ABC_FREE( pAig->pCexSeq ); - pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); - printf( "Sequential miter is trivially SAT.\n" ); - return 0; - } - - // compute intial abstraction - if ( pAig->vGateClasses == NULL ) - { - if ( fStartVta ) - { - int nFramesMaxOld = pPars->nFramesMax; - int nFramesStartOld = pPars->nFramesStart; - int nTimeOutOld = pPars->nTimeOut; - int nDumpOld = pPars->fDumpVabs; - pPars->nFramesMax = pPars->nFramesStart; - pPars->nFramesStart = Abc_MinInt( pPars->nFramesStart/2 + 1, 3 ); - pPars->nTimeOut = 20; - pPars->fDumpVabs = 0; - RetValue = Gia_VtaPerformInt( pAig, pPars ); - pPars->nFramesMax = nFramesMaxOld; - pPars->nFramesStart = nFramesStartOld; - pPars->nTimeOut = nTimeOutOld; - pPars->fDumpVabs = nDumpOld; - // create gate classes - Vec_IntFreeP( &pAig->vGateClasses ); - if ( pAig->vObjClasses ) - pAig->vGateClasses = Gia_VtaConvertToGla( pAig, pAig->vObjClasses ); - Vec_IntFreeP( &pAig->vObjClasses ); - // return if VTA solve the problem if could not start - if ( RetValue == 0 || pAig->vGateClasses == NULL ) - return RetValue; - } - else - { - pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) ); - Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 ); - Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 ); - } - } - // start the manager - p = Gla_ManStart( pAig, pPars ); - p->timeInit = clock() - clk; - // set runtime limit - if ( p->pPars->nTimeOut ) - sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() ); - // perform initial abstraction - if ( p->pPars->fVerbose ) - { - Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" ); - Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%.\n", - pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin ); - Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n", - pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce ); - Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" ); - } - for ( f = i = iPrev = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++, iPrev = i ) - { - int nConflsBeg = sat_solver2_nconflicts(p->pSat); - p->pPars->iFrame = f; - - // load timeframe - Gia_GlaAddTimeFrame( p, f ); - - // iterate as long as there are counter-examples - for ( i = 0; ; i++ ) - { - clk2 = clock(); - vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls ); -// assert( (vCore != NULL) == (Status == 1) ); - if ( Status == -1 || (p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit) ) // resource limit is reached - { - Prf_ManStopP( &p->pSat->pPrf2 ); -// if ( Gia_ManRegNum(p->pGia) > 1 ) // for comb cases, return the abstraction -// Vec_IntShrink( p->vAbs, p->nAbsOld ); - goto finish; - } - if ( Status == 1 ) - { - Prf_ManStopP( &p->pSat->pPrf2 ); - p->timeUnsat += clock() - clk2; - break; - } - p->timeSat += clock() - clk2; - assert( Status == 0 ); - p->nCexes++; - - // cancel old one if it was sent - if ( Abc_FrameIsBridgeMode() && fOneIsSent ) - { - Gia_GlaSendCancel( p, pPars->fVerbose ); - fOneIsSent = 0; - } - - // perform the refinement - clk2 = clock(); - if ( pPars->fAddLayer ) - { - vPPis = Gla_ManCollectPPis( p, NULL ); -// Gla_ManExplorePPis( p, vPPis ); - } - else - { - vPPis = Gla_ManRefinement( p ); - if ( vPPis == NULL ) - { - Prf_ManStopP( &p->pSat->pPrf2 ); - pCex = p->pGia->pCexSeq; p->pGia->pCexSeq = NULL; - break; - } - } - assert( pCex == NULL ); - - // start proof logging - if ( i == 0 ) - { - // create bookmark to be used for rollback - sat_solver2_bookmark( p->pSat ); - Vec_IntClear( p->vAddedNew ); - p->nAbsOld = Vec_IntSize( p->vAbs ); - nVarsOld = p->nSatVars; -// p->nLrnOld = sat_solver2_nlearnts( p->pSat ); -// p->nAbsNew = 0; -// p->nLrnNew = 0; - - // start incremental proof manager - assert( p->pSat->pPrf2 == NULL ); - if ( p->pSat->pPrf1 == NULL ) - p->pSat->pPrf2 = Prf_ManAlloc(); - if ( p->pSat->pPrf2 ) - { - p->nProofIds = 0; - Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); - Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) ); - } - } - else - { - // resize the proof logger - if ( p->pSat->pPrf2 ) - Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) ); - } - - Gia_GlaAddToAbs( p, vPPis, 1 ); - Gia_GlaAddOneSlice( p, f, vPPis ); - Vec_IntFree( vPPis ); - - // print the result (do not count it towards change) - if ( p->pPars->fVerbose ) - Gla_ManAbsPrintFrame( p, -1, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk ); - } - if ( pCex != NULL ) - break; - assert( Status == 1 ); - - // valid core is obtained - nCoreSize = 1; - if ( vCore ) - { - nCoreSize += Vec_IntSize( vCore ); - Gia_GlaAddToCounters( p, vCore ); - } - if ( i == 0 ) - { - p->pPars->nFramesNoChange++; - Vec_IntFreeP( &vCore ); - } - else - { - p->pPars->nFramesNoChange = 0; -// p->nAbsNew = Vec_IntSize( p->vAbs ) - p->nAbsOld; -// p->nLrnNew = Abc_AbsInt( sat_solver2_nlearnts( p->pSat ) - p->nLrnOld ); - // update the SAT solver - sat_solver2_rollback( p->pSat ); - // update storage - Gla_ManRollBack( p ); - p->nSatVars = nVarsOld; - // load this timeframe - Gia_GlaAddToAbs( p, vCore, 0 ); - Gia_GlaAddOneSlice( p, f, vCore ); - Vec_IntFree( vCore ); - // run SAT solver - clk2 = clock(); - vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls ); - p->timeUnsat += clock() - clk2; -// assert( (vCore != NULL) == (Status == 1) ); - Vec_IntFreeP( &vCore ); - if ( Status == -1 ) // resource limit is reached - break; - if ( Status == 0 ) - { - assert( 0 ); - // Vta_ManSatVerify( p ); - // make sure, there was no initial abstraction (otherwise, it was invalid) - assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart ); - // pCex = Vga_ManDeriveCex( p ); - break; - } - } - // print the result - if ( p->pPars->fVerbose ) - Gla_ManAbsPrintFrame( p, nCoreSize, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk ); - - if ( f > 2 && iPrev > 0 && i == 0 ) // change has happened - { - if ( Abc_FrameIsBridgeMode() ) - { - // cancel old one if it was sent - if ( fOneIsSent ) - Gia_GlaSendCancel( p, pPars->fVerbose ); - // send new one - Gia_GlaSendAbsracted( p, pPars->fVerbose ); - fOneIsSent = 1; - } - - // dump the model into file - if ( p->pPars->fDumpVabs ) - { - char Command[1000]; - Abc_FrameSetStatus( -1 ); - Abc_FrameSetCex( NULL ); - Abc_FrameSetNFrames( f+1 ); - sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") ); - Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); - Gia_GlaDumpAbsracted( p, pPars->fVerbose ); - } - } - - // check if the number of objects is below limit - if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 ) - { - Status = -1; - break; - } - } -finish: - // analize the results - if ( pCex == NULL ) - { - if ( p->pPars->fVerbose && Status == -1 ) - printf( "\n" ); -// if ( pAig->vGateClasses != NULL ) -// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); - Vec_IntFreeP( &pAig->vGateClasses ); - pAig->vGateClasses = Gla_ManTranslate( p ); - if ( Status == -1 ) - { - if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) - Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange ); - else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) - Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange ); - else if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 ) - Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f ); - else - Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f ); - } - else - { - p->pPars->iFrame++; - Abc_Print( 1, "GLA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange ); - } - } - else - { - if ( p->pPars->fVerbose ) - printf( "\n" ); - ABC_FREE( pAig->pCexSeq ); - pAig->pCexSeq = pCex; - if ( !Gia_ManVerifyCex( pAig, pCex, 0 ) ) - Abc_Print( 1, " Gia_GlaPerform(): CEX verification has failed!\n" ); - Abc_Print( 1, "Counter-example detected in frame %d. ", f ); - p->pPars->iFrame = pCex->iFrame - 1; - Vec_IntFreeP( &pAig->vGateClasses ); - RetValue = 0; - } - Abc_PrintTime( 1, "Time", clock() - clk ); - if ( p->pPars->fVerbose ) - { - p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit; - ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk ); - ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); - ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); - ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); - ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); - ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); - Gla_ManReportMemory( p ); - } -// Ga2_ManDumpStats( pAig, p->pPars, p->pSat, p->pPars->iFrame, 1 ); - Gla_ManStop( p ); - fflush( stdout ); - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsGla2.c b/src/aig/gia/giaAbsGla2.c deleted file mode 100644 index ca424b44..00000000 --- a/src/aig/gia/giaAbsGla2.c +++ /dev/null @@ -1,1899 +0,0 @@ -/**CFile**************************************************************** - - FileName [gia.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Scalable gate-level abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAbsRef.h" -//#include "giaAbsRef2.h" -#include "sat/cnf/cnf.h" -#include "sat/bsat/satSolver2.h" -#include "base/main/main.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define GA2_BIG_NUM 0x3FFFFFF0 - -typedef struct Ga2_Man_t_ Ga2_Man_t; // manager -struct Ga2_Man_t_ -{ - // user data - Gia_Man_t * pGia; // working AIG manager - Gia_ParVta_t * pPars; // parameters - // markings - Vec_Ptr_t * vCnfs; // for each object: CNF0, CNF1 - // abstraction - Vec_Int_t * vIds; // abstraction ID for each GIA object - Vec_Int_t * vProofIds; // mapping of GIA objects into their proof IDs - Vec_Int_t * vAbs; // array of abstracted objects - Vec_Int_t * vValues; // array of objects with abstraction ID assigned - int nProofIds; // the counter of proof IDs - int LimAbs; // limit value for starting abstraction objects - int LimPpi; // limit value for starting PPI objects - int nMarked; // total number of marked nodes and flops - // refinement - Rnm_Man_t * pRnm; // refinement manager -// Rf2_Man_t * pRf2; // refinement manager - // SAT solver and variables - Vec_Ptr_t * vId2Lit; // mapping, for each timeframe, of object ID into SAT literal - sat_solver2 * pSat; // incremental SAT solver - int nSatVars; // the number of SAT variables - int nCexes; // the number of counter-examples - int nObjAdded; // objs added during refinement - // hash table - int * pTable; - int nTable; - int nHashHit; - int nHashMiss; - int nHashOver; - // temporaries - Vec_Int_t * vLits; - Vec_Int_t * vIsopMem; - char * pSopSizes, ** pSops; // CNF representation - // statistics - clock_t timeStart; - clock_t timeInit; - clock_t timeSat; - clock_t timeUnsat; - clock_t timeCex; - clock_t timeOther; -}; - -static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); } -static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); } -static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); } -static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); } -static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); } -static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; } - -static inline int Ga2_ObjId( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vIds, Gia_ObjId(p->pGia, pObj)); } -static inline void Ga2_ObjSetId( Ga2_Man_t * p, Gia_Obj_t * pObj, int i ) { Vec_IntWriteEntry(p->vIds, Gia_ObjId(p->pGia, pObj), i); } - -static inline Vec_Int_t * Ga2_ObjCnf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj) ); } -static inline Vec_Int_t * Ga2_ObjCnf1( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj)+1 ); } - -static inline int Ga2_ObjIsAbs0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < p->LimAbs; } -static inline int Ga2_ObjIsLeaf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= p->LimAbs && Ga2_ObjId(p,pObj) < p->LimPpi; } -static inline int Ga2_ObjIsAbs( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjCnf0(p,pObj); } -static inline int Ga2_ObjIsLeaf( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && !Ga2_ObjCnf0(p,pObj); } - -static inline Vec_Int_t * Ga2_MapFrameMap( Ga2_Man_t * p, int f ) { return (Vec_Int_t *)Vec_PtrEntry( p->vId2Lit, f ); } - -// returns literal of this object, or -1 if SAT variable of the object is not assigned -static inline int Ga2_ObjFindLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) -{ -// int Id = Ga2_ObjId(p,pObj); - assert( Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < Vec_IntSize(p->vValues) ); - return Vec_IntEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj) ); -} -// inserts literal of this object -static inline void Ga2_ObjAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int Lit ) -{ -// assert( Lit > 1 ); - assert( Ga2_ObjFindLit(p, pObj, f) == -1 ); - Vec_IntSetEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj), Lit ); -} -// returns or inserts-and-returns literal of this object -static inline int Ga2_ObjFindOrAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) -{ - int Lit = Ga2_ObjFindLit( p, pObj, f ); - if ( Lit == -1 ) - { - Lit = toLitCond( p->nSatVars++, 0 ); - Ga2_ObjAddLit( p, pObj, f, Lit ); - } -// assert( Lit > 1 ); - return Lit; -} - - -// calling pthreads -extern void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ); -extern void Gia_Ga2ProveCancel( int fVerbose ); -extern int Gia_Ga2ProveCheck( int fVerbose ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes truth table for the marked node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ga2_ObjComputeTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst ) -{ - unsigned Val0, Val1; - if ( pObj->fPhase && !fFirst ) - return pObj->Value; - assert( Gia_ObjIsAnd(pObj) ); - Val0 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin0(pObj), 0 ); - Val1 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin1(pObj), 0 ); - return (Gia_ObjFaninC0(pObj) ? ~Val0 : Val0) & (Gia_ObjFaninC1(pObj) ? ~Val1 : Val1); -} -unsigned Ga2_ManComputeTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves ) -{ - static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; - Gia_Obj_t * pObj; - unsigned Res; - int i; - Gia_ManForEachObjVec( vLeaves, p, pObj, i ) - pObj->Value = uTruth5[i]; - Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); - Gia_ManForEachObjVec( vLeaves, p, pObj, i ) - pObj->Value = 0; - return Res; -} - -/**Function************************************************************* - - Synopsis [Returns AIG marked for CNF generation.] - - Description [The marking satisfies the following requirements: - Each marked node has the number of marked fanins no more than N.] - - SideEffects [Uses pObj->fPhase to store the markings.] - - SeeAlso [] - -***********************************************************************/ -int Ga2_ManBreakTree_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst, int N ) -{ // breaks a tree rooted at the node into N-feasible subtrees - int Val0, Val1; - if ( pObj->fPhase && !fFirst ) - return 1; - Val0 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin0(pObj), 0, N ); - Val1 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin1(pObj), 0, N ); - if ( Val0 + Val1 < N ) - return Val0 + Val1; - if ( Val0 + Val1 == N ) - { - pObj->fPhase = 1; - return 1; - } - assert( Val0 + Val1 > N ); - assert( Val0 < N && Val1 < N ); - if ( Val0 >= Val1 ) - { - Gia_ObjFanin0(pObj)->fPhase = 1; - Val0 = 1; - } - else - { - Gia_ObjFanin1(pObj)->fPhase = 1; - Val1 = 1; - } - if ( Val0 + Val1 < N ) - return Val0 + Val1; - if ( Val0 + Val1 == N ) - { - pObj->fPhase = 1; - return 1; - } - assert( 0 ); - return -1; -} -int Ga2_ManCheckNodesAnd( Gia_Man_t * p, Vec_Int_t * vNodes ) -{ - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObjVec( vNodes, p, pObj, i ) - if ( (!Gia_ObjFanin0(pObj)->fPhase && Gia_ObjFaninC0(pObj)) || - (!Gia_ObjFanin1(pObj)->fPhase && Gia_ObjFaninC1(pObj)) ) - return 0; - return 1; -} -void Ga2_ManCollectNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes, int fFirst ) -{ - if ( pObj->fPhase && !fFirst ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Ga2_ManCollectNodes_rec( p, Gia_ObjFanin0(pObj), vNodes, 0 ); - Ga2_ManCollectNodes_rec( p, Gia_ObjFanin1(pObj), vNodes, 0 ); - Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); - -} -void Ga2_ManCollectLeaves_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, int fFirst ) -{ - if ( pObj->fPhase && !fFirst ) - { - Vec_IntPushUnique( vLeaves, Gia_ObjId(p, pObj) ); - return; - } - assert( Gia_ObjIsAnd(pObj) ); - Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin0(pObj), vLeaves, 0 ); - Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin1(pObj), vLeaves, 0 ); -} -int Ga2_ManMarkup( Gia_Man_t * p, int N, int fSimple ) -{ - static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; -// clock_t clk = clock(); - Vec_Int_t * vLeaves; - Gia_Obj_t * pObj; - int i, k, Leaf, CountMarks; - - vLeaves = Vec_IntAlloc( 100 ); - - if ( fSimple ) - { - Gia_ManForEachObj( p, pObj, i ) - pObj->fPhase = !Gia_ObjIsCo(pObj); - } - else - { - // label nodes with multiple fanouts and inputs MUXes - Gia_ManForEachObj( p, pObj, i ) - { - pObj->Value = 0; - if ( !Gia_ObjIsAnd(pObj) ) - continue; - Gia_ObjFanin0(pObj)->Value++; - Gia_ObjFanin1(pObj)->Value++; - if ( !Gia_ObjIsMuxType(pObj) ) - continue; - Gia_ObjFanin0(Gia_ObjFanin0(pObj))->Value++; - Gia_ObjFanin1(Gia_ObjFanin0(pObj))->Value++; - Gia_ObjFanin0(Gia_ObjFanin1(pObj))->Value++; - Gia_ObjFanin1(Gia_ObjFanin1(pObj))->Value++; - } - Gia_ManForEachObj( p, pObj, i ) - { - pObj->fPhase = 0; - if ( Gia_ObjIsAnd(pObj) ) - pObj->fPhase = (pObj->Value > 1); - else if ( Gia_ObjIsCo(pObj) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else - pObj->fPhase = 1; - } - // add marks when needed - Gia_ManForEachAnd( p, pObj, i ) - { - if ( !pObj->fPhase ) - continue; - Vec_IntClear( vLeaves ); - Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 ); - if ( Vec_IntSize(vLeaves) > N ) - Ga2_ManBreakTree_rec( p, pObj, 1, N ); - } - } - - // verify that the tree is split correctly - Vec_IntFreeP( &p->vMapping ); - p->vMapping = Vec_IntStart( Gia_ManObjNum(p) ); - Gia_ManForEachRo( p, pObj, i ) - { - Gia_Obj_t * pObjRi = Gia_ObjRoToRi(p, pObj); - assert( pObj->fPhase ); - assert( Gia_ObjFanin0(pObjRi)->fPhase ); - // create map - Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); - Vec_IntPush( p->vMapping, 1 ); - Vec_IntPush( p->vMapping, Gia_ObjFaninId0p(p, pObjRi) ); - Vec_IntPush( p->vMapping, Gia_ObjFaninC0(pObjRi) ? 0x55555555 : 0xAAAAAAAA ); - Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter - } - CountMarks = Gia_ManRegNum(p); - Gia_ManForEachAnd( p, pObj, i ) - { - if ( !pObj->fPhase ) - continue; - Vec_IntClear( vLeaves ); - Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 ); - assert( Vec_IntSize(vLeaves) <= N ); - // create map - Vec_IntWriteEntry( p->vMapping, i, Vec_IntSize(p->vMapping) ); - Vec_IntPush( p->vMapping, Vec_IntSize(vLeaves) ); - Vec_IntForEachEntry( vLeaves, Leaf, k ) - { - Vec_IntPush( p->vMapping, Leaf ); - Gia_ManObj(p, Leaf)->Value = uTruth5[k]; - assert( Gia_ManObj(p, Leaf)->fPhase ); - } - Vec_IntPush( p->vMapping, (int)Ga2_ObjComputeTruth_rec( p, pObj, 1 ) ); - Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter - CountMarks++; - } -// Abc_PrintTime( 1, "Time", clock() - clk ); - Vec_IntFree( vLeaves ); - Gia_ManCleanValue( p ); - return CountMarks; -} -void Ga2_ManComputeTest( Gia_Man_t * p ) -{ - clock_t clk; -// unsigned uTruth; - Gia_Obj_t * pObj; - int i, Counter = 0; - clk = clock(); - Ga2_ManMarkup( p, 5, 0 ); - Abc_PrintTime( 1, "Time", clock() - clk ); - Gia_ManForEachAnd( p, pObj, i ) - { - if ( !pObj->fPhase ) - continue; -// uTruth = Ga2_ObjTruth( p, pObj ); -// printf( "%6d : ", Counter ); -// Kit_DsdPrintFromTruth( &uTruth, Ga2_ObjLeaveNum(p, pObj) ); -// printf( "\n" ); - Counter++; - } - Abc_Print( 1, "Marked AND nodes = %6d. ", Counter ); - Abc_PrintTime( 1, "Time", clock() - clk ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ga2_Man_t * Ga2_ManStart( Gia_Man_t * pGia, Gia_ParVta_t * pPars ) -{ - Ga2_Man_t * p; - p = ABC_CALLOC( Ga2_Man_t, 1 ); - p->timeStart = clock(); - // user data - p->pGia = pGia; - p->pPars = pPars; - // markings - p->nMarked = Ga2_ManMarkup( pGia, 5, pPars->fUseSimple ); - p->vCnfs = Vec_PtrAlloc( 1000 ); - Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) ); - Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) ); - // abstraction - p->vIds = Vec_IntStartFull( Gia_ManObjNum(pGia) ); - p->vProofIds = Vec_IntAlloc( 0 ); - p->vAbs = Vec_IntAlloc( 1000 ); - p->vValues = Vec_IntAlloc( 1000 ); - // add constant node to abstraction - Ga2_ObjSetId( p, Gia_ManConst0(pGia), 0 ); - Vec_IntPush( p->vValues, 0 ); - Vec_IntPush( p->vAbs, 0 ); - // refinement - p->pRnm = Rnm_ManStart( pGia ); -// p->pRf2 = Rf2_ManStart( pGia ); - // SAT solver and variables - p->vId2Lit = Vec_PtrAlloc( 1000 ); - // temporaries - p->vLits = Vec_IntAlloc( 100 ); - p->vIsopMem = Vec_IntAlloc( 100 ); - Cnf_ReadMsops( &p->pSopSizes, &p->pSops ); - // hash table - p->nTable = Abc_PrimeCudd(1<<18); - p->pTable = ABC_CALLOC( int, 6 * p->nTable ); - return p; -} - -void Ga2_ManDumpStats( Gia_Man_t * pGia, Gia_ParVta_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN ) -{ - FILE * pFile; - char pFileName[32]; - sprintf( pFileName, "stats_gla%s%s.txt", fUseN ? "n":"", pPars->fUseFullProof ? "p":"" ); - - pFile = fopen( pFileName, "a+" ); - - fprintf( pFile, "%s pi=%d ff=%d and=%d mem=%d bmc=%d", - pGia->pName, - Gia_ManPiNum(pGia), Gia_ManRegNum(pGia), Gia_ManAndNum(pGia), - (int)(1 + sat_solver2_memory_proof(pSat)/(1<<20)), - iFrame ); - - if ( pGia->vGateClasses ) - fprintf( pFile, " ff=%d and=%d", - Gia_GlaCountFlops( pGia, pGia->vGateClasses ), - Gia_GlaCountNodes( pGia, pGia->vGateClasses ) ); - - fprintf( pFile, "\n" ); - fclose( pFile ); -} -void Ga2_ManReportMemory( Ga2_Man_t * p ) -{ - double memTot = 0; - double memAig = 1.0 * p->pGia->nObjsAlloc * sizeof(Gia_Obj_t) + Vec_IntMemory(p->pGia->vMapping); - double memSat = sat_solver2_memory( p->pSat, 1 ); - double memPro = sat_solver2_memory_proof( p->pSat ); - double memMap = Vec_VecMemoryInt( (Vec_Vec_t *)p->vId2Lit ); - double memRef = Rnm_ManMemoryUsage( p->pRnm ); - double memHash= sizeof(int) * 6 * p->nTable; - double memOth = sizeof(Ga2_Man_t); - memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCnfs ); - memOth += Vec_IntMemory( p->vIds ); - memOth += Vec_IntMemory( p->vProofIds ); - memOth += Vec_IntMemory( p->vAbs ); - memOth += Vec_IntMemory( p->vValues ); - memOth += Vec_IntMemory( p->vLits ); - memOth += Vec_IntMemory( p->vIsopMem ); - memOth += 336450 + (sizeof(char) + sizeof(char*)) * 65536; - memTot = memAig + memSat + memPro + memMap + memRef + memHash + memOth; - ABC_PRMP( "Memory: AIG ", memAig, memTot ); - ABC_PRMP( "Memory: SAT ", memSat, memTot ); - ABC_PRMP( "Memory: Proof ", memPro, memTot ); - ABC_PRMP( "Memory: Map ", memMap, memTot ); - ABC_PRMP( "Memory: Refine ", memRef, memTot ); - ABC_PRMP( "Memory: Hash ", memHash,memTot ); - ABC_PRMP( "Memory: Other ", memOth, memTot ); - ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); -} -void Ga2_ManStop( Ga2_Man_t * p ) -{ - Vec_IntFreeP( &p->pGia->vMapping ); - Gia_ManSetPhase( p->pGia ); - if ( p->pPars->fVerbose ) - Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d ObjsAdded = %d\n", - sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), - sat_solver2_nconflicts(p->pSat), sat_solver2_nlearnts(p->pSat), - p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); - if ( p->pPars->fVerbose ) - Abc_Print( 1, "Hash hits = %d. Hash misses = %d. Hash overs = %d.\n", - p->nHashHit, p->nHashMiss, p->nHashOver ); - - if( p->pSat ) sat_solver2_delete( p->pSat ); - Vec_VecFree( (Vec_Vec_t *)p->vCnfs ); - Vec_VecFree( (Vec_Vec_t *)p->vId2Lit ); - Vec_IntFree( p->vIds ); - Vec_IntFree( p->vProofIds ); - Vec_IntFree( p->vAbs ); - Vec_IntFree( p->vValues ); - Vec_IntFree( p->vLits ); - Vec_IntFree( p->vIsopMem ); - Rnm_ManStop( p->pRnm, 0 ); -// Rf2_ManStop( p->pRf2, p->pPars->fVerbose ); - ABC_FREE( p->pTable ); - ABC_FREE( p->pSopSizes ); - ABC_FREE( p->pSops[1] ); - ABC_FREE( p->pSops ); - ABC_FREE( p ); -} - - -/**Function************************************************************* - - Synopsis [Computes a minimized truth table.] - - Description [Input literals can be 0/1 (const 0/1), non-trivial literals - (integers that are more than 1) and unassigned literals (large integers). - This procedure computes the truth table that essentially depends on input - variables ordered in the increasing order of their positive literals.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Ga2_ObjTruthDepends( unsigned t, int v ) -{ - static unsigned uInvTruth5[5] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF }; - assert( v >= 0 && v <= 4 ); - return ((t ^ (t >> (1 << v))) & uInvTruth5[v]); -} -unsigned Ga2_ObjComputeTruthSpecial( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vLits ) -{ - int fVerbose = 0; - static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; - unsigned Res; - Gia_Obj_t * pObj; - int i, Entry; -// int Id = Gia_ObjId(p, pRoot); - assert( Gia_ObjIsAnd(pRoot) ); - - if ( fVerbose ) - printf( "Object %d.\n", Gia_ObjId(p, pRoot) ); - - // assign elementary truth tables - Gia_ManForEachObjVec( vLeaves, p, pObj, i ) - { - Entry = Vec_IntEntry( vLits, i ); - assert( Entry >= 0 ); - if ( Entry == 0 ) - pObj->Value = 0; - else if ( Entry == 1 ) - pObj->Value = ~0; - else // non-trivial literal - pObj->Value = uTruth5[i]; - if ( fVerbose ) - printf( "%d ", Entry ); - } - - if ( fVerbose ) - { - Res = Ga2_ObjTruth( p, pRoot ); -// Kit_DsdPrintFromTruth( &Res, Vec_IntSize(vLeaves) ); - printf( "\n" ); - } - - // compute truth table - Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); - if ( Res != 0 && Res != ~0 ) - { - // find essential variables - int nUsed = 0, pUsed[5]; - for ( i = 0; i < Vec_IntSize(vLeaves); i++ ) - if ( Ga2_ObjTruthDepends( Res, i ) ) - pUsed[nUsed++] = i; - assert( nUsed > 0 ); - // order positions by literal value - Vec_IntSelectSortCost( pUsed, nUsed, vLits ); - assert( Vec_IntEntry(vLits, pUsed[0]) <= Vec_IntEntry(vLits, pUsed[nUsed-1]) ); - // assign elementary truth tables to the leaves - Gia_ManForEachObjVec( vLeaves, p, pObj, i ) - { - Entry = Vec_IntEntry( vLits, i ); - assert( Entry >= 0 ); - if ( Entry == 0 ) - pObj->Value = 0; - else if ( Entry == 1 ) - pObj->Value = ~0; - else // non-trivial literal - pObj->Value = 0xDEADCAFE; // not important - } - for ( i = 0; i < nUsed; i++ ) - { - Entry = Vec_IntEntry( vLits, pUsed[i] ); - assert( Entry > 1 ); - pObj = Gia_ManObj( p, Vec_IntEntry(vLeaves, pUsed[i]) ); - pObj->Value = Abc_LitIsCompl(Entry) ? ~uTruth5[i] : uTruth5[i]; -// pObj->Value = uTruth5[i]; - // remember this literal - pUsed[i] = Abc_LitRegular(Entry); -// pUsed[i] = Entry; - } - // compute truth table - Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); - // reload the literals - Vec_IntClear( vLits ); - for ( i = 0; i < nUsed; i++ ) - { - Vec_IntPush( vLits, pUsed[i] ); - assert( Ga2_ObjTruthDepends(Res, i) ); - if ( fVerbose ) - printf( "%d ", pUsed[i] ); - } - for ( ; i < 5; i++ ) - assert( !Ga2_ObjTruthDepends(Res, i) ); - -if ( fVerbose ) -{ -// Kit_DsdPrintFromTruth( &Res, nUsed ); - printf( "\n" ); -} - - } - else - { - -if ( fVerbose ) -{ - Vec_IntClear( vLits ); - printf( "Const %d\n", Res > 0 ); -} - - } - Gia_ManForEachObjVec( vLeaves, p, pObj, i ) - pObj->Value = 0; - return Res; -} - -/**Function************************************************************* - - Synopsis [Returns CNF of the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover ) -{ - extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ); - int RetValue; - assert( nVars <= 5 ); - // transform truth table into the SOP - RetValue = Kit_TruthIsop( &uTruth, nVars, vCover, 0 ); - assert( RetValue == 0 ); - // check the case of constant cover - return Vec_IntDup( vCover ); -} - -/**Function************************************************************* - - Synopsis [Derives CNF for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Ga2_ManCnfAddDynamic( Ga2_Man_t * p, int uTruth, int Lits[], int iLitOut, int ProofId ) -{ - int i, k, b, Cube, nClaLits, ClaLits[6]; -// assert( uTruth > 0 && uTruth < 0xffff ); - for ( i = 0; i < 2; i++ ) - { - if ( i ) - uTruth = 0xffff & ~uTruth; -// Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); - for ( k = 0; k < p->pSopSizes[uTruth]; k++ ) - { - nClaLits = 0; - ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut; - Cube = p->pSops[uTruth][k]; - for ( b = 3; b >= 0; b-- ) - { - if ( Cube % 3 == 0 ) // value 0 --> add positive literal - { - assert( Lits[b] > 1 ); - ClaLits[nClaLits++] = Lits[b]; - } - else if ( Cube % 3 == 1 ) // value 1 --> add negative literal - { - assert( Lits[b] > 1 ); - ClaLits[nClaLits++] = lit_neg(Lits[b]); - } - Cube = Cube / 3; - } - sat_solver2_addclause( p->pSat, ClaLits, ClaLits+nClaLits, ProofId ); - } - } -} -void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int Lits[], int iLitOut, int ProofId ) -{ - Vec_Int_t * vCnf; - int i, k, b, Cube, Literal, nClaLits, ClaLits[6]; - for ( i = 0; i < 2; i++ ) - { - vCnf = i ? vCnf1 : vCnf0; - Vec_IntForEachEntry( vCnf, Cube, k ) - { - nClaLits = 0; - ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut; - for ( b = 0; b < 5; b++ ) - { - Literal = 3 & (Cube >> (b << 1)); - if ( Literal == 1 ) // value 0 --> add positive literal - { -// assert( Lits[b] > 1 ); - ClaLits[nClaLits++] = Lits[b]; - } - else if ( Literal == 2 ) // value 1 --> add negative literal - { -// assert( Lits[b] > 1 ); - ClaLits[nClaLits++] = lit_neg(Lits[b]); - } - else if ( Literal != 0 ) - assert( 0 ); - } - sat_solver2_addclause( pSat, ClaLits, ClaLits+nClaLits, ProofId ); - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Saig_ManBmcHashKey( int * pArray ) -{ - static int s_Primes[5] = { 12582917, 25165843, 50331653, 100663319, 201326611 }; - unsigned i, Key = 0; - for ( i = 0; i < 5; i++ ) - Key += pArray[i] * s_Primes[i]; - return Key; -} -static inline int * Saig_ManBmcLookup( Ga2_Man_t * p, int * pArray ) -{ - int * pTable = p->pTable + 6 * (Saig_ManBmcHashKey(pArray) % p->nTable); - if ( memcmp( pTable, pArray, 20 ) ) - { - if ( pTable[0] == 0 ) - p->nHashMiss++; - else - p->nHashOver++; - memcpy( pTable, pArray, 20 ); - pTable[5] = 0; - } - else - p->nHashHit++; - assert( pTable + 5 < pTable + 6 * p->nTable ); - return pTable + 5; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Ga2_ManSetupNode( Ga2_Man_t * p, Gia_Obj_t * pObj, int fAbs ) -{ - unsigned uTruth; - int nLeaves; -// int Id = Gia_ObjId(p->pGia, pObj); - assert( pObj->fPhase ); - assert( Vec_PtrSize(p->vCnfs) == 2 * Vec_IntSize(p->vValues) ); - // assign abstraction ID to the node - if ( Ga2_ObjId(p,pObj) == -1 ) - { - Ga2_ObjSetId( p, pObj, Vec_IntSize(p->vValues) ); - Vec_IntPush( p->vValues, Gia_ObjId(p->pGia, pObj) ); - Vec_PtrPush( p->vCnfs, NULL ); - Vec_PtrPush( p->vCnfs, NULL ); - } - assert( Ga2_ObjCnf0(p, pObj) == NULL ); - if ( !fAbs ) - return; - Vec_IntPush( p->vAbs, Gia_ObjId(p->pGia, pObj) ); - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); - // compute parameters - nLeaves = Ga2_ObjLeaveNum(p->pGia, pObj); - uTruth = Ga2_ObjTruth( p->pGia, pObj ); - // create CNF for pos/neg phases - Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), Ga2_ManCnfCompute( uTruth, nLeaves, p->vIsopMem) ); - Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, Ga2_ManCnfCompute(~uTruth, nLeaves, p->vIsopMem) ); -} - -static inline void Ga2_ManAddToAbsOneStatic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int fUseId ) -{ - Vec_Int_t * vLeaves; - Gia_Obj_t * pLeaf; - int k, Lit, iLitOut = Ga2_ObjFindOrAddLit( p, pObj, f ); - assert( iLitOut > 1 ); - assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); - if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) ) - { - iLitOut = Abc_LitNot( iLitOut ); - sat_solver2_addclause( p->pSat, &iLitOut, &iLitOut + 1, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 ); - } - else - { - int fUseStatic = 1; - Vec_IntClear( p->vLits ); - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, k ) - { - Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f - Gia_ObjIsRo(p->pGia, pObj) ); - Vec_IntPush( p->vLits, Lit ); - if ( Lit < 2 ) - fUseStatic = 0; - } - if ( fUseStatic || Gia_ObjIsRo(p->pGia, pObj) ) - Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), iLitOut, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 ); - else - { - unsigned uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits ); - Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), iLitOut, Gia_ObjId(p->pGia, pObj) ); - } - } -} -static inline void Ga2_ManAddToAbsOneDynamic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) -{ -// int Id = Gia_ObjId(p->pGia, pObj); - Vec_Int_t * vLeaves; - Gia_Obj_t * pLeaf; - unsigned uTruth; - int i, Lit; - - assert( Ga2_ObjIsAbs0(p, pObj) ); - assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); - if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) ) - { - Ga2_ObjAddLit( p, pObj, f, 0 ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - // if flop is included in the abstraction, but its driver is not - // flop input driver has no variable assigned -- we assign it here - pLeaf = Gia_ObjRoToRi( p->pGia, pObj ); - Lit = Ga2_ObjFindOrAddLit( p, Gia_ObjFanin0(pLeaf), f-1 ); - assert( Lit >= 0 ); - Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(pLeaf) ); - Ga2_ObjAddLit( p, pObj, f, Lit ); - } - else - { - assert( Gia_ObjIsAnd(pObj) ); - Vec_IntClear( p->vLits ); - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i ) - { - if ( Ga2_ObjIsAbs0(p, pLeaf) ) // belongs to original abstraction - { - Lit = Ga2_ObjFindLit( p, pLeaf, f ); - assert( Lit >= 0 ); - } - else if ( Ga2_ObjIsLeaf0(p, pLeaf) ) // belongs to original PPIs - { - Lit = Ga2_ObjFindLit( p, pLeaf, f ); -// Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); - if ( Lit == -1 ) - { - Lit = GA2_BIG_NUM + 2*i; -// assert( 0 ); - } - } - else assert( 0 ); - Vec_IntPush( p->vLits, Lit ); - } - - // minimize truth table - uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits ); - if ( uTruth == 0 || uTruth == ~0 ) // const 0 / 1 - { - Lit = (uTruth > 0); - Ga2_ObjAddLit( p, pObj, f, Lit ); - } - else if ( uTruth == 0xAAAAAAAA || uTruth == 0x55555555 ) // buffer / inverter - { - Lit = Vec_IntEntry( p->vLits, 0 ); - if ( Lit >= GA2_BIG_NUM ) - { - pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) ); - Lit = Ga2_ObjFindLit( p, pLeaf, f ); - assert( Lit == -1 ); - Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); - } - assert( Lit >= 0 ); - Lit = Abc_LitNotCond( Lit, uTruth == 0x55555555 ); - Ga2_ObjAddLit( p, pObj, f, Lit ); - assert( Lit < 10000000 ); - } - else - { - assert( Vec_IntSize(p->vLits) > 1 && Vec_IntSize(p->vLits) < 6 ); - // replace literals - Vec_IntForEachEntry( p->vLits, Lit, i ) - { - if ( Lit >= GA2_BIG_NUM ) - { - pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) ); - Lit = Ga2_ObjFindLit( p, pLeaf, f ); - assert( Lit == -1 ); - Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); - Vec_IntWriteEntry( p->vLits, i, Lit ); - } - assert( Lit < 10000000 ); - } - - // add new nodes - if ( Vec_IntSize(p->vLits) == 5 ) - { - Vec_IntClear( p->vLits ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i ) - Vec_IntPush( p->vLits, Ga2_ObjFindOrAddLit( p, pLeaf, f ) ); - Lit = Ga2_ObjFindOrAddLit(p, pObj, f); - Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), Lit, -1 ); - } - else - { -// int fUseHash = 1; - if ( !p->pPars->fSkipHash ) - { - int * pLookup, nSize = Vec_IntSize(p->vLits); - assert( Vec_IntSize(p->vLits) < 5 ); - assert( Vec_IntEntry(p->vLits, 0) <= Vec_IntEntryLast(p->vLits) ); - assert( Ga2_ObjFindLit(p, pObj, f) == -1 ); - for ( i = Vec_IntSize(p->vLits); i < 4; i++ ) - Vec_IntPush( p->vLits, GA2_BIG_NUM ); - Vec_IntPush( p->vLits, (int)uTruth ); - assert( Vec_IntSize(p->vLits) == 5 ); - - // perform structural hashing here!!! - pLookup = Saig_ManBmcLookup( p, Vec_IntArray(p->vLits) ); - if ( *pLookup == 0 ) - { - *pLookup = Ga2_ObjFindOrAddLit(p, pObj, f); - Vec_IntShrink( p->vLits, nSize ); - Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), *pLookup, -1 ); - } - else - Ga2_ObjAddLit( p, pObj, f, *pLookup ); - - } - else - { - Lit = Ga2_ObjFindOrAddLit(p, pObj, f); - Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), Lit, -1 ); - } - } - } - } -} - -void Ga2_ManAddAbsClauses( Ga2_Man_t * p, int f ) -{ - int fSimple = 0; - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) - { - if ( i == p->LimAbs ) - break; - if ( fSimple ) - Ga2_ManAddToAbsOneStatic( p, pObj, f, 0 ); - else - Ga2_ManAddToAbsOneDynamic( p, pObj, f ); - } - Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) - if ( i >= p->LimAbs ) - Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 ); -// sat_solver2_simplify( p->pSat ); -} - -void Ga2_ManAddToAbs( Ga2_Man_t * p, Vec_Int_t * vToAdd ) -{ - Vec_Int_t * vLeaves; - Gia_Obj_t * pObj, * pFanin; - int f, i, k; - // add abstraction objects - Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) - { - Ga2_ManSetupNode( p, pObj, 1 ); - if ( p->pSat->pPrf2 ) - Vec_IntWriteEntry( p->vProofIds, Gia_ObjId(p->pGia, pObj), p->nProofIds++ ); - } - // add PPI objects - Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) - { - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - if ( Ga2_ObjId( p, pFanin ) == -1 ) - Ga2_ManSetupNode( p, pFanin, 0 ); - } - // add new clauses to the timeframes - for ( f = 0; f <= p->pPars->iFrame; f++ ) - { - Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 ); - Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) - Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 ); - } -// sat_solver2_simplify( p->pSat ); -} - -void Ga2_ManShrinkAbs( Ga2_Man_t * p, int nAbs, int nValues, int nSatVars ) -{ - Vec_Int_t * vMap; - Gia_Obj_t * pObj; - int i, k, Entry; - assert( nAbs > 0 ); - assert( nValues > 0 ); - assert( nSatVars > 0 ); - // shrink abstraction - Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) - { - if ( !i ) continue; - assert( Ga2_ObjCnf0(p, pObj) != NULL ); - assert( Ga2_ObjCnf1(p, pObj) != NULL ); - if ( i < nAbs ) - continue; - Vec_IntFree( Ga2_ObjCnf0(p, pObj) ); - Vec_IntFree( Ga2_ObjCnf1(p, pObj) ); - Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), NULL ); - Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, NULL ); - } - Vec_IntShrink( p->vAbs, nAbs ); - // shrink values - Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) - { - assert( Ga2_ObjId(p,pObj) >= 0 ); - if ( i < nValues ) - continue; - Ga2_ObjSetId( p, pObj, -1 ); - } - Vec_IntShrink( p->vValues, nValues ); - Vec_PtrShrink( p->vCnfs, 2 * nValues ); - // hack to clear constant - if ( nValues == 1 ) - nValues = 0; - // clean mapping for each timeframe - Vec_PtrForEachEntry( Vec_Int_t *, p->vId2Lit, vMap, i ) - { - Vec_IntShrink( vMap, nValues ); - Vec_IntForEachEntryStart( vMap, Entry, k, p->LimAbs ) - if ( Entry >= 2*nSatVars ) - Vec_IntWriteEntry( vMap, k, -1 ); - } - // shrink SAT variables - p->nSatVars = nSatVars; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ga2_ManAbsTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vClasses, int fFirst ) -{ - if ( pObj->fPhase && !fFirst ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin0(pObj), vClasses, 0 ); - Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin1(pObj), vClasses, 0 ); - Vec_IntWriteEntry( vClasses, Gia_ObjId(p, pObj), 1 ); -} - -Vec_Int_t * Ga2_ManAbsTranslate( Ga2_Man_t * p ) -{ - Vec_Int_t * vGateClasses; - Gia_Obj_t * pObj; - int i; - vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) ); - Vec_IntWriteEntry( vGateClasses, 0, 1 ); - Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - Ga2_ManAbsTranslate_rec( p->pGia, pObj, vGateClasses, 1 ); - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - Vec_IntWriteEntry( vGateClasses, Gia_ObjId(p->pGia, pObj), 1 ); - else if ( !Gia_ObjIsConst0(pObj) ) - assert( 0 ); -// Gia_ObjPrint( p->pGia, pObj ); - } - return vGateClasses; -} - -Vec_Int_t * Ga2_ManAbsDerive( Gia_Man_t * p ) -{ - Vec_Int_t * vToAdd; - Gia_Obj_t * pObj; - int i; - vToAdd = Vec_IntAlloc( 1000 ); - Gia_ManForEachRo( p, pObj, i ) - if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)) ) - Vec_IntPush( vToAdd, Gia_ObjId(p, pObj) ); - Gia_ManForEachAnd( p, pObj, i ) - if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, i) ) - Vec_IntPush( vToAdd, i ); - return vToAdd; -} - -void Ga2_ManRestart( Ga2_Man_t * p ) -{ - Vec_Int_t * vToAdd; - int Lit = 1; - assert( p->pGia != NULL && p->pGia->vGateClasses != NULL ); - assert( Gia_ManPi(p->pGia, 0)->fPhase ); // marks are set - // clear SAT variable numbers (begin with 1) - if ( p->pSat ) sat_solver2_delete( p->pSat ); - p->pSat = sat_solver2_new(); - p->pSat->nLearntStart = p->pPars->nLearnedStart; - p->pSat->nLearntDelta = p->pPars->nLearnedDelta; - p->pSat->nLearntRatio = p->pPars->nLearnedPerce; - p->pSat->nLearntMax = p->pSat->nLearntStart; - // add clause x0 = 0 (lit0 = 1; lit1 = 0) - sat_solver2_addclause( p->pSat, &Lit, &Lit + 1, -1 ); - // remove previous abstraction - Ga2_ManShrinkAbs( p, 1, 1, 1 ); - // start new abstraction - vToAdd = Ga2_ManAbsDerive( p->pGia ); - assert( p->pSat->pPrf2 == NULL ); - assert( p->pPars->iFrame < 0 ); - Ga2_ManAddToAbs( p, vToAdd ); - Vec_IntFree( vToAdd ); - p->LimAbs = Vec_IntSize(p->vAbs); - p->LimPpi = Vec_IntSize(p->vValues); - // set runtime limit - if ( p->pPars->nTimeOut ) - sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + p->timeStart ); - // clean the hash table - memset( p->pTable, 0, 6 * sizeof(int) * p->nTable ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Vec_IntCheckUnique( Vec_Int_t * p ) -{ - int RetValue; - Vec_Int_t * pDup = Vec_IntDup( p ); - Vec_IntUniqify( pDup ); - RetValue = Vec_IntSize(p) - Vec_IntSize(pDup); - Vec_IntFree( pDup ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ga2_ObjSatValue( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) -{ - int Lit = Ga2_ObjFindLit( p, pObj, f ); - assert( !Gia_ObjIsConst0(pObj) ); - if ( Lit == -1 ) - return 0; - if ( Abc_Lit2Var(Lit) >= p->pSat->size ) - return 0; - return Abc_LitIsCompl(Lit) ^ sat_solver2_var_value( p->pSat, Abc_Lit2Var(Lit) ); -} -Abc_Cex_t * Ga2_ManDeriveCex( Ga2_Man_t * p, Vec_Int_t * vPis ) -{ - Abc_Cex_t * pCex; - Gia_Obj_t * pObj; - int i, f; - pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); - pCex->iPo = 0; - pCex->iFrame = p->pPars->iFrame; - Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) - { - if ( !Gia_ObjIsPi(p->pGia, pObj) ) - continue; - assert( Gia_ObjIsPi(p->pGia, pObj) ); - for ( f = 0; f <= pCex->iFrame; f++ ) - if ( Ga2_ObjSatValue( p, pObj, f ) ) - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) ); - } - return pCex; -} -void Ga2_ManRefinePrint( Ga2_Man_t * p, Vec_Int_t * vVec ) -{ - Gia_Obj_t * pObj, * pFanin; - int i, k; - printf( "\n Unsat core: \n" ); - Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) - { - Vec_Int_t * vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - printf( "%12d : ", i ); - printf( "Obj =%6d ", Gia_ObjId(p->pGia, pObj) ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - printf( "ff " ); - else - printf( " " ); - if ( Ga2_ObjIsAbs0(p, pObj) ) - printf( "a " ); - else if ( Ga2_ObjIsLeaf0(p, pObj) ) - printf( "l " ); - else - printf( " " ); - printf( "Fanins: " ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - { - printf( "%6d ", Gia_ObjId(p->pGia, pFanin) ); - if ( Gia_ObjIsRo(p->pGia, pFanin) ) - printf( "ff " ); - else - printf( " " ); - if ( Ga2_ObjIsAbs0(p, pFanin) ) - printf( "a " ); - else if ( Ga2_ObjIsLeaf0(p, pFanin) ) - printf( "l " ); - else - printf( " " ); - } - printf( "\n" ); - } -} -void Ga2_ManRefinePrintPPis( Ga2_Man_t * p ) -{ - Vec_Int_t * vVec = Vec_IntAlloc( 100 ); - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) - { - if ( !i ) continue; - if ( Ga2_ObjIsAbs(p, pObj) ) - continue; - assert( pObj->fPhase ); - assert( Ga2_ObjIsLeaf(p, pObj) ); - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); - Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) ); - } - printf( " Current PPIs (%d): ", Vec_IntSize(vVec) ); - Vec_IntSort( vVec, 1 ); - Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) - printf( "%d ", Gia_ObjId(p->pGia, pObj) ); - printf( "\n" ); - Vec_IntFree( vVec ); -} - - -void Ga2_GlaPrepareCexAndMap( Ga2_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMaps ) -{ - Abc_Cex_t * pCex; - Vec_Int_t * vMap; - Gia_Obj_t * pObj; - int f, i, k; -/* - Gia_ManForEachObj( p->pGia, pObj, i ) - if ( Ga2_ObjId(p, pObj) >= 0 ) - assert( Vec_IntEntry(p->vValues, Ga2_ObjId(p, pObj)) == i ); -*/ - // find PIs and PPIs - vMap = Vec_IntAlloc( 1000 ); - Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) - { - if ( !i ) continue; - if ( Ga2_ObjIsAbs(p, pObj) ) - continue; - assert( pObj->fPhase ); - assert( Ga2_ObjIsLeaf(p, pObj) ); - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); - Vec_IntPush( vMap, Gia_ObjId(p->pGia, pObj) ); - } - // derive counter-example - pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 ); - pCex->iFrame = p->pPars->iFrame; - for ( f = 0; f <= p->pPars->iFrame; f++ ) - Gia_ManForEachObjVec( vMap, p->pGia, pObj, k ) - if ( Ga2_ObjSatValue( p, pObj, f ) ) - Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k ); - *pvMaps = vMap; - *ppCex = pCex; -} -Vec_Int_t * Ga2_ManRefine( Ga2_Man_t * p ) -{ - Abc_Cex_t * pCex; - Vec_Int_t * vMap, * vVec; - Gia_Obj_t * pObj; - int i, k; - if ( p->pPars->fAddLayer ) - { - // use simplified refinement strategy, which adds logic near at PPI without finding important ones - vVec = Vec_IntAlloc( 100 ); - Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) - { - if ( !i ) continue; - if ( Ga2_ObjIsAbs(p, pObj) ) - continue; - assert( pObj->fPhase ); - assert( Ga2_ObjIsLeaf(p, pObj) ); - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); - if ( Gia_ObjIsPi(p->pGia, pObj) ) - continue; - Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) ); - } - p->nObjAdded += Vec_IntSize(vVec); - return vVec; - } - Ga2_GlaPrepareCexAndMap( p, &pCex, &vMap ); - // Rf2_ManRefine( p->pRf2, pCex, vMap, p->pPars->fPropFanout, 1 ); - vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 1, 1 ); -// printf( "Refinement %d\n", Vec_IntSize(vVec) ); - Abc_CexFree( pCex ); - if ( Vec_IntSize(vVec) == 0 ) - { - Vec_IntFree( vVec ); - Abc_CexFreeP( &p->pGia->pCexSeq ); - p->pGia->pCexSeq = Ga2_ManDeriveCex( p, vMap ); - Vec_IntFree( vMap ); - return NULL; - } - Vec_IntFree( vMap ); - // remove those already added - k = 0; - Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) - if ( !Ga2_ObjIsAbs(p, pObj) ) - Vec_IntWriteEntry( vVec, k++, Gia_ObjId(p->pGia, pObj) ); - Vec_IntShrink( vVec, k ); - - // these objects should be PPIs that are not abstracted yet - Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) - assert( pObj->fPhase );//&& Ga2_ObjIsLeaf(p, pObj) ); - p->nObjAdded += Vec_IntSize(vVec); - return vVec; -} - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ga2_GlaAbsCount( Ga2_Man_t * p, int fRo, int fAnd ) -{ - Gia_Obj_t * pObj; - int i, Counter = 0; - if ( fRo ) - Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) - Counter += Gia_ObjIsRo(p->pGia, pObj); - else if ( fAnd ) - Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) - Counter += Gia_ObjIsAnd(pObj); - else assert( 0 ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ga2_ManAbsPrintFrame( Ga2_Man_t * p, int nFrames, int nConfls, int nCexes, clock_t Time, int fFinal ) -{ - if ( Abc_FrameIsBatchMode() && !(((fFinal && nCexes) || p->pPars->fVeryVerbose)) ) - return; - Abc_Print( 1, "%4d :", nFrames ); - Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Vec_IntSize(p->vAbs) / p->nMarked) ); - Abc_Print( 1, "%6d", Vec_IntSize(p->vAbs) ); - Abc_Print( 1, "%5d", Vec_IntSize(p->vValues)-Vec_IntSize(p->vAbs)-1 ); - Abc_Print( 1, "%5d", Ga2_GlaAbsCount(p, 1, 0) ); - Abc_Print( 1, "%6d", Ga2_GlaAbsCount(p, 0, 1) ); - Abc_Print( 1, "%8d", nConfls ); - if ( nCexes == 0 ) - Abc_Print( 1, "%5c", '-' ); - else - Abc_Print( 1, "%5d", nCexes ); - Abc_PrintInt( sat_solver2_nvars(p->pSat) ); - Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); - Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); - Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); - Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) ); - Abc_Print( 1, "%s", ((fFinal && nCexes) || p->pPars->fVeryVerbose) ? "\n" : "\r" ); - fflush( stdout ); -} - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Ga2_GlaGetFileName( Ga2_Man_t * p, int fAbs ) -{ - static char * pFileNameDef = "glabs.aig"; - if ( p->pPars->pFileVabs ) - return p->pPars->pFileVabs; - if ( p->pGia->pSpec ) - { - if ( fAbs ) - return Extra_FileNameGenericAppend( p->pGia->pSpec, "_abs.aig"); - else - return Extra_FileNameGenericAppend( p->pGia->pSpec, "_gla.aig"); - } - return pFileNameDef; -} - -void Ga2_GlaDumpAbsracted( Ga2_Man_t * p, int fVerbose ) -{ - char * pFileName; - assert( p->pPars->fDumpMabs || p->pPars->fDumpVabs || p->pPars->fCallProver ); - if ( p->pPars->fDumpMabs ) - { - pFileName = Ga2_GlaGetFileName(p, 0); -// if ( fVerbose ) -// Abc_Print( 1, "Dumping miter with abstraction map into file \"%s\"...\n", pFileName ); - // dump abstraction map - Vec_IntFreeP( &p->pGia->vGateClasses ); - p->pGia->vGateClasses = Ga2_ManAbsTranslate( p ); - Gia_WriteAiger( p->pGia, pFileName, 0, 0 ); - } - if ( p->pPars->fDumpVabs || p->pPars->fCallProver ) - { - Vec_Int_t * vGateClasses; - Gia_Man_t * pAbs; - pFileName = Ga2_GlaGetFileName(p, 1); -// if ( fVerbose ) -// Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); - // dump absracted model - vGateClasses = Ga2_ManAbsTranslate( p ); - pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses ); - Gia_ManCleanValue( p->pGia ); - Gia_WriteAiger( pAbs, pFileName, 0, 0 ); - Gia_ManStop( pAbs ); - Vec_IntFreeP( &vGateClasses ); - } -} - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_Ga2SendAbsracted( Ga2_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); - Gia_Man_t * pAbs; - Vec_Int_t * vGateClasses; - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Sending abstracted model...\n" ); - // create abstraction (value of p->pGia is not used here) - vGateClasses = Ga2_ManAbsTranslate( p ); - pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses ); - Vec_IntFreeP( &vGateClasses ); - Gia_ManCleanValue( p->pGia ); - // send it out - Gia_ManToBridgeAbsNetlist( stdout, pAbs ); - Gia_ManStop( pAbs ); -} -void Gia_Ga2SendCancel( Ga2_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeBadAbs( FILE * pFile ); - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Cancelling previously sent model...\n" ); - Gia_ManToBridgeBadAbs( stdout ); -} - -/**Function************************************************************* - - Synopsis [Performs gate-level abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ga2_ManPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars ) -{ - int fUseSecondCore = 1; - Ga2_Man_t * p; - Vec_Int_t * vCore, * vPPis; - clock_t clk2, clk = clock(); - int Status = l_Undef, RetValue = -1, iFrameTryToProve = -1, fOneIsSent = 0; - int i, c, f, Lit; - // check trivial case - assert( Gia_ManPoNum(pAig) == 1 ); - ABC_FREE( pAig->pCexSeq ); - if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) - { - if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) - { - Abc_Print( 1, "Sequential miter is trivially UNSAT.\n" ); - return 1; - } - pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); - Abc_Print( 1, "Sequential miter is trivially SAT.\n" ); - return 0; - } - // create gate classes if not given - if ( pAig->vGateClasses == NULL ) - { - pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) ); - Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 ); - Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 ); - } - // start the manager - p = Ga2_ManStart( pAig, pPars ); - p->timeInit = clock() - clk; - // perform initial abstraction - if ( p->pPars->fVerbose ) - { - Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" ); - Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %% RatioMax = %d %%\n", - pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin, pPars->nRatioMax ); - Abc_Print( 1, "LrnStart = %d LrnDelta = %d LrnRatio = %d %% Skip = %d SimpleCNF = %d Dump = %d\n", - pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce, pPars->fUseSkip, pPars->fUseSimple, pPars->fDumpVabs|pPars->fDumpMabs|pPars->fCallProver ); - if ( pPars->fDumpVabs || pPars->fDumpMabs ) - Abc_Print( 1, "%s will be dumped into file \"%s\".\n", - pPars->fDumpVabs ? "Abstracted model" : "Miter with abstraction map", - Ga2_GlaGetFileName(p, pPars->fDumpVabs) ); - Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" ); - } - // iterate unrolling - for ( i = f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; i++ ) - { - int nAbsOld; - // remember the timeframe - p->pPars->iFrame = -1; - // create new SAT solver - Ga2_ManRestart( p ); - // remember abstraction size after the last restart - nAbsOld = Vec_IntSize(p->vAbs); - // unroll the circuit - for ( f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; f++ ) - { - // remember current limits - int nConflsBeg = sat_solver2_nconflicts(p->pSat); - int nAbs = Vec_IntSize(p->vAbs); - int nValues = Vec_IntSize(p->vValues); - int nVarsOld; - // remember the timeframe - p->pPars->iFrame = f; - // extend and clear storage - if ( f == Vec_PtrSize(p->vId2Lit) ) - Vec_PtrPush( p->vId2Lit, Vec_IntAlloc(0) ); - Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 ); - // add static clauses to this timeframe - Ga2_ManAddAbsClauses( p, f ); - // skip checking if skipcheck is enabled (&gla -s) - if ( p->pPars->fUseSkip && f <= p->pPars->iFrameProved ) - continue; - // skip checking if we need to skip several starting frames (&gla -S ) - if ( p->pPars->nFramesStart && f <= p->pPars->nFramesStart ) - continue; - // get the output literal -// Lit = Ga2_ManUnroll_rec( p, Gia_ManPo(pAig,0), f ); - Lit = Ga2_ObjFindLit( p, Gia_ObjFanin0(Gia_ManPo(pAig,0)), f ); - assert( Lit >= 0 ); - Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ); - if ( Lit == 0 ) - continue; - assert( Lit > 1 ); - // check for counter-examples - if ( p->nSatVars > sat_solver2_nvars(p->pSat) ) - sat_solver2_setnvars( p->pSat, p->nSatVars ); - nVarsOld = p->nSatVars; - for ( c = 0; ; c++ ) - { - // consider the special case when the target literal is implied false - // by implications which happened as a result of previous refinements - // note that incremental UNSAT core cannot be computed because there is no learned clauses - // in this case, we will assume that UNSAT core cannot reduce the problem - if ( var_is_assigned(p->pSat, Abc_Lit2Var(Lit)) ) - { - Prf_ManStopP( &p->pSat->pPrf2 ); - break; - } - // perform SAT solving - clk2 = clock(); - Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( Status == l_True ) // perform refinement - { - p->nCexes++; - p->timeSat += clock() - clk2; - - // cancel old one if it was sent - if ( Abc_FrameIsBridgeMode() && fOneIsSent ) - { - Gia_Ga2SendCancel( p, pPars->fVerbose ); - fOneIsSent = 0; - } - if ( iFrameTryToProve >= 0 ) - { - Gia_Ga2ProveCancel( pPars->fVerbose ); - iFrameTryToProve = -1; - } - - // perform refinement - clk2 = clock(); - vPPis = Ga2_ManRefine( p ); - p->timeCex += clock() - clk2; - if ( vPPis == NULL ) - { - if ( pPars->fVerbose ) - Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 ); - goto finish; - } - - if ( c == 0 ) - { -// Ga2_ManRefinePrintPPis( p ); - // create bookmark to be used for rollback - assert( nVarsOld == p->pSat->size ); - sat_solver2_bookmark( p->pSat ); - // start incremental proof manager - assert( p->pSat->pPrf2 == NULL ); - p->pSat->pPrf2 = Prf_ManAlloc(); - if ( p->pSat->pPrf2 ) - { - p->nProofIds = 0; - Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); - Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) ); - } - } - else - { - // resize the proof logger - if ( p->pSat->pPrf2 ) - Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) ); - } - - Ga2_ManAddToAbs( p, vPPis ); - Vec_IntFree( vPPis ); - if ( pPars->fVerbose ) - Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c+1, clock() - clk, 0 ); - continue; - } - p->timeUnsat += clock() - clk2; - if ( Status == l_Undef ) // ran out of resources - goto finish; - if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit ) // timeout - goto finish; - if ( c == 0 ) - { - if ( f > p->pPars->iFrameProved ) - p->pPars->nFramesNoChange++; - break; - } - if ( f > p->pPars->iFrameProved ) - p->pPars->nFramesNoChange = 0; - - // derive the core - assert( p->pSat->pPrf2 != NULL ); - vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); - Prf_ManStopP( &p->pSat->pPrf2 ); - // update the SAT solver - sat_solver2_rollback( p->pSat ); - // reduce abstraction - Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld ); - - // purify UNSAT core - if ( fUseSecondCore ) - { -// int nOldCore = Vec_IntSize(vCore); - // reverse the order of objects in the core -// Vec_IntSort( vCore, 0 ); -// Vec_IntPrint( vCore ); - // create bookmark to be used for rollback - assert( nVarsOld == p->pSat->size ); - sat_solver2_bookmark( p->pSat ); - // start incremental proof manager - assert( p->pSat->pPrf2 == NULL ); - p->pSat->pPrf2 = Prf_ManAlloc(); - if ( p->pSat->pPrf2 ) - { - p->nProofIds = 0; - Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); - Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vCore) ); - - Ga2_ManAddToAbs( p, vCore ); - Vec_IntFree( vCore ); - } - // run SAT solver - clk2 = clock(); - Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( Status == l_Undef ) - goto finish; - assert( Status == l_False ); - p->timeUnsat += clock() - clk2; - - // derive the core - assert( p->pSat->pPrf2 != NULL ); - vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); - Prf_ManStopP( &p->pSat->pPrf2 ); - // update the SAT solver - sat_solver2_rollback( p->pSat ); - // reduce abstraction - Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld ); -// printf( "\n%4d -> %4d\n", nOldCore, Vec_IntSize(vCore) ); - } - - Ga2_ManAddToAbs( p, vCore ); -// Ga2_ManRefinePrint( p, vCore ); - Vec_IntFree( vCore ); - break; - } - // remember the last proved frame - if ( p->pPars->iFrameProved < f ) - p->pPars->iFrameProved = f; - // print statistics - if ( pPars->fVerbose ) - Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 ); - // check if abstraction was proved - if ( Gia_Ga2ProveCheck( pPars->fVerbose ) ) - { - RetValue = 1; - goto finish; - } - if ( c > 0 ) - { - if ( p->pPars->fVeryVerbose ) - Abc_Print( 1, "\n" ); - // recompute the abstraction - Vec_IntFreeP( &pAig->vGateClasses ); - pAig->vGateClasses = Ga2_ManAbsTranslate( p ); - // check if the number of objects is below limit - if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 ) - { - Status = l_Undef; - goto finish; - } - } - // check the number of stable frames - if ( p->pPars->nFramesNoChange == p->pPars->nFramesNoChangeLim ) - { - // dump the model into file - if ( p->pPars->fDumpVabs || p->pPars->fDumpMabs || p->pPars->fCallProver ) - { - char Command[1000]; - Abc_FrameSetStatus( -1 ); - Abc_FrameSetCex( NULL ); - Abc_FrameSetNFrames( f+1 ); - sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") ); - Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); - Ga2_GlaDumpAbsracted( p, pPars->fVerbose ); - } - // call the prover - if ( p->pPars->fCallProver ) - { - // cancel old one if it is proving - if ( iFrameTryToProve >= 0 ) - Gia_Ga2ProveCancel( pPars->fVerbose ); - // prove new one - Gia_Ga2ProveAbsracted( Ga2_GlaGetFileName(p, 1), pPars->fVerbose ); - iFrameTryToProve = f; - } - // speak to the bridge - if ( Abc_FrameIsBridgeMode() ) - { - // cancel old one if it was sent - if ( fOneIsSent ) - Gia_Ga2SendCancel( p, pPars->fVerbose ); - // send new one - Gia_Ga2SendAbsracted( p, pPars->fVerbose ); - fOneIsSent = 1; - } - } - // if abstraction grew more than a certain percentage, force a restart - if ( pPars->nRatioMax == 0 ) - continue; - if ( c > 0 && (f > 20 || Vec_IntSize(p->vAbs) > 100) && Vec_IntSize(p->vAbs) - nAbsOld >= nAbsOld * pPars->nRatioMax / 100 ) - { - if ( p->pPars->fVerbose ) - Abc_Print( 1, "Forcing restart because abstraction grew from %d to %d (more than %d %%).\n", - nAbsOld, Vec_IntSize(p->vAbs), pPars->nRatioMax ); - break; - } - } - } -finish: - Prf_ManStopP( &p->pSat->pPrf2 ); - // cancel old one if it is proving - if ( iFrameTryToProve >= 0 ) - Gia_Ga2ProveCancel( pPars->fVerbose ); - // analize the results - if ( RetValue == 1 ) - Abc_Print( 1, "GLA completed %d frames and proved abstraction derived in frame %d. ", p->pPars->iFrameProved+1, iFrameTryToProve ); - else if ( pAig->pCexSeq == NULL ) - { -// if ( pAig->vGateClasses != NULL ) -// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); - Vec_IntFreeP( &pAig->vGateClasses ); - pAig->vGateClasses = Ga2_ManAbsTranslate( p ); - if ( Status == l_Undef ) - { - if ( p->pPars->fVerbose ) - Abc_Print( 1, "\n" ); - if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) - Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); - else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) - Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); - else if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 ) - Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, p->pPars->iFrameProved+1 ); - else - Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", p->pPars->iFrameProved+1 ); - } - else - { - p->pPars->iFrame = p->pPars->iFrameProved; - Abc_Print( 1, "GLA completed %d frames and produced a %d-stable abstraction. ", p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); - } - } - else - { - if ( p->pPars->fVerbose ) - Abc_Print( 1, "\n" ); - if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) ) - Abc_Print( 1, " Gia_GlaPerform(): CEX verification has failed!\n" ); - Abc_Print( 1, "True counter-example detected in frame %d. ", f ); - p->pPars->iFrame = f - 1; - Vec_IntFreeP( &pAig->vGateClasses ); - RetValue = 0; - } - Abc_PrintTime( 1, "Time", clock() - clk ); - if ( p->pPars->fVerbose ) - { - p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit; - ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk ); - ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); - ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); - ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); - ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); - ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); - Ga2_ManReportMemory( p ); - } -// Ga2_ManDumpStats( p->pGia, p->pPars, p->pSat, p->pPars->iFrameProved, 0 ); - Ga2_ManStop( p ); - fflush( stdout ); - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsIter.c b/src/aig/gia/giaAbsIter.c deleted file mode 100644 index 42f4ed1e..00000000 --- a/src/aig/gia/giaAbsIter.c +++ /dev/null @@ -1,149 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaIter.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Iterative improvement of abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAig.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Gia_ObjIsInGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)); } -static inline void Gia_ObjAddToGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 1); } -static inline void Gia_ObjRemFromGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 0); } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_IterTryImprove( Gia_Man_t * p, int nTimeOut, int iFrame0 ) -{ - extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames, int fSilent ); - Gia_Man_t * pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); - Aig_Man_t * pAig = Gia_ManToAigSimple( pAbs ); - int nStart = 0; - int nFrames = iFrame0 ? iFrame0 + 1 : 10000000; - int nNodeDelta = 2000; - int nBTLimit = 0; - int nBTLimitAll = 0; - int fVerbose = 0; - int RetValue, iFrame; - RetValue = Saig_BmcPerform( pAig, nStart, nFrames, nNodeDelta, nTimeOut, nBTLimit, nBTLimitAll, fVerbose, 0, &iFrame, 1 ); - assert( RetValue == 0 || RetValue == -1 ); - Aig_ManStop( pAig ); - Gia_ManStop( pAbs ); - return iFrame; -} -Gia_Man_t * Gia_IterImprove( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose ) -{ - Gia_Obj_t * pObj; - int i, iFrame0, iFrame; - int nTotal = 0, nRemoved = 0; - Vec_Int_t * vGScopy; - clock_t clk, clkTotal = clock(); - assert( Gia_ManPoNum(p) == 1 ); - assert( p->vGateClasses != NULL ); - vGScopy = Vec_IntDup( p->vGateClasses ); - if ( nFrameMax == 0 ) - iFrame0 = Gia_IterTryImprove( p, 0, 0 ); - else - iFrame0 = nFrameMax - 1; - while ( 1 ) - { - int fChanges = 0; - Gia_ManForEachObj1( p, pObj, i ) - { - if ( pObj->fMark0 ) - continue; - if ( !Gia_ObjIsInGla(p, pObj) ) - continue; - if ( pObj == Gia_ObjFanin0( Gia_ManPo(p, 0) ) ) - continue; - if ( Gia_ObjIsAnd(pObj) ) - { - if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(pObj)) && Gia_ObjIsInGla(p, Gia_ObjFanin1(pObj)) ) - continue; - } - if ( Gia_ObjIsRo(p, pObj) ) - { - if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj))) ) - continue; - } - clk = clock(); - printf( "%5d : ", nTotal ); - printf( "Obj =%7d ", i ); - Gia_ObjRemFromGla( p, pObj ); - iFrame = Gia_IterTryImprove( p, nTimeOut, iFrame0 ); - if ( nFrameMax ) - assert( iFrame <= nFrameMax ); - else - assert( iFrame <= iFrame0 ); - printf( "Frame =%6d ", iFrame ); - if ( iFrame < iFrame0 ) - { - pObj->fMark0 = 1; - Gia_ObjAddToGla( p, pObj ); - printf( " " ); - } - else - { - fChanges = 1; - nRemoved++; - printf( "Removing " ); - Vec_IntWriteEntry( vGScopy, Gia_ObjId(p, pObj), 0 ); - } - Abc_PrintTime( 1, "Time", clock() - clk ); - nTotal++; - // update the classes - Vec_IntFreeP( &p->vGateClasses ); - p->vGateClasses = Vec_IntDup(vGScopy); - } - if ( !fChanges ) - break; - } - Gia_ManCleanMark0(p); - Vec_IntFree( vGScopy ); - printf( "Tried = %d. ", nTotal ); - printf( "Removed = %d. (%.2f %%) ", nRemoved, 100.0 * nRemoved / Vec_IntCountPositive(p->vGateClasses) ); - Abc_PrintTime( 1, "Time", clock() - clkTotal ); - return NULL; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsOut.c b/src/aig/gia/giaAbsOut.c deleted file mode 100644 index 536ea277..00000000 --- a/src/aig/gia/giaAbsOut.c +++ /dev/null @@ -1,461 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsOut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Abstraction refinement outside of abstraction engines.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsOut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAig.h" -#include "aig/saig/saig.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Derive a new counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Gia_ManCexRemap( Gia_Man_t * p, Abc_Cex_t * pCexAbs, Vec_Int_t * vPis ) -{ - Abc_Cex_t * pCex; - int i, f, iPiNum; - assert( pCexAbs->iPo == 0 ); - // start the counter-example - pCex = Abc_CexAlloc( Gia_ManRegNum(p), Gia_ManPiNum(p), pCexAbs->iFrame+1 ); - pCex->iFrame = pCexAbs->iFrame; - pCex->iPo = pCexAbs->iPo; - // copy the bit data - for ( f = 0; f <= pCexAbs->iFrame; f++ ) - for ( i = 0; i < Vec_IntSize(vPis); i++ ) - { - if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) ) - { - iPiNum = Gia_ObjCioId( Gia_ManObj(p, Vec_IntEntry(vPis, i)) ); - Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + iPiNum ); - } - } - // verify the counter example - if ( !Gia_ManVerifyCex( p, pCex, 0 ) ) - { - Abc_Print( 1, "Gia_ManCexRemap(): Counter-example is invalid.\n" ); - Abc_CexFree( pCex ); - pCex = NULL; - } - else - { - Abc_Print( 1, "Counter-example verification is successful.\n" ); - Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame ); - } - return pCex; -} - -/**Function************************************************************* - - Synopsis [Refines gate-level abstraction using the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManGlaRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int fMinCut, int fVerbose ) -{ - extern void Nwk_ManDeriveMinCut( Gia_Man_t * p, int fVerbose ); -// extern Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ); - int fAddOneLayer = 1; - Abc_Cex_t * pCexNew = NULL; - Gia_Man_t * pAbs; - Aig_Man_t * pAig; - Abc_Cex_t * pCare; - Vec_Int_t * vPis, * vPPis; - int f, i, iObjId; - clock_t clk = clock(); - int nOnes = 0, Counter = 0; - if ( p->vGateClasses == NULL ) - { - Abc_Print( 1, "Gia_ManGlaRefine(): Abstraction gate map is missing.\n" ); - return -1; - } - // derive abstraction - pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); - Gia_ManStop( pAbs ); - pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); - if ( Gia_ManPiNum(pAbs) != pCex->nPis ) - { - Abc_Print( 1, "Gia_ManGlaRefine(): The PI counts in GLA and in CEX do not match.\n" ); - Gia_ManStop( pAbs ); - return -1; - } - if ( !Gia_ManVerifyCex( pAbs, pCex, 0 ) ) - { - Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is invalid.\n" ); -// Gia_ManStop( pAbs ); -// return -1; - } -// else -// Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is correct.\n" ); - // get inputs - Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, NULL, NULL ); - assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); - // add missing logic - if ( fAddOneLayer ) - { - Gia_Obj_t * pObj; - // check if this is a real counter-example - Gia_ObjTerSimSet0( Gia_ManConst0(pAbs) ); - for ( f = 0; f <= pCex->iFrame; f++ ) - { - Gia_ManForEachPi( pAbs, pObj, i ) - { - if ( i >= Vec_IntSize(vPis) ) // PPIs - Gia_ObjTerSimSetX( pObj ); - else if ( Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachRo( pAbs, pObj, i ) - { - if ( f == 0 ) - Gia_ObjTerSimSet0( pObj ); - else - Gia_ObjTerSimRo( pAbs, pObj ); - } - Gia_ManForEachAnd( pAbs, pObj, i ) - Gia_ObjTerSimAnd( pObj ); - Gia_ManForEachCo( pAbs, pObj, i ) - Gia_ObjTerSimCo( pObj ); - } - pObj = Gia_ManPo( pAbs, 0 ); - if ( Gia_ObjTerSimGet1(pObj) ) - { - pCexNew = Gia_ManCexRemap( p, pCex, vPis ); - Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); - } -// else -// Abc_Print( 1, "CEX is not real.\n" ); - Gia_ManForEachObj( pAbs, pObj, i ) - Gia_ObjTerSimSetC( pObj ); - if ( pCexNew == NULL ) - { - // grow one layer - Vec_IntForEachEntry( vPPis, iObjId, i ) - { - assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); - Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); - } - if ( fVerbose ) - { - Abc_Print( 1, "Additional objects = %d. ", Vec_IntSize(vPPis) ); - Abc_PrintTime( 1, "Time", clock() - clk ); - } - } - } - else - { - // minimize the CEX - pAig = Gia_ManToAigSimple( pAbs ); - pCare = Saig_ManCbaFindCexCareBits( pAig, pCex, Vec_IntSize(vPis), fVerbose ); - Aig_ManStop( pAig ); - if ( pCare == NULL ) - Abc_Print( 1, "Counter-example minimization has failed.\n" ); - // add new objects to the map - iObjId = -1; - for ( f = 0; f <= pCare->iFrame; f++ ) - for ( i = 0; i < pCare->nPis; i++ ) - if ( Abc_InfoHasBit( pCare->pData, pCare->nRegs + f * pCare->nPis + i ) ) - { - nOnes++; - assert( i >= Vec_IntSize(vPis) ); - iObjId = Vec_IntEntry( vPPis, i - Vec_IntSize(vPis) ); - assert( iObjId > 0 && iObjId < Gia_ManObjNum(p) ); - if ( Vec_IntEntry( p->vGateClasses, iObjId ) > 0 ) - continue; - assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); - Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); - // Abc_Print( 1, "Adding object %d.\n", iObjId ); - // Gia_ObjPrint( p, Gia_ManObj(p, iObjId) ); - Counter++; - } - Abc_CexFree( pCare ); - if ( fVerbose ) - { - Abc_Print( 1, "Essential bits = %d. Additional objects = %d. ", nOnes, Counter ); - Abc_PrintTime( 1, "Time", clock() - clk ); - } - // consider the case of SAT - if ( iObjId == -1 ) - { - pCexNew = Gia_ManCexRemap( p, pCex, vPis ); - Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); - } - } - Vec_IntFree( vPis ); - Vec_IntFree( vPPis ); - Gia_ManStop( pAbs ); - if ( pCexNew ) - { - ABC_FREE( p->pCexSeq ); - p->pCexSeq = pCexNew; - return 0; - } - // extract abstraction to include min-cut - if ( fMinCut ) - Nwk_ManDeriveMinCut( p, fVerbose ); - return -1; -} - - - - - -/**Function************************************************************* - - Synopsis [Resimulates the counter-example and returns flop values.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_ManGetStateAndCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) -{ - Vec_Int_t * vInit = Vec_IntAlloc( Gia_ManRegNum(pAig) ); - Gia_Obj_t * pObj, * pObjRi, * pObjRo; - int RetValue, i, k, iBit = 0; - assert( iFrame >= 0 && iFrame <= p->iFrame ); - Gia_ManCleanMark0(pAig); - Gia_ManForEachRo( pAig, pObj, i ) - pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); - for ( i = 0, iBit = p->nRegs; i <= p->iFrame; i++ ) - { - if ( i == iFrame ) - { - Gia_ManForEachRo( pAig, pObjRo, k ) - Vec_IntPush( vInit, pObjRo->fMark0 ); - } - Gia_ManForEachPi( pAig, pObj, k ) - pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); - Gia_ManForEachAnd( pAig, pObj, k ) - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - Gia_ManForEachCo( pAig, pObj, k ) - pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); - if ( i == p->iFrame ) - break; - Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) - pObjRo->fMark0 = pObjRi->fMark0; - } - assert( iBit == p->nBits ); - RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; - if ( RetValue != 1 ) - Vec_IntFreeP( &vInit ); - Gia_ManCleanMark0(pAig); - return vInit; -} - -/**Function************************************************************* - - Synopsis [Verify counter-example starting in the given timeframe.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) -{ - Gia_Obj_t * pObj, * pObjRi, * pObjRo; - int RetValue, i, k, iBit = 0; - assert( iFrame >= 0 && iFrame <= p->iFrame ); - Gia_ManCleanMark0(pAig); - Gia_ManForEachRo( pAig, pObj, i ) - pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); - for ( i = iFrame, iBit += p->nRegs + Gia_ManPiNum(pAig) * iFrame; i <= p->iFrame; i++ ) - { - Gia_ManForEachPi( pAig, pObj, k ) - pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); - Gia_ManForEachAnd( pAig, pObj, k ) - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - Gia_ManForEachCo( pAig, pObj, k ) - pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); - if ( i == p->iFrame ) - break; - Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) - pObjRo->fMark0 = pObjRi->fMark0; - } - assert( iBit == p->nBits ); - RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; - Gia_ManCleanMark0(pAig); - if ( RetValue == 1 ) - printf( "Shortened CEX holds for the abstraction of the fast-forwarded model.\n" ); - else - printf( "Shortened CEX does not hold for the abstraction of the fast-forwarded model.\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Gia_ManTransformFlops( Gia_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vInit ) -{ - Vec_Bit_t * vInitNew; - Gia_Man_t * pNew; - Gia_Obj_t * pObj; - int i, iFlopId; - assert( Vec_IntSize(vInit) == Vec_IntSize(vFlops) ); - vInitNew = Vec_BitStart( Gia_ManRegNum(p) ); - Gia_ManForEachObjVec( vFlops, p, pObj, i ) - { - assert( Gia_ObjIsRo(p, pObj) ); - if ( Vec_IntEntry(vInit, i) == 0 ) - continue; - iFlopId = Gia_ObjCioId(pObj) - Gia_ManPiNum(p); - assert( iFlopId >= 0 && iFlopId < Gia_ManRegNum(p) ); - Vec_BitWriteEntry( vInitNew, iFlopId, 1 ); - } - pNew = Gia_ManDupFlip( p, Vec_BitArray(vInitNew) ); - Vec_BitFree( vInitNew ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManNewRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrameStart, int iFrameExtra, int fVerbose ) -{ - Gia_Man_t * pAbs, * pNew; - Vec_Int_t * vFlops, * vInit; - Vec_Int_t * vCopy; -// clock_t clk = clock(); - int RetValue; - ABC_FREE( p->pCexSeq ); - if ( p->vGateClasses == NULL ) - { - Abc_Print( 1, "Gia_ManNewRefine(): Abstraction gate map is missing.\n" ); - return -1; - } - vCopy = Vec_IntDup( p->vGateClasses ); - Abc_Print( 1, "Refining with %d-frame CEX, starting in frame %d, with %d extra frames.\n", pCex->iFrame, iFrameStart, iFrameExtra ); - // derive abstraction - pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); - Gia_ManStop( pAbs ); - pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); - if ( Gia_ManPiNum(pAbs) != pCex->nPis ) - { - Abc_Print( 1, "Gia_ManNewRefine(): The PI counts in GLA and in CEX do not match.\n" ); - Gia_ManStop( pAbs ); - Vec_IntFree( vCopy ); - return -1; - } - // get the state in frame iFrameStart - vInit = Gia_ManGetStateAndCheckCex( pAbs, pCex, iFrameStart ); - if ( vInit == NULL ) - { - Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is invalid.\n" ); - Gia_ManStop( pAbs ); - Vec_IntFree( vCopy ); - return -1; - } - if ( fVerbose ) - Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is correct.\n" ); - // get inputs - Gia_ManGlaCollect( p, p->vGateClasses, NULL, NULL, &vFlops, NULL ); -// assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); - Gia_ManStop( pAbs ); -//Vec_IntPrint( vFlops ); -//Vec_IntPrint( vInit ); - // transform the manager to have new init state - pNew = Gia_ManTransformFlops( p, vFlops, vInit ); - Vec_IntFree( vFlops ); - Vec_IntFree( vInit ); - // verify abstraction - { - Gia_Man_t * pAbs = Gia_ManDupAbsGates( pNew, p->vGateClasses ); - Gia_ManCheckCex( pAbs, pCex, iFrameStart ); - Gia_ManStop( pAbs ); - } - // transfer abstraction - assert( pNew->vGateClasses == NULL ); - pNew->vGateClasses = Vec_IntDup( p->vGateClasses ); - // perform abstraction for the new AIG - { - Gia_ParVta_t Pars, * pPars = &Pars; - Gia_VtaSetDefaultParams( pPars ); - pPars->nFramesMax = pCex->iFrame - iFrameStart + 1 + iFrameExtra; - pPars->fVerbose = fVerbose; - RetValue = Ga2_ManPerform( pNew, pPars ); - if ( RetValue == 0 ) // spurious SAT - { - Vec_IntFreeP( &pNew->vGateClasses ); - pNew->vGateClasses = Vec_IntDup( vCopy ); - } - } - // move the abstraction map - Vec_IntFreeP( &p->vGateClasses ); - p->vGateClasses = pNew->vGateClasses; - pNew->vGateClasses = NULL; - // cleanup - Gia_ManStop( pNew ); - Vec_IntFree( vCopy ); - return -1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsPth.c b/src/aig/gia/giaAbsPth.c deleted file mode 100644 index 3b997443..00000000 --- a/src/aig/gia/giaAbsPth.c +++ /dev/null @@ -1,199 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsPth.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Interface to pthreads.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsPth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig/ioa/ioa.h" -#include "proof/pdr/pdr.h" - -// uncomment this line to enable pthreads -//#define ABC_USE_PTHREADS - -// to compile on Linux, modify Makefile as follows: -// add -pthread to OPTFLAGS -// add -lpthread to LIBS - -#ifdef ABC_USE_PTHREADS - -#ifdef WIN32 -#include "../lib/pthread.h" -#else -#include -#include -#endif - -#endif - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#ifndef ABC_USE_PTHREADS - -void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ) {} -void Gia_Ga2ProveCancel( int fVerbose ) {} -int Gia_Ga2ProveCheck( int fVerbose ) { return 0; } - -#else // pthreads are used - -// information given to the thread -typedef struct Abs_ThData_t_ -{ - char * pFileName; - int fVerbose; - int RunId; -} Abs_ThData_t; - -// mutext to control access to shared variables -pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; -static volatile int g_nRunIds = 0; // the number of the last prover instance -static volatile int g_fAbstractionProved = 0; // set to 1 when prover successed to prove - -// call back procedure for PDR -int Abs_CallBackToStop( int RunId ) { assert( RunId <= g_nRunIds ); return RunId < g_nRunIds; } - -// test procedure to replace PDR -int Pdr_ManSolve_test( Aig_Man_t * pAig, Pdr_Par_t * pPars, Abc_Cex_t ** ppCex ) -{ - char * p = ABC_ALLOC( char, 111 ); - while ( 1 ) - { - if ( pPars->pFuncStop && pPars->pFuncStop(pPars->RunId) ) - break; - } - ABC_FREE( p ); - return -1; -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Create one thread] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abs_ProverThread( void * pArg ) -{ - Abs_ThData_t * pThData = (Abs_ThData_t *)pArg; - Pdr_Par_t Pars, * pPars = &Pars; - Aig_Man_t * pAig, * pTemp; - int RetValue, status; - pAig = Ioa_ReadAiger( pThData->pFileName, 0 ); - if ( pAig == NULL ) - Abc_Print( 1, "\nCannot open file \"%s\".\n", pThData->pFileName ); - else - { - // synthesize abstraction - pAig = Aig_ManScl( pTemp = pAig, 1, 1, 0, -1, -1, 0, 0 ); - Aig_ManStop( pTemp ); - // call PDR - Pdr_ManSetDefaultParams( pPars ); - pPars->fSilent = 1; - pPars->RunId = pThData->RunId; - pPars->pFuncStop = Abs_CallBackToStop; - RetValue = Pdr_ManSolve( pAig, pPars, NULL ); -// RetValue = Pdr_ManSolve_test( pAig, pPars, NULL ); - // update the result - if ( RetValue == 1 ) - { - status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); - g_fAbstractionProved = 1; - status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); - } - // free memory - Aig_ManStop( pAig ); - // quit this thread - if ( pThData->fVerbose ) - { - if ( RetValue == 1 ) - Abc_Print( 1, "\nProved abstraction %d.\n", pThData->RunId ); - else if ( RetValue == 0 ) - Abc_Print( 1, "\nDisproved abstraction %d.\n", pThData->RunId ); - else if ( RetValue == -1 ) - Abc_Print( 1, "\nCancelled abstraction %d.\n", pThData->RunId ); - else assert( 0 ); - } - } - ABC_FREE( pThData->pFileName ); - ABC_FREE( pThData ); - // quit this thread - pthread_exit( NULL ); - assert(0); - return NULL; -} -void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ) -{ - Abs_ThData_t * pThData; - pthread_t ProverThread; - int status; - assert( pFileName != NULL ); - // disable verbosity - fVerbose = 0; - // reset the proof - status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); - g_fAbstractionProved = 0; - status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); - // collect thread data - pThData = ABC_CALLOC( Abs_ThData_t, 1 ); - pThData->pFileName = Abc_UtilStrsav( (void *)pFileName ); - pThData->fVerbose = fVerbose; - status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); - pThData->RunId = ++g_nRunIds; - status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); - // create thread - if ( fVerbose ) Abc_Print( 1, "\nTrying to prove abstraction %d.\n", pThData->RunId ); - status = pthread_create( &ProverThread, NULL, Abs_ProverThread, pThData ); - assert( status == 0 ); -} -void Gia_Ga2ProveCancel( int fVerbose ) -{ - int status; - status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); - g_nRunIds++; - status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); -} -int Gia_Ga2ProveCheck( int fVerbose ) -{ - int status; - if ( g_fAbstractionProved == 0 ) - return 0; - status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); - g_fAbstractionProved = 0; - status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); - return 1; -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsRef.c b/src/aig/gia/giaAbsRef.c deleted file mode 100644 index 8a5aedc5..00000000 --- a/src/aig/gia/giaAbsRef.c +++ /dev/null @@ -1,1001 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsRef.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Refinement manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAbsRef.h" -#include "sat/bsat/satSolver2.h" - -ABC_NAMESPACE_IMPL_START - -/* - Description of the refinement manager - - This refinement manager should be - * started by calling Rnm_ManStart() - this procedure takes one argument, the user's seq miter as a GIA manager - - the manager should have only one property output - - this manager should not change while the refinement manager is alive - - it cannot be used by external applications for any purpose - - when the refinement manager stop, GIA manager is the same as at the beginning - - in the meantime, it will have some data-structures attached to its nodes... - * stopped by calling Rnm_ManStop() - * between starting and stopping, refinements are obtained by calling Rnm_ManRefine() - - Procedure Rnm_ManRefine() takes the following arguments: - * the refinement manager previously started by Rnm_ManStart() - * counter-example (CEX) obtained by abstracting some logic of GIA - * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager - - only PI, flop outputs, and internal AND nodes can be used in vMap - - the ordering of objects in vMap is not important - - however, the index of a non-PI object in vMap is used as its priority - (the smaller the index, the more likely this non-PI object apears in a refinement) - - only the logic between PO and the objects listed in vMap is traversed by the manager - (as a result, GIA can be arbitrarily large, but only objects used in the abstraction - and the pseudo-PI, that is, objects in the cut, will be visited by the manager) - * flag fPropFanout defines whether value propagation is done through the fanout - - it this flag is enabled, theoretically refinement should be better (the result smaller) - * flag fVerbose may print some statistics - - The refinement manager returns a minimal-size array of integer IDs of GIA objects - which should be added to the abstraction to possibly prevent the given counter-example - - only flop output and internal AND nodes from vMap may appear in the resulting array - - if the resulting array is empty, the CEX is a true CEX - (in other words, non-PI objects are not needed to set the PO value to 1) - - Verification of the selected refinement is performed by - - initializing all PI objects in vMap to value 0 or 1 they have in the CEX - - initializing all remaining objects in vMap to value X - - initializing objects used in the refiment to value 0 or 1 they have in the CEX - - simulating through as many timeframes as required by the CEX - - if the PO value in the last frame is 1, the refinement is correct - (however, the minimality of the refinement is not currently checked) - -*/ - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rnm_Obj_t_ Rnm_Obj_t; // refinement object -struct Rnm_Obj_t_ -{ - unsigned Value : 1; // binary value - unsigned fVisit : 1; // visited object - unsigned fVisit0 : 1; // visited object - unsigned fPPi : 1; // PPI object - unsigned Prio : 24; // priority (0 - highest) -}; - -struct Rnm_Man_t_ -{ - // user data - Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package) - Abc_Cex_t * pCex; // counter-example - Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order) - int fPropFanout; // propagate fanouts - int fVerbose; // verbose flag - // traversing data - Vec_Int_t * vObjs; // internal objects used in value propagation - Vec_Str_t * vCounts; // fanin counters - Vec_Int_t * vFanins; // fanins - // SAT solver - sat_solver2 * pSat; // incremental SAT solver - Vec_Int_t * vSatVars; // SAT variables - Vec_Int_t * vSat2Ids; // mapping of SAT variables into object IDs - Vec_Int_t * vIsopMem; // memory for ISOP computation - // internal data - Rnm_Obj_t * pObjs; // refinement objects - int nObjs; // the number of used objects - int nObjsAlloc; // the number of allocated objects - int nObjsFrame; // the number of used objects in each frame - int nCalls; // total number of calls - int nRefines; // total refined objects - int nVisited; // visited during justification - // statistics - clock_t timeFwd; // forward propagation - clock_t timeBwd; // backward propagation - clock_t timeVer; // ternary simulation - clock_t timeTotal; // other time -}; - -// accessing the refinement object -static inline Rnm_Obj_t * Rnm_ManObj( Rnm_Man_t * p, Gia_Obj_t * pObj, int f ) -{ - assert( Gia_ObjIsConst0(pObj) || pObj->Value ); - assert( (int)pObj->Value < p->nObjsFrame ); - assert( f >= 0 && f <= p->pCex->iFrame ); - return p->pObjs + f * p->nObjsFrame + pObj->Value; -} - -static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); } -static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); } -static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); } -static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); } -static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); } -static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; } - -static inline int Rnm_ObjCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_StrEntry( p->vCounts, Gia_ObjId(p->pGia, pObj) ); } -static inline void Rnm_ObjSetCount( Rnm_Man_t * p, Gia_Obj_t * pObj, int c ) { Vec_StrWriteEntry( p->vCounts, Gia_ObjId(p->pGia, pObj), (char)c ); } -static inline int Rnm_ObjAddToCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { int c = Rnm_ObjCount(p, pObj); if ( c < 16 ) Rnm_ObjSetCount(p, pObj, c+1); return c; } - -static inline int Rnm_ObjSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj) ); } -static inline void Rnm_ObjSetSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj, int c) { Vec_IntWriteEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj), c ); } -static inline int Rnm_ObjFindOrAddSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj) { if ( Rnm_ObjSatVar(p, pObj) == 0 ) { Rnm_ObjSetSatVar(p, pObj, Vec_IntSize(p->vSat2Ids)); Vec_IntPush(p->vSat2Ids, Gia_ObjId(p->pGia, pObj)); }; return 2*Rnm_ObjSatVar(p, pObj); } - -extern void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int * pLits, int iLitOut, int ProofId ); - -extern Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs UNSAT-core-based refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rnm_ManRefineCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisited, Vec_Int_t * vFlops ) -{ - Vec_Int_t * vLeaves; - Gia_Obj_t * pFanin; - int k; - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pObj); - if ( Gia_ObjIsCi(pObj) ) - { - if ( Gia_ObjIsRo(p, pObj) ) - Vec_IntPush( vFlops, Gia_ObjId(p, pObj) ); - return; - } - assert( Gia_ObjIsAnd(pObj) ); - vLeaves = Ga2_ObjLeaves( p, pObj ); - Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) - Rnm_ManRefineCollect_rec( p, pFanin, vVisited, vFlops ); - Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); -} - -Vec_Int_t * Rnm_ManRefineUnsatCore( Rnm_Man_t * p, Vec_Int_t * vPPIs ) -{ - Vec_Int_t * vCnf0, * vCnf1; - Vec_Int_t * vLeaves, * vLits, * vPpi2Map; - Vec_Int_t * vVisited, * vFlops, * vCore, * vCoreFinal; - Gia_Obj_t * pObj, * pFanin; - int i, k, f, Status, Entry, pLits[5], iBit = p->pCex->nRegs; - // map PPIs into their positions in the map // CAN BE MADE FASTER - vPpi2Map = Vec_IntAlloc( Vec_IntSize(vPPIs) ); - Vec_IntForEachEntry( vPPIs, Entry, i ) - { - Entry = Vec_IntFind( p->vMap, Entry ); - assert( Entry >= 0 ); - Vec_IntPush( vPpi2Map, Entry ); - } - // collect nodes between selected PPIs and CIs - vFlops = Vec_IntAlloc( 100 ); - vVisited = Vec_IntAlloc( 100 ); - Gia_ManIncrementTravId( p->pGia ); - Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) -// if ( !Gia_ObjIsRo(p->pGia, pObj) ) // SKIP PPIs that are flops - Rnm_ManRefineCollect_rec( p->pGia, pObj, vVisited, vFlops ); - // create SAT variables and SAT solver - Vec_IntFill( p->vSat2Ids, 1, -1 ); - assert( p->pSat == NULL ); - p->pSat = sat_solver2_new(); - Vec_IntFill( p->vSatVars, Gia_ManObjNum(p->pGia), 0 ); // NO NEED TO CLEAN EACH TIME - // assign PPI variables - Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i ) - Rnm_ObjFindOrAddSatVar( p, pObj ); - // assign other variables - Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i ) - { - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - pLits[k] = Rnm_ObjFindOrAddSatVar( p, pFanin ); - vCnf0 = Ga2_ManCnfCompute( Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem ); - vCnf1 = Ga2_ManCnfCompute( ~Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem ); - Ga2_ManCnfAddStatic( p->pSat, vCnf0, vCnf1, pLits, Rnm_ObjFindOrAddSatVar(p, pObj), Rnm_ObjFindOrAddSatVar(p, pObj)/2 ); - Vec_IntFree( vCnf0 ); - Vec_IntFree( vCnf1 ); - } - -// printf( "\n" ); - - p->pSat->pPrf2 = Prf_ManAlloc(); - Prf_ManRestart( p->pSat->pPrf2, NULL, sat_solver2_nlearnts(p->pSat), Vec_IntSize(p->vSat2Ids) ); - - // iterate UNSAT core computation for each timeframe - vLits = Vec_IntAlloc( 100 ); - vCoreFinal = Vec_IntAlloc( 100 ); - for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) - { - // collect values of PPIs in this timeframe - Vec_IntClear( vLits ); - Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) - { - Entry = Abc_InfoHasBit( p->pCex->pData, iBit + Vec_IntEntry(vPpi2Map, i) ); - Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), !Entry ) ); - } - - // handle the first timeframe in a special vay - if ( f == 0 ) - Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i ) - if ( Vec_IntFind( vPPIs, Gia_ObjId(p->pGia, pObj) ) == -1 ) - Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), 1 ) ); -/* - // uniqify literals and detect special conflicts - Vec_IntUniqify( vLits ); - Vec_IntForEachEntryStart( vLits, Entry, i, 1 ) - if ( Vec_IntEntry(vLits, i-1) == Abc_LitNot(Entry) ) - break; - if ( i < Vec_IntSize(vLits) ) - printf( "triv_unsat " ); - else -*/ - - Status = sat_solver2_solve( p->pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( Status != l_False ) - continue; - vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); -// vCore = Vec_IntAlloc( 0 ); - // add to the UNSAT core - Vec_IntAppend( vCoreFinal, vCore ); - -// printf( "Frame %d : ", f ); -// Vec_IntPrint( vCore ); - Vec_IntFree( vCore ); - } - assert( iBit == p->pCex->nBits ); - Vec_IntUniqify( vCoreFinal ); - Vec_IntFree( vLits ); - Prf_ManStopP( &p->pSat->pPrf2 ); - sat_solver2_delete( p->pSat ); - p->pSat = NULL; - - // translate from entry into ID - Vec_IntForEachEntry( vCoreFinal, Entry, i ) - { - assert( Vec_IntEntry(p->vSat2Ids, Entry) >= 0 ); - assert( Vec_IntEntry(p->vSat2Ids, Entry) < Gia_ManObjNum(p->pGia) ); - Vec_IntWriteEntry( vCoreFinal, i, Vec_IntEntry(p->vSat2Ids, Entry) ); - } - // if there are flop outputs, add them - Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) - if ( Gia_ObjIsRo(p->pGia, pObj) ) - Vec_IntPush( vCoreFinal, Gia_ObjId(p->pGia, pObj) ); - Vec_IntUniqify( vCoreFinal ); - -// printf( "\n" ); -// Vec_IntPrint( vPPIs ); -// Vec_IntPrint( vCoreFinal ); - -// printf( "\n" ); - - // clean SAT variable numbers - Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i ) - { - Rnm_ObjSetSatVar( p, pObj, 0 ); - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - Rnm_ObjSetSatVar( p, pFanin, 0 ); - } - Vec_IntFree( vFlops ); - Vec_IntFree( vVisited ); - Vec_IntFree( vPpi2Map ); - return vCoreFinal; -} - - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia ) -{ - Rnm_Man_t * p; - assert( Gia_ManPoNum(pGia) == 1 ); - p = ABC_CALLOC( Rnm_Man_t, 1 ); - p->pGia = pGia; - p->vObjs = Vec_IntAlloc( 100 ); - p->vCounts = Vec_StrStart( Gia_ManObjNum(pGia) ); - p->vFanins = Vec_IntAlloc( 1000 ); - p->vSatVars = Vec_IntAlloc( 0 ); - p->vSat2Ids = Vec_IntAlloc( 1000 ); - p->vIsopMem = Vec_IntAlloc( 0 ); - p->nObjsAlloc = 10000; - p->pObjs = ABC_ALLOC( Rnm_Obj_t, p->nObjsAlloc ); - if ( p->pGia->vFanout == NULL ) - Gia_ManStaticFanoutStart( p->pGia ); - Gia_ManCleanValue(pGia); - Gia_ManCleanMark0(pGia); - Gia_ManCleanMark1(pGia); - return p; -} -void Rnm_ManStop( Rnm_Man_t * p, int fProfile ) -{ - if ( !p ) return; - // print runtime statistics - if ( fProfile && p->nCalls ) - { - double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc; - double MemOther = sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs); - clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer; - printf( "Abstraction refinement runtime statistics:\n" ); - ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal ); - ABC_PRTP( "Justification", p->timeBwd, p->timeTotal ); - ABC_PRTP( "Verification ", p->timeVer, p->timeTotal ); - ABC_PRTP( "Other ", timeOther, p->timeTotal ); - ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); - printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n", - p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) ); - } - - Gia_ManCleanMark0(p->pGia); - Gia_ManCleanMark1(p->pGia); - Gia_ManStaticFanoutStop(p->pGia); -// Gia_ManSetPhase(p->pGia); - Vec_IntFree( p->vIsopMem ); - Vec_IntFree( p->vSatVars ); - Vec_IntFree( p->vSat2Ids ); - Vec_StrFree( p->vCounts ); - Vec_IntFree( p->vFanins ); - Vec_IntFree( p->vObjs ); - ABC_FREE( p->pObjs ); - ABC_FREE( p ); -} -double Rnm_ManMemoryUsage( Rnm_Man_t * p ) -{ - return (double)(sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs)); -} - - -/**Function************************************************************* - - Synopsis [Collect internal objects to be used in value propagation.] - - Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rnm_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs, int nAddOn ) -{ - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pObj); - if ( Gia_ObjIsCo(pObj) ) - Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn ); - else if ( Gia_ObjIsAnd(pObj) ) - { - Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn ); - Rnm_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs, nAddOn ); - } - else if ( !Gia_ObjIsRo(p, pObj) ) - assert( 0 ); - pObj->Value = Vec_IntSize(vObjs) + nAddOn; - Vec_IntPush( vObjs, Gia_ObjId(p, pObj) ); -} -void Rnm_ManCollect( Rnm_Man_t * p ) -{ - Gia_Obj_t * pObj = NULL; - int i; - // mark const/PIs/PPIs - Gia_ManIncrementTravId( p->pGia ); - Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); - Gia_ManConst0(p->pGia)->Value = 0; - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - Gia_ObjSetTravIdCurrent( p->pGia, pObj ); - pObj->Value = 1 + i; - } - // collect objects - Vec_IntClear( p->vObjs ); - Rnm_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs, 1 + Vec_IntSize(p->vMap) ); - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - if ( Gia_ObjIsRo(p->pGia, pObj) ) - Rnm_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs, 1 + Vec_IntSize(p->vMap) ); - // the last object should be a CO - assert( Gia_ObjIsCo(pObj) ); - assert( (int)pObj->Value == Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) ); -} -void Rnm_ManCleanValues( Rnm_Man_t * p ) -{ - Gia_Obj_t * pObj; - int i; - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - pObj->Value = 0; - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - pObj->Value = 0; -} - -/**Function************************************************************* - - Synopsis [Performs sensitization analysis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rnm_ManSensitize( Rnm_Man_t * p ) -{ - Rnm_Obj_t * pRnm, * pRnm0, * pRnm1; - Gia_Obj_t * pObj; - int f, i, iBit = p->pCex->nRegs; - // const0 is initialized automatically in all timeframes - for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) - { - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - pRnm = Rnm_ManObj( p, pObj, f ); - pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i ); - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - { - assert( pObj->Value > 0 ); - pRnm->Prio = pObj->Value; - pRnm->fPPi = 1; - } - } - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - { - assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ); - pRnm = Rnm_ManObj( p, pObj, f ); - assert( !pRnm->fPPi ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f == 0 ) - continue; - pRnm0 = Rnm_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); - pRnm->Value = pRnm0->Value; - pRnm->Prio = pRnm0->Prio; - continue; - } - if ( Gia_ObjIsCo(pObj) ) - { - pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); - pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)); - pRnm->Prio = pRnm0->Prio; - continue; - } - assert( Gia_ObjIsAnd(pObj) ); - pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); - pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f ); - pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj)); - if ( pRnm->Value == 1 ) - pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio ); - else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice - else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) - pRnm->Prio = pRnm0->Prio; - else - pRnm->Prio = pRnm1->Prio; - } - } - assert( iBit == p->pCex->nBits ); - pRnm = Rnm_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame ); - if ( pRnm->Value != 1 ) - printf( "Output value is incorrect.\n" ); - return pRnm->Prio; -} - - -/**Function************************************************************* - - Synopsis [Drive implications of the given node towards primary outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rnm_ManJustifyPropFanout_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect ) -{ - Rnm_Obj_t * pRnm0, * pRnm1, * pRnm = Rnm_ManObj( p, pObj, f ); - Gia_Obj_t * pFanout = NULL; - int i, k;//, Id = Gia_ObjId(p->pGia, pObj); - assert( pRnm->fVisit == 0 ); - pRnm->fVisit = 1; - if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ) - { - Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1; - p->nVisited++; - } - if ( pRnm->fPPi ) - { - assert( (int)pRnm->Prio > 0 ); - for ( i = p->pCex->iFrame; i >= 0; i-- ) - if ( !Rnm_ManObj(p, pObj, i)->fVisit ) - Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect ); - Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); - return; - } - if ( (Gia_ObjIsCo(pObj) && f == p->pCex->iFrame) || Gia_ObjIsPo(p->pGia, pObj) ) - return; - if ( Gia_ObjIsRi(p->pGia, pObj) ) - { - pFanout = Gia_ObjRiToRo(p->pGia, pObj); - if ( !Rnm_ManObj(p, pFanout, f+1)->fVisit ) - Rnm_ManJustifyPropFanout_rec( p, pFanout, f+1, vSelect ); - return; - } - assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); - Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k ) - { - Rnm_Obj_t * pRnmF; - if ( pFanout->Value == 0 ) - continue; - pRnmF = Rnm_ManObj(p, pFanout, f); - if ( pRnmF->fPPi || pRnmF->fVisit ) - continue; - if ( Gia_ObjIsCo(pFanout) ) - { - Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect ); - continue; - } - assert( Gia_ObjIsAnd(pFanout) ); - pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pFanout), f ); - pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pFanout), f ); - if ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRnm0->fVisit) || - ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRnm1->fVisit) || - ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRnm0->fVisit) && - ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRnm1->fVisit) ) ) - Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect ); - } -} -void Rnm_ManJustify_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect ) -{ - Rnm_Obj_t * pRnm = Rnm_ManObj( p, pObj, f ); - int i;//, Id = Gia_ObjId(p->pGia, pObj); - if ( pRnm->fVisit ) - return; - if ( p->fPropFanout ) - Rnm_ManJustifyPropFanout_rec( p, pObj, f, vSelect ); - else - { - pRnm->fVisit = 1; - if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ) - { - Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1; - p->nVisited++; - } - } - if ( pRnm->fPPi ) - { - assert( (int)pRnm->Prio > 0 ); - if ( p->fPropFanout ) - { - for ( i = p->pCex->iFrame; i >= 0; i-- ) - if ( !Rnm_ManObj(p, pObj, i)->fVisit ) - Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect ); - } - else - { - Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); -// for ( i = p->pCex->iFrame; i >= 0; i-- ) -// Rnm_ManObj(p, pObj, i)->fVisit = 1; - } - return; - } - if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) - return; - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect ); - return; - } - if ( Gia_ObjIsAnd(pObj) ) - { - Rnm_Obj_t * pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); - Rnm_Obj_t * pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f ); - if ( pRnm->Value == 1 ) - { - if ( pRnm0->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); - if ( pRnm1->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); - } - else // select one value - { - if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - { - if ( pRnm0->Prio <= pRnm1->Prio ) // choice - { - if ( pRnm0->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); - } - else - { - if ( pRnm1->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); - } - } - else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) - { - if ( pRnm0->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); - } - else if ( (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - { - if ( pRnm1->Prio > 0 ) - Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); - } - else assert( 0 ); - } - } - else assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [Performs refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rnm_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes ) -{ - Gia_Obj_t * pObj; - int i, f, iBit = pCex->nRegs; - Gia_ObjTerSimSet0( Gia_ManConst0(p) ); - for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis ) - { - Gia_ManForEachObjVec( vMap, p, pObj, i ) - { - pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i ); - if ( !Gia_ObjIsPi(p, pObj) ) - Gia_ObjTerSimSetX( pObj ); - else if ( pObj->Value ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap - { - if ( pObj->Value ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachObjVec( vObjs, p, pObj, i ) - { - if ( Gia_ObjIsCo(pObj) ) - Gia_ObjTerSimCo( pObj ); - else if ( Gia_ObjIsAnd(pObj) ) - Gia_ObjTerSimAnd( pObj ); - else if ( f == 0 ) - Gia_ObjTerSimSet0( pObj ); - else - Gia_ObjTerSimRo( p, pObj ); - } - } - Gia_ManForEachObjVec( vMap, p, pObj, i ) - pObj->Value = 0; - pObj = Gia_ManPo( p, 0 ); - if ( !Gia_ObjTerSimGet1(pObj) ) - Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rnm_ManPrintSelected( Rnm_Man_t * p, Vec_Int_t * vSelected ) -{ - Gia_Obj_t * pObj; - int i, Counter = 0; - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - { - if ( Vec_IntFind(vSelected, Gia_ObjId(p->pGia, pObj)) >= 0 ) - printf( "1" ), Counter++; - else - printf( "0" ); - } - else - printf( "-" ); - } - printf( " %3d\n", Counter ); -} - - - - - -/**Function************************************************************* - - Synopsis [Perform structural analysis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ga2_StructAnalize( Gia_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInter, Vec_Int_t * vSelect ) -{ - Vec_Int_t * vLeaves; - Gia_Obj_t * pObj, * pFanin; - int i, k; - // clean labels - Gia_ManForEachObj( p, pObj, i ) - pObj->fMark0 = pObj->fMark1 = 0; - // label frontier - Gia_ManForEachObjVec( vFront, p, pObj, i ) - pObj->fMark0 = 1, pObj->fMark1 = 0; - // label objects - Gia_ManForEachObjVec( vInter, p, pObj, i ) - pObj->fMark1 = 0, pObj->fMark1 = 1; - // label selected - Gia_ManForEachObjVec( vSelect, p, pObj, i ) - pObj->fMark1 = 1, pObj->fMark1 = 1; - // explore selected - printf( "\n" ); - Gia_ManForEachObjVec( vSelect, p, pObj, i ) - { - printf( "Selected %6d : ", Gia_ObjId(p, pObj) ); - printf( "\n" ); - vLeaves = Ga2_ObjLeaves( p, pObj ); - Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) - { - printf( " " ); - printf( "%6d ", Gia_ObjId(p, pFanin) ); - if ( pFanin->fMark0 && pFanin->fMark1 ) - printf( "select" ); - else if ( pFanin->fMark0 && !pFanin->fMark1 ) - printf( "front" ); - else if ( !pFanin->fMark0 && pFanin->fMark1 ) - printf( "internal" ); - else if ( !pFanin->fMark0 && !pFanin->fMark1 ) - printf( "new" ); - printf( "\n" ); - } - } -} - - -/**Function************************************************************* - - Synopsis [Finds essential objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Ga2_FilterSelected( Rnm_Man_t * p, Vec_Int_t * vSelect ) -{ - Vec_Int_t * vNew, * vLeaves; - Gia_Obj_t * pObj, * pFanin; - int i, k, RetValue;//, Counters[3] = {0}; -/* - // check that selected are not visited - Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) - assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 1 ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - if ( Vec_IntFind(vSelect, Gia_ObjId(p->pGia, pObj)) == -1 ) - assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ); -*/ - - // verify -// Gia_ManForEachObj( p->pGia, pObj, i ) -// assert( Rnm_ObjCount(p, pObj) == 0 ); - - // increment fanin counters - Vec_IntClear( p->vFanins ); - Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) - { - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - if ( Rnm_ObjAddToCount(p, pFanin) == 0 ) - Vec_IntPush( p->vFanins, Gia_ObjId(p->pGia, pFanin) ); - } - - // find selected objects, which create potential constraints - // - flop objects - // - objects whose fanin belongs to the justified area - // - objects whose fanins overlap - // (these do not guantee reconvergence, but may potentially have it) - // (other objects cannot have reconvergence, even if they are added) - vNew = Vec_IntAlloc( 100 ); - Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) - { - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) ); - continue; - } - vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); - Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) - { - if ( Gia_ObjIsConst0(pFanin) - || (pFanin->Value && Rnm_ManObj(p, pFanin, 0)->fVisit0 == 1) - || Rnm_ObjCount(p, pFanin) > 1 - ) - { - Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) ); - break; - } - } -// Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) -// { -// Counters[1] += (pFanin->Value && Rnm_ManObj( p, pFanin, 0 )->fVisit0 == 1); -// Counters[2] += (Rnm_ObjCount(p, pFanin) > 1); -// } - } - RetValue = Vec_IntUniqify( vNew ); - assert( RetValue == 0 ); - -// printf( "\n*** Select = %5d. New = %5d. Flops = %5d. Visited = %5d. Fanins = %5d.\n", -// Vec_IntSize(vSelect), Vec_IntSize(vNew), Counters[0], Counters[1], Counters[2] ); - - // clear fanin counters - Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i ) - Rnm_ObjSetCount( p, pObj, 0 ); - return vNew; -} - - -/**Function************************************************************* - - Synopsis [Computes the refinement for a given counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose ) -{ - int fVerify = 0; -// int fPostProcess = 1; - Vec_Int_t * vSelected = Vec_IntAlloc( 100 ); - Vec_Int_t * vNew; - clock_t clk, clk2 = clock(); - int RetValue; - p->nCalls++; -// Gia_ManCleanValue( p->pGia ); - // initialize - p->pCex = pCex; - p->vMap = vMap; - p->fPropFanout = fPropFanout; - p->fVerbose = fVerbose; - // collects used objects - Rnm_ManCollect( p ); - // initialize datastructure - p->nObjsFrame = 1 + Vec_IntSize(vMap) + Vec_IntSize(p->vObjs); - p->nObjs = p->nObjsFrame * (pCex->iFrame + 1); - if ( p->nObjs > p->nObjsAlloc ) - p->pObjs = ABC_REALLOC( Rnm_Obj_t, p->pObjs, (p->nObjsAlloc = p->nObjs + 10000) ); - memset( p->pObjs, 0, sizeof(Rnm_Obj_t) * p->nObjs ); - // propagate priorities - clk = clock(); - if ( Rnm_ManSensitize( p ) ) // the CEX is not a true CEX - { - p->timeFwd += clock() - clk; - // select refinement - clk = clock(); - p->nVisited = 0; - Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), pCex->iFrame, vSelected ); - RetValue = Vec_IntUniqify( vSelected ); -// assert( RetValue == 0 ); - p->timeBwd += clock() - clk; - } - - if ( fPostProcess ) - { - vNew = Ga2_FilterSelected( p, vSelected ); - if ( Vec_IntSize(vNew) > 0 ) - { - Vec_IntFree( vSelected ); - vSelected = vNew; - } - else - { - Vec_IntFree( vNew ); - // printf( "\nBig refinement.\n" ); - } - } - else - { -/* - vNew = Rnm_ManRefineUnsatCore( p, vSelected ); - if ( Vec_IntSize(vNew) > 0 ) - { - Vec_IntFree( vSelected ); - vSelected = vNew; -// Vec_IntFree( vNew ); - } - else - { - Vec_IntFree( vNew ); - // printf( "\nBig refinement.\n" ); - } -*/ - } - - // clean values - Rnm_ManCleanValues( p ); - - // verify (empty) refinement - if ( fVerify ) - { - clk = clock(); - Rnm_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected ); - p->timeVer += clock() - clk; - } - -// printf( "\nOriginal (%d): \n", Vec_IntSize(p->vMap) ); -// Rnm_ManPrintSelected( p, vSelected ); - -// Ga2_StructAnalize( p->pGia, vMap, p->vObjs, vSelected ); -// printf( "\nObjects = %5d. Visited = %5d.\n", Vec_IntSize(p->vObjs), p->nVisited ); - -// Vec_IntReverseOrder( vSelected ); - p->timeTotal += clock() - clk2; - p->nRefines += Vec_IntSize(vSelected); - return vSelected; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsRef.h b/src/aig/gia/giaAbsRef.h deleted file mode 100644 index e44245be..00000000 --- a/src/aig/gia/giaAbsRef.h +++ /dev/null @@ -1,67 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsRef.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Refinement manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsRef.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef ABC__aig__gia__giaAbsRef_h -#define ABC__aig__gia__giaAbsRef_h - - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -ABC_NAMESPACE_HEADER_START - - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rnm_Man_t_ Rnm_Man_t; // refinement manager - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== giaAbsRef.c ===========================================================*/ -extern Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia ); -extern void Rnm_ManStop( Rnm_Man_t * p, int fProfile ); -extern double Rnm_ManMemoryUsage( Rnm_Man_t * p ); -extern Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose ); - - - -ABC_NAMESPACE_HEADER_END - - - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/gia/giaAbsRef2.c b/src/aig/gia/giaAbsRef2.c deleted file mode 100644 index e5bf3b0f..00000000 --- a/src/aig/gia/giaAbsRef2.c +++ /dev/null @@ -1,916 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsRef2.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Refinement manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsRef2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "giaAbsRef2.h" - -ABC_NAMESPACE_IMPL_START - -/* - Description of the refinement manager - - This refinement manager should be - * started by calling Rf2_ManStart() - this procedure takes one argument, the user's seq miter as a GIA manager - - the manager should have only one property output - - this manager should not change while the refinement manager is alive - - it cannot be used by external applications for any purpose - - when the refinement manager stop, GIA manager is the same as at the beginning - - in the meantime, it will have some data-structures attached to its nodes... - * stopped by calling Rf2_ManStop() - * between starting and stopping, refinements are obtained by calling Rf2_ManRefine() - - Procedure Rf2_ManRefine() takes the following arguments: - * the refinement manager previously started by Rf2_ManStart() - * counter-example (CEX) obtained by abstracting some logic of GIA - * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager - - only PI, flop outputs, and internal AND nodes can be used in vMap - - the ordering of objects in vMap is not important - - however, the index of a non-PI object in vMap is used as its priority - (the smaller the index, the more likely this non-PI object apears in a refinement) - - only the logic between PO and the objects listed in vMap is traversed by the manager - (as a result, GIA can be arbitrarily large, but only objects used in the abstraction - and the pseudo-PI, that is, objects in the cut, will be visited by the manager) - * flag fPropFanout defines whether value propagation is done through the fanout - - it this flag is enabled, theoretically refinement should be better (the result smaller) - * flag fVerbose may print some statistics - - The refinement manager returns a minimal-size array of integer IDs of GIA objects - which should be added to the abstraction to possibly prevent the given counter-example - - only flop output and internal AND nodes from vMap may appear in the resulting array - - if the resulting array is empty, the CEX is a true CEX - (in other words, non-PI objects are not needed to set the PO value to 1) - - Verification of the selected refinement is performed by - - initializing all PI objects in vMap to value 0 or 1 they have in the CEX - - initializing all remaining objects in vMap to value X - - initializing objects used in the refiment to value 0 or 1 they have in the CEX - - simulating through as many timeframes as required by the CEX - - if the PO value in the last frame is 1, the refinement is correct - (however, the minimality of the refinement is not currently checked) - -*/ - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rf2_Obj_t_ Rf2_Obj_t; // refinement object -struct Rf2_Obj_t_ -{ - unsigned Value : 1; // binary value - unsigned fVisit : 1; // visited object - unsigned fPPi : 1; // PPI object - unsigned Prio : 24; // priority (0 - highest) -}; - -struct Rf2_Man_t_ -{ - // user data - Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package) - Abc_Cex_t * pCex; // counter-example - Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order) - int fPropFanout; // propagate fanouts - int fVerbose; // verbose flag - // traversing data - Vec_Int_t * vObjs; // internal objects used in value propagation - Vec_Int_t * vFanins; // fanins of the PPI nodes - Vec_Int_t * pvVecs; // vectors of integers for each object - Vec_Vec_t * vGrp2Ppi; // for each node, the set of PPIs to include - int nMapWords; - // internal data - Rf2_Obj_t * pObjs; // refinement objects - int nObjs; // the number of used objects - int nObjsAlloc; // the number of allocated objects - int nObjsFrame; // the number of used objects in each frame - int nCalls; // total number of calls - int nRefines; // total refined objects - // statistics - clock_t timeFwd; // forward propagation - clock_t timeBwd; // backward propagation - clock_t timeVer; // ternary simulation - clock_t timeTotal; // other time -}; - -// accessing the refinement object -static inline Rf2_Obj_t * Rf2_ManObj( Rf2_Man_t * p, Gia_Obj_t * pObj, int f ) -{ - assert( Gia_ObjIsConst0(pObj) || pObj->Value ); - assert( (int)pObj->Value < p->nObjsFrame ); - assert( f >= 0 && f <= p->pCex->iFrame ); - return p->pObjs + f * p->nObjsFrame + pObj->Value; -} - -static inline Vec_Int_t * Rf2_ObjVec( Rf2_Man_t * p, Gia_Obj_t * pObj ) -{ - return p->pvVecs + Gia_ObjId(p->pGia, pObj); -} - - -static inline unsigned * Rf2_ObjA( Rf2_Man_t * p, Gia_Obj_t * pObj ) -{ - return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj)); -} -static inline unsigned * Rf2_ObjN( Rf2_Man_t * p, Gia_Obj_t * pObj ) -{ - return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj)) + p->nMapWords; -} -static inline void Rf2_ObjClear( Rf2_Man_t * p, Gia_Obj_t * pObj ) -{ - Vec_IntFill( Rf2_ObjVec(p, pObj), 2*p->nMapWords, 0 ); -} -static inline void Rf2_ObjStart( Rf2_Man_t * p, Gia_Obj_t * pObj, int i ) -{ - Vec_Int_t * vVec = Rf2_ObjVec(p, pObj); - int w; - Vec_IntClear( vVec ); - for ( w = 0; w < p->nMapWords; w++ ) - Vec_IntPush( vVec, 0 ); - for ( w = 0; w < p->nMapWords; w++ ) - Vec_IntPush( vVec, ~0 ); - Abc_InfoSetBit( Rf2_ObjA(p, pObj), i ); - Abc_InfoXorBit( Rf2_ObjN(p, pObj), i ); -} -static inline void Rf2_ObjCopy( Rf2_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) -{ - assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords ); - memcpy( Rf2_ObjA(p, pObj), Rf2_ObjA(p, pFanin), sizeof(unsigned) * 2 * p->nMapWords ); -} -static inline void Rf2_ObjDeriveAnd( Rf2_Man_t * p, Gia_Obj_t * pObj, int One ) -{ - unsigned * pInfo, * pInfo0, * pInfo1; - int i; - assert( Gia_ObjIsAnd(pObj) ); - assert( One == (int)pObj->fMark0 ); - assert( One == (int)(Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) ); - assert( One == (int)(Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) ); - assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords ); - - pInfo = Rf2_ObjA( p, pObj ); - pInfo0 = Rf2_ObjA( p, Gia_ObjFanin0(pObj) ); - pInfo1 = Rf2_ObjA( p, Gia_ObjFanin1(pObj) ); - for ( i = 0; i < p->nMapWords; i++ ) - pInfo[i] = One ? (pInfo0[i] & pInfo1[i]) : (pInfo0[i] | pInfo1[i]); - - pInfo = Rf2_ObjN( p, pObj ); - pInfo0 = Rf2_ObjN( p, Gia_ObjFanin0(pObj) ); - pInfo1 = Rf2_ObjN( p, Gia_ObjFanin1(pObj) ); - for ( i = 0; i < p->nMapWords; i++ ) - pInfo[i] = One ? (pInfo0[i] | pInfo1[i]) : (pInfo0[i] & pInfo1[i]); -} -static inline void Rf2_ObjPrint( Rf2_Man_t * p, Gia_Obj_t * pRoot ) -{ - Gia_Obj_t * pObj; - unsigned * pInfo; - int i; - pInfo = Rf2_ObjA( p, pRoot ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - if ( !Gia_ObjIsPi(p->pGia, pObj) ) - printf( "%d", Abc_InfoHasBit(pInfo, i) ); - printf( "\n" ); - pInfo = Rf2_ObjN( p, pRoot ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - if ( !Gia_ObjIsPi(p->pGia, pObj) ) - printf( "%d", !Abc_InfoHasBit(pInfo, i) ); - printf( "\n" ); - -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates a new manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia ) -{ - Rf2_Man_t * p; - assert( Gia_ManPoNum(pGia) == 1 ); - p = ABC_CALLOC( Rf2_Man_t, 1 ); - p->pGia = pGia; - p->vObjs = Vec_IntAlloc( 1000 ); - p->vFanins = Vec_IntAlloc( 1000 ); - p->pvVecs = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(pGia) ); - p->vGrp2Ppi = Vec_VecStart( 100 ); - Gia_ManCleanMark0(pGia); - Gia_ManCleanMark1(pGia); - return p; -} -void Rf2_ManStop( Rf2_Man_t * p, int fProfile ) -{ - if ( !p ) return; - // print runtime statistics - if ( fProfile && p->nCalls ) - { - double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc; - double MemOther = sizeof(Rf2_Man_t) + sizeof(Rf2_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs); - clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer; - printf( "Abstraction refinement runtime statistics:\n" ); - ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal ); - ABC_PRTP( "Justification", p->timeBwd, p->timeTotal ); - ABC_PRTP( "Verification ", p->timeVer, p->timeTotal ); - ABC_PRTP( "Other ", timeOther, p->timeTotal ); - ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); - printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n", - p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) ); - } - Vec_IntFree( p->vObjs ); - Vec_IntFree( p->vFanins ); - Vec_VecFree( p->vGrp2Ppi ); - ABC_FREE( p->pvVecs ); - ABC_FREE( p ); -} -double Rf2_ManMemoryUsage( Rf2_Man_t * p ) -{ - return (double)(sizeof(Rf2_Man_t) + sizeof(Vec_Int_t) * Gia_ManObjNum(p->pGia)); -} - - -/**Function************************************************************* - - Synopsis [Collect internal objects to be used in value propagation.] - - Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rf2_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs ) -{ - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p, pObj); - if ( Gia_ObjIsCo(pObj) ) - Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs ); - else if ( Gia_ObjIsAnd(pObj) ) - { - Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs ); - Rf2_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs ); - } - else if ( !Gia_ObjIsRo(p, pObj) ) - assert( 0 ); - Vec_IntPush( vObjs, Gia_ObjId(p, pObj) ); -} -void Rf2_ManCollect( Rf2_Man_t * p ) -{ - Gia_Obj_t * pObj = NULL; - int i; - // mark const/PIs/PPIs - Gia_ManIncrementTravId( p->pGia ); - Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - Gia_ObjSetTravIdCurrent( p->pGia, pObj ); - } - // collect objects - Vec_IntClear( p->vObjs ); - Rf2_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs ); - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - if ( Gia_ObjIsRo(p->pGia, pObj) ) - Rf2_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs ); - // the last object should be a CO - assert( Gia_ObjIsCo(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Performs sensitization analysis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rf2_ManSensitize( Rf2_Man_t * p ) -{ - Rf2_Obj_t * pRnm, * pRnm0, * pRnm1; - Gia_Obj_t * pObj; - int f, i, iBit = p->pCex->nRegs; - // const0 is initialized automatically in all timeframes - for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) - { - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - pRnm = Rf2_ManObj( p, pObj, f ); - pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i ); - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - { - assert( pObj->Value > 0 ); - pRnm->Prio = pObj->Value; - pRnm->fPPi = 1; - } - } - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - { - assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ); - pRnm = Rf2_ManObj( p, pObj, f ); - assert( !pRnm->fPPi ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f == 0 ) - continue; - pRnm0 = Rf2_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); - pRnm->Value = pRnm0->Value; - pRnm->Prio = pRnm0->Prio; - continue; - } - if ( Gia_ObjIsCo(pObj) ) - { - pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f ); - pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)); - pRnm->Prio = pRnm0->Prio; - continue; - } - assert( Gia_ObjIsAnd(pObj) ); - pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f ); - pRnm1 = Rf2_ManObj( p, Gia_ObjFanin1(pObj), f ); - pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj)); - if ( pRnm->Value == 1 ) - pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio ); - else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) - pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice - else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) - pRnm->Prio = pRnm0->Prio; - else - pRnm->Prio = pRnm1->Prio; - } - } - assert( iBit == p->pCex->nBits ); - pRnm = Rf2_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame ); - if ( pRnm->Value != 1 ) - printf( "Output value is incorrect.\n" ); - return pRnm->Prio; -} - - - -/**Function************************************************************* - - Synopsis [Performs refinement.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rf2_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes ) -{ - Gia_Obj_t * pObj; - int i, f, iBit = pCex->nRegs; - Gia_ObjTerSimSet0( Gia_ManConst0(p) ); - for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis ) - { - Gia_ManForEachObjVec( vMap, p, pObj, i ) - { - pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i ); - if ( !Gia_ObjIsPi(p, pObj) ) - Gia_ObjTerSimSetX( pObj ); - else if ( pObj->Value ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap - { - if ( pObj->Value ) - Gia_ObjTerSimSet1( pObj ); - else - Gia_ObjTerSimSet0( pObj ); - } - Gia_ManForEachObjVec( vObjs, p, pObj, i ) - { - if ( Gia_ObjIsCo(pObj) ) - Gia_ObjTerSimCo( pObj ); - else if ( Gia_ObjIsAnd(pObj) ) - Gia_ObjTerSimAnd( pObj ); - else if ( f == 0 ) - Gia_ObjTerSimSet0( pObj ); - else - Gia_ObjTerSimRo( p, pObj ); - } - } - Gia_ManForEachObjVec( vMap, p, pObj, i ) - pObj->Value = 0; - pObj = Gia_ManPo( p, 0 ); - if ( !Gia_ObjTerSimGet1(pObj) ) - Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); -} - -/**Function************************************************************* - - Synopsis [Computes the refinement for a given counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rf2_ManGatherFanins_rec( Rf2_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vFanins, int Depth, int RootId, int fFirst ) -{ - if ( Gia_ObjIsTravIdCurrent(p->pGia, pObj) ) - return; - Gia_ObjSetTravIdCurrent(p->pGia, pObj); - if ( pObj->fPhase && !fFirst ) - { - Vec_Int_t * vVec = Rf2_ObjVec( p, pObj ); -// if ( Vec_IntEntry( vVec, 0 ) == 0 ) -// return; - if ( Vec_IntSize(vVec) == 0 ) - Vec_IntPush( vFanins, Gia_ObjId(p->pGia, pObj) ); - Vec_IntPushUnique( vVec, RootId ); - if ( Depth == 0 ) - return; - } - if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) - return; - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - assert( pObj->fPhase ); - pObj = Gia_ObjRoToRi(p->pGia, pObj); - Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - 1, RootId, 0 ); - } - else if ( Gia_ObjIsAnd(pObj) ) - { - Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 ); - Rf2_ManGatherFanins_rec( p, Gia_ObjFanin1(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 ); - } - else assert( 0 ); -} -void Rf2_ManGatherFanins( Rf2_Man_t * p, int Depth ) -{ - Vec_Int_t * vUsed; - Vec_Int_t * vVec; - Gia_Obj_t * pObj; - int i, k, Entry; - // mark PPIs - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - vVec = Rf2_ObjVec( p, pObj ); - assert( Vec_IntSize(vVec) == 0 ); - Vec_IntPush( vVec, 0 ); - } - // collect internal - Vec_IntClear( p->vFanins ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - if ( Gia_ObjIsPi(p->pGia, pObj) ) - continue; - Gia_ManIncrementTravId( p->pGia ); - Rf2_ManGatherFanins_rec( p, pObj, p->vFanins, Depth, i, 1 ); - } - - vUsed = Vec_IntStart( Vec_IntSize(p->vMap) ); - - // evaluate collected - printf( "\nMap (%d): ", Vec_IntSize(p->vMap) ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - vVec = Rf2_ObjVec( p, pObj ); - if ( Vec_IntSize(vVec) > 1 ) - printf( "%d=%d ", i, Vec_IntSize(vVec) - 1 ); - Vec_IntForEachEntryStart( vVec, Entry, k, 1 ) - Vec_IntAddToEntry( vUsed, Entry, 1 ); - Vec_IntClear( vVec ); - } - printf( "\n" ); - // evaluate internal - printf( "Int (%d): ", Vec_IntSize(p->vFanins) ); - Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i ) - { - vVec = Rf2_ObjVec( p, pObj ); - if ( Vec_IntSize(vVec) > 1 ) - printf( "%d=%d ", i, Vec_IntSize(vVec) ); - if ( Vec_IntSize(vVec) > 1 ) - Vec_IntForEachEntry( vVec, Entry, k ) - Vec_IntAddToEntry( vUsed, Entry, 1 ); - Vec_IntClear( vVec ); - } - printf( "\n" ); - // evaluate PPIs - Vec_IntForEachEntry( vUsed, Entry, k ) - printf( "%d ", Entry ); - printf( "\n" ); - - Vec_IntFree( vUsed ); -} - - -/**Function************************************************************* - - Synopsis [Sort, make dup- and containment-free, and filter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Rf2_ManCountPpis( Rf2_Man_t * p ) -{ - Gia_Obj_t * pObj; - int i, Counter = 0; - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - Counter++; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Sort, make dup- and containment-free, and filter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Rf2_ManPrintVector( Vec_Int_t * p, int Num ) -{ - int i, k, Entry; - Vec_IntForEachEntry( p, Entry, i ) - { - for ( k = 0; k < Num; k++ ) - printf( "%c", '0' + ((Entry>>k) & 1) ); - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Sort, make dup- and containment-free, and filter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Rf2_ManProcessVector( Vec_Int_t * p, int Limit ) -{ -// int Start = Vec_IntSize(p); - int Start = 0; - int i, j, k, Entry, Entry2; -// printf( "%d", Vec_IntSize(p) ); - if ( Start > 5 ) - { - printf( "Before: \n" ); - Rf2_ManPrintVector( p, 31 ); - } - - k = 0; - Vec_IntForEachEntry( p, Entry, i ) - if ( Gia_WordCountOnes((unsigned)Entry) <= Limit ) - Vec_IntWriteEntry( p, k++, Entry ); - Vec_IntShrink( p, k ); - Vec_IntSort( p, 0 ); - k = 0; - Vec_IntForEachEntry( p, Entry, i ) - { - Vec_IntForEachEntryStop( p, Entry2, j, i ) - if ( (Entry2 & Entry) == Entry2 ) // Entry2 is a subset of Entry - break; - if ( j == i ) // Entry is not contained in any Entry2 - Vec_IntWriteEntry( p, k++, Entry ); - } - Vec_IntShrink( p, k ); -// printf( "->%d ", Vec_IntSize(p) ); - if ( Start > 5 ) - { - printf( "After: \n" ); - Rf2_ManPrintVector( p, 31 ); - k = 0; - } -} - -/**Function************************************************************* - - Synopsis [Assigns a unique justifification ID for each PPI.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rf2_ManAssignJustIds( Rf2_Man_t * p ) -{ - Gia_Obj_t * pObj; - int nPpis = Rf2_ManCountPpis( p ); - int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0); - int i, k = 0; - Vec_VecClear( p->vGrp2Ppi ); - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - Vec_VecPushInt( p->vGrp2Ppi, (k++ / nGroupSize), i ); - printf( "Considering %d PPIs combined into %d groups of size %d.\n", k, (k-1)/nGroupSize+1, nGroupSize ); - return (k-1)/nGroupSize+1; -} - -/**Function************************************************************* - - Synopsis [Sort, make dup- and containment-free, and filter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Rf2_ManPrintVectorSpecial( Rf2_Man_t * p, Vec_Int_t * vVec ) -{ - Gia_Obj_t * pObj; - int nPpis = Rf2_ManCountPpis( p ); - int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0); - int s, i, k, Entry, Counter; - - Vec_IntForEachEntry( vVec, Entry, s ) - { - k = 0; - Counter = 0; - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI - { - if ( (Entry >> (k++ / nGroupSize)) & 1 ) - printf( "1" ), Counter++; - else - printf( "0" ); - } - else - printf( "-" ); - } - printf( " %3d \n", Counter ); - } -} - -/**Function************************************************************* - - Synopsis [Performs justification propagation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Rf2_ManPropagate( Rf2_Man_t * p, int Limit ) -{ - Vec_Int_t * vVec, * vVec0, * vVec1; - Gia_Obj_t * pObj; - int f, i, k, j, Entry, Entry2, iBit = p->pCex->nRegs; - // init constant - pObj = Gia_ManConst0(p->pGia); - pObj->fMark0 = 0; - Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 ); - // iterate through the timeframes - for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) - { - // initialize frontier values and init justification sets - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i ); - Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 ); - } - // assign justification sets for PPis - Vec_VecForEachLevelInt( p->vGrp2Ppi, vVec, i ) - Vec_IntForEachEntry( vVec, Entry, k ) - { - assert( i < 31 ); - pObj = Gia_ManObj( p->pGia, Vec_IntEntry(p->vMap, Entry) ); - assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 1 ); - Vec_IntAddToEntry( Rf2_ObjVec(p, pObj), 0, (1 << i) ); - } - // propagate internal nodes - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - { - pObj->fMark0 = 0; - vVec = Rf2_ObjVec(p, pObj); - Vec_IntClear( vVec ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f == 0 ) - { - Vec_IntPush( vVec, 0 ); - continue; - } - pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0; - vVec0 = Rf2_ObjVec( p, Gia_ObjRoToRi(p->pGia, pObj) ); - Vec_IntAppend( vVec, vVec0 ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - { - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); - vVec0 = Rf2_ObjVec( p, Gia_ObjFanin0(pObj) ); - Vec_IntAppend( vVec, vVec0 ); - continue; - } - assert( Gia_ObjIsAnd(pObj) ); - vVec0 = Rf2_ObjVec(p, Gia_ObjFanin0(pObj)); - vVec1 = Rf2_ObjVec(p, Gia_ObjFanin1(pObj)); - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - if ( pObj->fMark0 == 1 ) - { - Vec_IntForEachEntry( vVec0, Entry, k ) - Vec_IntForEachEntry( vVec1, Entry2, j ) - Vec_IntPush( vVec, Entry | Entry2 ); - Rf2_ManProcessVector( vVec, Limit ); - } - else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 ) - { - Vec_IntAppend( vVec, vVec0 ); - Vec_IntAppend( vVec, vVec1 ); - Rf2_ManProcessVector( vVec, Limit ); - } - else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 ) - Vec_IntAppend( vVec, vVec0 ); - else - Vec_IntAppend( vVec, vVec1 ); - } - } - assert( iBit == p->pCex->nBits ); - if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 ) - printf( "Output value is incorrect.\n" ); - return Rf2_ObjVec(p, Gia_ManPo(p->pGia, 0)); -} - -/**Function************************************************************* - - Synopsis [Performs justification propagation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rf2_ManBounds( Rf2_Man_t * p ) -{ - Gia_Obj_t * pObj; - int f, i, iBit = p->pCex->nRegs; - // init constant - pObj = Gia_ManConst0(p->pGia); - pObj->fMark0 = 0; - Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) ); - // iterate through the timeframes - for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) - { - // initialize frontier values and init justification sets - Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) - { - assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); - pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i ); - Rf2_ObjStart( p, pObj, i ); - } - // propagate internal nodes - Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) - { - pObj->fMark0 = 0; - Rf2_ObjClear( p, pObj ); - if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( f == 0 ) - { - Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + i ); - continue; - } - pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0; - Rf2_ObjCopy( p, pObj, Gia_ObjRoToRi(p->pGia, pObj) ); - continue; - } - if ( Gia_ObjIsCo(pObj) ) - { - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); - Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) ); - continue; - } - assert( Gia_ObjIsAnd(pObj) ); - pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); - if ( pObj->fMark0 == 1 ) - Rf2_ObjDeriveAnd( p, pObj, 1 ); - else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 ) - Rf2_ObjDeriveAnd( p, pObj, 0 ); - else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 ) - Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) ); - else - Rf2_ObjCopy( p, pObj, Gia_ObjFanin1(pObj) ); - } - } - assert( iBit == p->pCex->nBits ); - if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 ) - printf( "Output value is incorrect.\n" ); - - printf( "Bounds: \n" ); - Rf2_ObjPrint( p, Gia_ManPo(p->pGia, 0) ); -} - -/**Function************************************************************* - - Synopsis [Computes the refinement for a given counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose ) -{ - Vec_Int_t * vJusts; -// Vec_Int_t * vSelected = Vec_IntAlloc( 100 ); - Vec_Int_t * vSelected = NULL; - clock_t clk, clk2 = clock(); - int nGroups; - p->nCalls++; - // initialize - p->pCex = pCex; - p->vMap = vMap; - p->fPropFanout = fPropFanout; - p->fVerbose = fVerbose; - // collects used objects - Rf2_ManCollect( p ); - // collect reconvergence points -// Rf2_ManGatherFanins( p, 2 ); - // propagate justification IDs - nGroups = Rf2_ManAssignJustIds( p ); - vJusts = Rf2_ManPropagate( p, 32 ); - -// printf( "\n" ); -// Rf2_ManPrintVector( vJusts, nGroups ); - Rf2_ManPrintVectorSpecial( p, vJusts ); - if ( Vec_IntSize(vJusts) == 0 ) - { - printf( "Empty set of justifying subsets.\n" ); - return NULL; - } - -// p->nMapWords = Abc_BitWordNum( Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) + 1 ); // Map + Flops + Const -// Rf2_ManBounds( p ); - - // select the result -// Abc_PrintTime( 1, "Time", clock() - clk2 ); - - // verify (empty) refinement - clk = clock(); -// Rf2_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected ); -// Vec_IntUniqify( vSelected ); -// Vec_IntReverseOrder( vSelected ); - p->timeVer += clock() - clk; - p->timeTotal += clock() - clk2; -// p->nRefines += Vec_IntSize(vSelected); - return vSelected; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaAbsRef2.h b/src/aig/gia/giaAbsRef2.h deleted file mode 100644 index f0ad9670..00000000 --- a/src/aig/gia/giaAbsRef2.h +++ /dev/null @@ -1,67 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsRef2.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Refinement manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsRef2.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef ABC__aig__gia__giaAbsRef2_h -#define ABC__aig__gia__giaAbsRef2_h - - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -ABC_NAMESPACE_HEADER_START - - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rf2_Man_t_ Rf2_Man_t; // refinement manager - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== giaAbsRef.c ===========================================================*/ -extern Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia ); -extern void Rf2_ManStop( Rf2_Man_t * p, int fProfile ); -extern double Rf2_ManMemoryUsage( Rf2_Man_t * p ); -extern Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose ); - - - -ABC_NAMESPACE_HEADER_END - - - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/gia/giaAbsVta.c b/src/aig/gia/giaAbsVta.c deleted file mode 100644 index 517c1d3d..00000000 --- a/src/aig/gia/giaAbsVta.c +++ /dev/null @@ -1,1799 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaAbsVta.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Variable time-frame abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaAbsVta.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "sat/bsat/satSolver2.h" -#include "base/main/main.h" - -ABC_NAMESPACE_IMPL_START - -#define VTA_LARGE 0xFFFFFFF - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Vta_Obj_t_ Vta_Obj_t; // object -struct Vta_Obj_t_ -{ - int iObj; - int iFrame; - int iNext; - unsigned Prio : 28; // related to VTA_LARGE - unsigned Value : 2; - unsigned fAdded : 1; - unsigned fVisit : 1; -}; - -typedef struct Vta_Man_t_ Vta_Man_t; // manager -struct Vta_Man_t_ -{ - // user data - Gia_Man_t * pGia; // AIG manager - Gia_ParVta_t* pPars; // parameters - // internal data - int nObjs; // the number of objects - int nObjsAlloc; // the number of objects allocated - int nBins; // number of hash table entries - int * pBins; // hash table bins - Vta_Obj_t * pObjs; // storage for objects - Vec_Int_t * vOrder; // objects in DPS order - // abstraction - int nObjBits; // the number of bits to represent objects - unsigned nObjMask; // object mask - Vec_Ptr_t * vFrames; // start abstraction for each frame - int nWords; // the number of words in the record - int nCexes; // the number of CEXes - int nObjAdded; // objects added to the abstraction - Vec_Int_t * vSeens; // seen objects - Vec_Bit_t * vSeenGla; // seen objects in all frames - int nSeenGla; // seen objects in all frames - int nSeenAll; // seen objects in all frames - // other data - Vec_Ptr_t * vCores; // unsat core for each frame - sat_solver2 * pSat; // incremental SAT solver - Vec_Int_t * vAddedNew; // the IDs of variables added to the solver - // statistics - clock_t timeSat; - clock_t timeUnsat; - clock_t timeCex; - clock_t timeOther; -}; - - -// ternary simulation - -#define VTA_VAR0 1 -#define VTA_VAR1 2 -#define VTA_VARX 3 - -static inline int Vta_ValIs0( Vta_Obj_t * pThis, int fCompl ) -{ - if ( pThis->Value == VTA_VAR1 && fCompl ) - return 1; - if ( pThis->Value == VTA_VAR0 && !fCompl ) - return 1; - return 0; -} -static inline int Vta_ValIs1( Vta_Obj_t * pThis, int fCompl ) -{ - if ( pThis->Value == VTA_VAR0 && fCompl ) - return 1; - if ( pThis->Value == VTA_VAR1 && !fCompl ) - return 1; - return 0; -} - -static inline Vta_Obj_t * Vta_ManObj( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; } -static inline int Vta_ObjId( Vta_Man_t * p, Vta_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } - -#define Vta_ManForEachObj( p, pObj, i ) \ - for ( i = 1; (i < p->nObjs) && ((pObj) = Vta_ManObj(p, i)); i++ ) -#define Vta_ManForEachObjObj( p, pObjVta, pObjGia, i ) \ - for ( i = 1; (i < p->nObjs) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ ) -#define Vta_ManForEachObjObjReverse( p, pObjVta, pObjGia, i ) \ - for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ ) - -#define Vta_ManForEachObjVec( vVec, p, pObj, i ) \ - for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) -#define Vta_ManForEachObjVecReverse( vVec, p, pObj, i ) \ - for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i-- ) - -#define Vta_ManForEachObjObjVec( vVec, p, pObj, pObjG, i ) \ - for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i++ ) -#define Vta_ManForEachObjObjVecReverse( vVec, p, pObj, pObjG, i ) \ - for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i-- ) - - -// abstraction is given as an array of integers: -// - the first entry is the number of timeframes (F) -// - the next (F+1) entries give the beginning position of each timeframe -// - the following entries give the object IDs -// invariant: assert( vec[vec[0]+1] == size(vec) ); - -extern void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [This procedure sets default parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_VtaSetDefaultParams( Gia_ParVta_t * p ) -{ - memset( p, 0, sizeof(Gia_ParVta_t) ); - p->nFramesMax = 0; // maximum frames - p->nFramesStart = 0; // starting frame - p->nFramesPast = 4; // overlap frames - p->nConfLimit = 0; // conflict limit - p->nLearnedMax = 1000; // max number of learned clauses - p->nLearnedStart = 1000; // max number of learned clauses - p->nLearnedDelta = 200; // max number of learned clauses - p->nLearnedPerce = 70; // max number of learned clauses - p->nTimeOut = 0; // timeout in seconds - p->nRatioMin = 0; // stop when less than this % of object is abstracted - p->nRatioMax = 30; // restart when more than this % of object is abstracted - p->fUseTermVars = 0; // use terminal variables - p->fUseRollback = 0; // use rollback to the starting number of frames - p->fPropFanout = 1; // propagate fanouts during refinement - p->fVerbose = 0; // verbose flag - p->iFrame = -1; // the number of frames covered - p->iFrameProved = -1; // the number of frames proved - p->nFramesNoChangeLim = 1; // the number of frames without change to dump abstraction -} - -/**Function************************************************************* - - Synopsis [Converting from one array to per-frame arrays.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Gia_VtaAbsToFrames( Vec_Int_t * vAbs ) -{ - Vec_Ptr_t * vFrames; - Vec_Int_t * vFrame; - int i, k, Entry, iStart, iStop = -1; - int nFrames = Vec_IntEntry( vAbs, 0 ); - assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) ); - vFrames = Vec_PtrAlloc( nFrames ); - for ( i = 0; i < nFrames; i++ ) - { - iStart = Vec_IntEntry( vAbs, i+1 ); - iStop = Vec_IntEntry( vAbs, i+2 ); - vFrame = Vec_IntAlloc( iStop - iStart ); - Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop ) - Vec_IntPush( vFrame, Entry ); - Vec_PtrPush( vFrames, vFrame ); - } - assert( iStop == Vec_IntSize(vAbs) ); - return vFrames; -} - -/**Function************************************************************* - - Synopsis [Converting from per-frame arrays to one integer array.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_VtaFramesToAbs( Vec_Vec_t * vFrames ) -{ - Vec_Int_t * vOne, * vAbs; - int i, k, Entry, nSize; - vAbs = Vec_IntAlloc( 2 + Vec_VecSize(vFrames) + Vec_VecSizeSize(vFrames) ); - Vec_IntPush( vAbs, Vec_VecSize(vFrames) ); - nSize = Vec_VecSize(vFrames) + 2; - Vec_VecForEachLevelInt( vFrames, vOne, i ) - { - Vec_IntPush( vAbs, nSize ); - nSize += Vec_IntSize( vOne ); - } - Vec_IntPush( vAbs, nSize ); - assert( Vec_IntSize(vAbs) == Vec_VecSize(vFrames) + 2 ); - Vec_VecForEachLevelInt( vFrames, vOne, i ) - Vec_IntForEachEntry( vOne, Entry, k ) - Vec_IntPush( vAbs, Entry ); - assert( Vec_IntEntry(vAbs, Vec_IntEntry(vAbs,0)+1) == Vec_IntSize(vAbs) ); - return vAbs; -} - -/**Function************************************************************* - - Synopsis [Detects how many frames are completed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vta_ManDeriveAbsAll( Vec_Int_t * p, int nWords ) -{ - Vec_Int_t * vRes; - unsigned * pThis; - int i, w, nObjs = Vec_IntSize(p) / nWords; - assert( Vec_IntSize(p) % nWords == 0 ); - vRes = Vec_IntAlloc( nObjs ); - for ( i = 0; i < nObjs; i++ ) - { - pThis = (unsigned *)Vec_IntEntryP( p, nWords * i ); - for ( w = 0; w < nWords; w++ ) - if ( pThis[w] ) - break; - Vec_IntPush( vRes, (int)(w < nWords) ); - } - return vRes; -} - -/**Function************************************************************* - - Synopsis [Collect nodes/flops involved in different timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Vec_IntDoubleWidth( Vec_Int_t * p, int nWords ) -{ - int * pArray = ABC_CALLOC( int, Vec_IntSize(p) * 2 ); - int i, w, nObjs = Vec_IntSize(p) / nWords; - assert( Vec_IntSize(p) % nWords == 0 ); - for ( i = 0; i < nObjs; i++ ) - for ( w = 0; w < nWords; w++ ) - pArray[2 * nWords * i + w] = p->pArray[nWords * i + w]; - ABC_FREE( p->pArray ); - p->pArray = pArray; - p->nSize *= 2; - p->nCap = p->nSize; - return 2 * nWords; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vga_ManHash( int iObj, int iFrame, int nBins ) -{ - return ((unsigned)((iObj + iFrame)*(iObj + iFrame + 1))) % nBins; -} -static inline int * Vga_ManLookup( Vta_Man_t * p, int iObj, int iFrame ) -{ - Vta_Obj_t * pThis; - int * pPlace = p->pBins + Vga_ManHash( iObj, iFrame, p->nBins ); - for ( pThis = Vta_ManObj(p, *pPlace); - pThis; pPlace = &pThis->iNext, - pThis = Vta_ManObj(p, *pPlace) ) - if ( pThis->iObj == iObj && pThis->iFrame == iFrame ) - break; - return pPlace; -} -static inline Vta_Obj_t * Vga_ManFind( Vta_Man_t * p, int iObj, int iFrame ) -{ - int * pPlace = Vga_ManLookup( p, iObj, iFrame ); - return Vta_ManObj(p, *pPlace); -} -static inline Vta_Obj_t * Vga_ManFindOrAdd( Vta_Man_t * p, int iObj, int iFrame ) -{ - Vta_Obj_t * pThis; - int i, * pPlace; - assert( iObj >= 0 && iFrame >= -1 ); - if ( p->nObjs == p->nObjsAlloc ) - { - // resize objects - p->pObjs = ABC_REALLOC( Vta_Obj_t, p->pObjs, 2 * p->nObjsAlloc ); - memset( p->pObjs + p->nObjsAlloc, 0, p->nObjsAlloc * sizeof(Vta_Obj_t) ); - p->nObjsAlloc *= 2; - // rehash entries in the table - ABC_FREE( p->pBins ); - p->nBins = Abc_PrimeCudd( 2 * p->nBins ); - p->pBins = ABC_CALLOC( int, p->nBins ); - Vta_ManForEachObj( p, pThis, i ) - { - pThis->iNext = 0; - pPlace = Vga_ManLookup( p, pThis->iObj, pThis->iFrame ); - assert( *pPlace == 0 ); - *pPlace = i; - } - } - pPlace = Vga_ManLookup( p, iObj, iFrame ); - if ( *pPlace ) - return Vta_ManObj(p, *pPlace); - *pPlace = p->nObjs++; - pThis = Vta_ManObj(p, *pPlace); - pThis->iObj = iObj; - pThis->iFrame = iFrame; - return pThis; -} -static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame ) -{ - int * pPlace = Vga_ManLookup( p, iObj, iFrame ); - Vta_Obj_t * pThis = Vta_ManObj(p, *pPlace); - assert( pThis != NULL ); - *pPlace = pThis->iNext; - pThis->iNext = -1; -} - - -/**Function************************************************************* - - Synopsis [Derives counter-example using current assignments.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Vga_ManDeriveCex( Vta_Man_t * p ) -{ - Abc_Cex_t * pCex; - Vta_Obj_t * pThis; - Gia_Obj_t * pObj; - int i; - pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); - pCex->iPo = 0; - pCex->iFrame = p->pPars->iFrame; - Vta_ManForEachObjObj( p, pThis, pObj, i ) - if ( Gia_ObjIsPi(p->pGia, pObj) && sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ) - Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) ); - return pCex; -} - -/**Function************************************************************* - - Synopsis [Remaps core into frame/node pairs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vta_ManUnsatCoreRemap( Vta_Man_t * p, Vec_Int_t * vCore ) -{ - Vta_Obj_t * pThis; - int i, Entry; - Vec_IntForEachEntry( vCore, Entry, i ) - { - pThis = Vta_ManObj( p, Entry ); - Entry = (pThis->iFrame << p->nObjBits) | pThis->iObj; - Vec_IntWriteEntry( vCore, i, Entry ); - } -} - -/**Function************************************************************* - - Synopsis [Compares two objects by their distance.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Vta_ManComputeDepthIncrease( Vta_Obj_t ** pp1, Vta_Obj_t ** pp2 ) -{ - int Diff = (*pp1)->Prio - (*pp2)->Prio; - if ( Diff < 0 ) - return -1; - if ( Diff > 0 ) - return 1; - Diff = (*pp1) - (*pp2); - if ( Diff < 0 ) - return -1; - if ( Diff > 0 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the object is already used.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj ) -{ - int i; - unsigned * pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj ); - for ( i = 0; i < p->nWords; i++ ) - if ( pInfo[i] ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Finds predecessors of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vta_ObjPreds( Vta_Man_t * p, Vta_Obj_t * pThis, Gia_Obj_t * pObj, Vta_Obj_t ** ppThis0, Vta_Obj_t ** ppThis1 ) -{ - *ppThis0 = NULL; - *ppThis1 = NULL; -// if ( !pThis->fAdded ) -// return; - assert( !Gia_ObjIsPi(p->pGia, pObj) ); - if ( Gia_ObjIsConst0(pObj) || (Gia_ObjIsCi(pObj) && pThis->iFrame == 0) ) - return; - if ( Gia_ObjIsAnd(pObj) ) - { - *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); - *ppThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); -// assert( *ppThis0 && *ppThis1 ); - return; - } - assert( Gia_ObjIsRo(p->pGia, pObj) && pThis->iFrame > 0 ); - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); -// assert( *ppThis0 ); -} - -/**Function************************************************************* - - Synopsis [Collect const/PI/RO/AND in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vta_ManCollectNodes_rec( Vta_Man_t * p, Vta_Obj_t * pThis, Vec_Int_t * vOrder ) -{ - Gia_Obj_t * pObj; - Vta_Obj_t * pThis0, * pThis1; - if ( pThis->fVisit ) - return; - pThis->fVisit = 1; - pObj = Gia_ManObj( p->pGia, pThis->iObj ); - if ( pThis->fAdded ) - { - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - if ( pThis0 ) Vta_ManCollectNodes_rec( p, pThis0, vOrder ); - if ( pThis1 ) Vta_ManCollectNodes_rec( p, pThis1, vOrder ); - } - Vec_IntPush( vOrder, Vta_ObjId(p, pThis) ); -} -Vec_Int_t * Vta_ManCollectNodes( Vta_Man_t * p, int f ) -{ - Vta_Obj_t * pThis; - Gia_Obj_t * pObj; - Vec_IntClear( p->vOrder ); - pObj = Gia_ManPo( p->pGia, 0 ); - pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f ); - assert( pThis != NULL ); - assert( !pThis->fVisit ); - Vta_ManCollectNodes_rec( p, pThis, p->vOrder ); - assert( pThis->fVisit ); - return p->vOrder; -} - -/**Function************************************************************* - - Synopsis [Refines abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vta_ManSatVerify( Vta_Man_t * p ) -{ - Vta_Obj_t * pThis, * pThis0, * pThis1; - Gia_Obj_t * pObj; - int i; - Vta_ManForEachObj( p, pThis, i ) - pThis->Value = (sat_solver2_var_value(p->pSat, i) ? VTA_VAR1 : VTA_VAR0); - Vta_ManForEachObjObj( p, pThis, pObj, i ) - { - if ( !pThis->fAdded ) - continue; - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - if ( Gia_ObjIsAnd(pObj) ) - { - if ( pThis->Value == VTA_VAR1 ) - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); - else if ( pThis->Value == VTA_VAR0 ) - assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ); - else assert( 0 ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - if ( pThis->iFrame == 0 ) - assert( pThis->Value == VTA_VAR0 ); - else if ( pThis->Value == VTA_VAR0 ) - assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ); - else if ( pThis->Value == VTA_VAR1 ) - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ); - else assert( 0 ); - } - } -} - -/**Function************************************************************* - - Synopsis [Refines abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vta_ManProfileAddition( Vta_Man_t * p, Vec_Int_t * vTermsToAdd ) -{ - Vta_Obj_t * pThis; - Gia_Obj_t * pObj; - // profile the added ones - int i, * pCounters = ABC_CALLOC( int, p->pPars->iFrame+1 ); - Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i ) - pCounters[pThis->iFrame]++; - for ( i = 0; i <= p->pPars->iFrame; i++ ) - Abc_Print( 1, "%2d", pCounters[i] ); - Abc_Print( 1, "***\n" ); -} - -/**Function************************************************************* - - Synopsis [Refines abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p, int f ) -{ - int fVerify = 0; - Abc_Cex_t * pCex = NULL; - Vec_Int_t * vOrder, * vTermsToAdd; - Vec_Ptr_t * vTermsUsed, * vTermsUnused; - Vta_Obj_t * pThis, * pThis0, * pThis1, * pTop; - Gia_Obj_t * pObj; - int i, Counter; - - if ( fVerify ) - Vta_ManSatVerify( p ); - - // collect nodes in a topological order - vOrder = Vta_ManCollectNodes( p, f ); - Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) - { - pThis->Prio = VTA_LARGE; - pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0; - pThis->fVisit = 0; - } - - // verify - if ( fVerify ) - Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) - { - if ( !pThis->fAdded ) - continue; - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - if ( Gia_ObjIsAnd(pObj) ) - { - if ( pThis->Value == VTA_VAR1 ) - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); - else if ( pThis->Value == VTA_VAR0 ) - assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ); - else assert( 0 ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - if ( pThis->iFrame == 0 ) - assert( pThis->Value == VTA_VAR0 ); - else if ( pThis->Value == VTA_VAR0 ) - assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ); - else if ( pThis->Value == VTA_VAR1 ) - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ); - else assert( 0 ); - } - } - - // compute distance in reverse order - pThis = Vta_ManObj( p, Vec_IntEntryLast(vOrder) ); - pThis->Prio = 1; - // collect used and unused terms - vTermsUsed = Vec_PtrAlloc( 1015 ); - vTermsUnused = Vec_PtrAlloc( 1016 ); - Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) - { - // there is no unreachable states - assert( pThis->Prio < VTA_LARGE ); - // skip constants and PIs - if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) - { - pThis->Prio = 0; // set highest priority - continue; - } - // collect terminals - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); - if ( !pThis->fAdded ) - { - assert( pThis->Prio > 0 ); - if ( Vta_ManObjIsUsed(p, pThis->iObj) ) - Vec_PtrPush( vTermsUsed, pThis ); - else - Vec_PtrPush( vTermsUnused, pThis ); - continue; - } - // propagate - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - if ( pThis0 ) - pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 ); - if ( pThis1 ) - pThis1->Prio = Abc_MinInt( pThis1->Prio, pThis->Prio + 1 ); - } - -/* - Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) - if ( pThis->Prio > 0 ) - pThis->Prio = 10; -*/ -/* - // update priorities according to reconvergence counters - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) - { - Vta_Obj_t * pThis0, * pThis1; - Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj ); - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - pThis->Prio += 10000000; - if ( pThis0 ) - pThis->Prio -= 1000000 * pThis0->fAdded; - if ( pThis1 ) - pThis->Prio -= 1000000 * pThis1->fAdded; - } - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) - { - Vta_Obj_t * pThis0, * pThis1; - Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj ); - Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); - pThis->Prio += 10000000; - if ( pThis0 ) - pThis->Prio -= 1000000 * pThis0->fAdded; - if ( pThis1 ) - pThis->Prio -= 1000000 * pThis1->fAdded; - } -*/ - - - // update priorities according to reconvergence counters - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) - pThis->Prio = pThis->iObj; - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) - pThis->Prio = pThis->iObj; - - - // objects with equal distance should receive priority based on number - // those objects whose prototypes have been added in other timeframes - // should have higher priority than the current object - Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease ); - Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease ); - if ( Vec_PtrSize(vTermsUsed) > 1 ) - { - pThis0 = (Vta_Obj_t *)Vec_PtrEntry(vTermsUsed, 0); - pThis1 = (Vta_Obj_t *)Vec_PtrEntryLast(vTermsUsed); - assert( pThis0->Prio <= pThis1->Prio ); - } - // assign the priority based on these orders - Counter = 1; - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) - pThis->Prio = Counter++; - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) - pThis->Prio = Counter++; -// Abc_Print( 1, "Used %d Unused %d\n", Vec_PtrSize(vTermsUsed), Vec_PtrSize(vTermsUnused) ); - - - // propagate in the direct order - Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) - { - assert( pThis->fVisit == 0 ); - assert( pThis->Prio < VTA_LARGE ); - // skip terminal objects - if ( !pThis->fAdded ) - continue; - // assumes that values are assigned!!! - assert( pThis->Value != 0 ); - // propagate - if ( Gia_ObjIsAnd(pObj) ) - { - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); - pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); - assert( pThis0 && pThis1 ); - if ( pThis->Value == VTA_VAR1 ) - { - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); - pThis->Prio = Abc_MaxInt( pThis0->Prio, pThis1->Prio ); - } - else if ( pThis->Value == VTA_VAR0 ) - { - if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) - pThis->Prio = Abc_MinInt( pThis0->Prio, pThis1->Prio ); // choice!!! - else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) - pThis->Prio = pThis0->Prio; - else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) - pThis->Prio = pThis1->Prio; - else assert( 0 ); - } - else assert( 0 ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( pThis->iFrame > 0 ) - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); - assert( pThis0 ); - pThis->Prio = pThis0->Prio; - } - else - pThis->Prio = 0; - } - else if ( Gia_ObjIsConst0(pObj) ) - pThis->Prio = 0; - else - assert( 0 ); - } - - // select important values - pTop = Vta_ManObj( p, Vec_IntEntryLast(vOrder) ); - pTop->fVisit = 1; - vTermsToAdd = Vec_IntAlloc( 100 ); - Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) - { - if ( !pThis->fVisit ) - continue; - pThis->fVisit = 0; - assert( pThis->Prio >= 0 && pThis->Prio <= pTop->Prio ); - // skip terminal objects - if ( !pThis->fAdded ) - { - assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ); - Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) ); - continue; - } - // assumes that values are assigned!!! - assert( pThis->Value != 0 ); - // propagate - if ( Gia_ObjIsAnd(pObj) ) - { - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); - pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); - assert( pThis0 && pThis1 ); - if ( pThis->Value == VTA_VAR1 ) - { - assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); - assert( pThis0->Prio <= pThis->Prio ); - assert( pThis1->Prio <= pThis->Prio ); - pThis0->fVisit = 1; - pThis1->fVisit = 1; - } - else if ( pThis->Value == VTA_VAR0 ) - { - if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) - { - if ( pThis0->fVisit ) - { - } - else if ( pThis1->fVisit ) - { - } - else if ( pThis0->Prio <= pThis1->Prio ) // choice!!! - { - pThis0->fVisit = 1; - assert( pThis0->Prio == pThis->Prio ); - } - else - { - pThis1->fVisit = 1; - assert( pThis1->Prio == pThis->Prio ); - } - } - else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) - { - pThis0->fVisit = 1; - assert( pThis0->Prio == pThis->Prio ); - } - else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) - { - pThis1->fVisit = 1; - assert( pThis1->Prio == pThis->Prio ); - } - else assert( 0 ); - } - else assert( 0 ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( pThis->iFrame > 0 ) - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); - assert( pThis0 ); - pThis0->fVisit = 1; - assert( pThis0->Prio == pThis->Prio ); - } - } - else if ( !Gia_ObjIsConst0(pObj) ) - assert( 0 ); - } - - if ( p->pPars->fAddLayer ) - { - // mark those currently included - Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) - { - assert( pThis->fVisit == 0 ); - pThis->fVisit = 1; - } - // add used terms, which have close relationship - Counter = Vec_IntSize(vTermsToAdd); - Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) - { - if ( pThis->fVisit ) - continue; - // Vta_ObjPreds( p, pThis, Gia_ManObj(p->pGia, pThis->iObj), &pThis0, &pThis1 ); - // if ( (pThis0 && (pThis0->fAdded || pThis0->fVisit)) || (pThis1 && (pThis1->fAdded || pThis1->fVisit)) ) - Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) ); - } - // remove those currenty included - Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) - pThis->fVisit = 0; - } -// printf( "\n%d -> %d\n", Counter, Vec_IntSize(vTermsToAdd) ); -//Vec_IntReverseOrder( vTermsToAdd ); -//Vec_IntSort( vTermsToAdd, 1 ); - - - // cleanup - Vec_PtrFree( vTermsUsed ); - Vec_PtrFree( vTermsUnused ); - - - if ( fVerify ) - { - // verify - Vta_ManForEachObjVec( vOrder, p, pThis, i ) - pThis->Value = VTA_VARX; - Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) - { - assert( !pThis->fAdded ); - pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0; - } - // simulate - Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) - { - assert( pThis->fVisit == 0 ); - if ( !pThis->fAdded ) - continue; - if ( Gia_ObjIsAnd(pObj) ) - { - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); - pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); - assert( pThis0 && pThis1 ); - if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ) - pThis->Value = VTA_VAR1; - else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) - pThis->Value = VTA_VAR0; - else - pThis->Value = VTA_VARX; - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( pThis->iFrame > 0 ) - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); - assert( pThis0 ); - if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) - pThis->Value = VTA_VAR0; - else if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ) - pThis->Value = VTA_VAR1; - else - pThis->Value = VTA_VARX; - } - else - { - pThis->Value = VTA_VAR0; - } - } - else if ( Gia_ObjIsConst0(pObj) ) - { - pThis->Value = VTA_VAR0; - } - else assert( 0 ); - // double check the solver - assert( pThis->Value == VTA_VARX || (int)pThis->Value == (sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0) ); - } - - // check the output - if ( !Vta_ValIs1(pTop, Gia_ObjFaninC0(Gia_ManPo(p->pGia, 0))) ) - Abc_Print( 1, "Vta_ManRefineAbstraction(): Terminary simulation verification failed!\n" ); -// else -// Abc_Print( 1, "Verification OK.\n" ); - } - - - // produce true counter-example - if ( pTop->Prio == 0 ) - pCex = Vga_ManDeriveCex( p ); - else - { -// Vta_ManProfileAddition( p, vTermsToAdd ); - - Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i ) - if ( !Gia_ObjIsPi(p->pGia, pObj) ) - Vga_ManAddClausesOne( p, pThis->iObj, pThis->iFrame ); - sat_solver2_simplify( p->pSat ); - } - p->nObjAdded += Vec_IntSize(vTermsToAdd); - Vec_IntFree( vTermsToAdd ); - return pCex; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vta_Man_t * Vga_ManStart( Gia_Man_t * pGia, Gia_ParVta_t * pPars ) -{ - Vta_Man_t * p; - p = ABC_CALLOC( Vta_Man_t, 1 ); - p->pGia = pGia; - p->pPars = pPars; - // internal data - p->nObjsAlloc = (1 << 18); - p->pObjs = ABC_CALLOC( Vta_Obj_t, p->nObjsAlloc ); - p->nObjs = 1; - p->nBins = Abc_PrimeCudd( 2*p->nObjsAlloc ); - p->pBins = ABC_CALLOC( int, p->nBins ); - p->vOrder = Vec_IntAlloc( 1013 ); - // abstraction - p->nObjBits = Abc_Base2Log( Gia_ManObjNum(pGia) ); - p->nObjMask = (1 << p->nObjBits) - 1; - assert( Gia_ManObjNum(pGia) <= (int)p->nObjMask ); - p->nWords = 1; - p->vSeens = Vec_IntStart( Gia_ManObjNum(pGia) * p->nWords ); - p->vSeenGla = Vec_BitStart( Gia_ManObjNum(pGia) ); - p->nSeenGla = 1; - p->nSeenAll = 1; - // other data - p->vCores = Vec_PtrAlloc( 100 ); - p->pSat = sat_solver2_new(); - p->pSat->pPrf1 = Vec_SetAlloc( 20 ); -// p->pSat->fVerbose = p->pPars->fVerbose; -// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax ); - p->pSat->nLearntStart = p->pPars->nLearnedStart; - p->pSat->nLearntDelta = p->pPars->nLearnedDelta; - p->pSat->nLearntRatio = p->pPars->nLearnedPerce; - p->pSat->nLearntMax = p->pSat->nLearntStart; - // start the abstraction - assert( pGia->vObjClasses != NULL ); - p->vFrames = Gia_VtaAbsToFrames( pGia->vObjClasses ); - p->vAddedNew = Vec_IntAlloc( 1000 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Delete manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vga_ManStop( Vta_Man_t * p ) -{ - if ( p->pPars->fVerbose ) - Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n", - sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat), - sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); - Vec_VecFreeP( (Vec_Vec_t **)&p->vCores ); - Vec_VecFreeP( (Vec_Vec_t **)&p->vFrames ); - Vec_BitFreeP( &p->vSeenGla ); - Vec_IntFreeP( &p->vSeens ); - Vec_IntFreeP( &p->vOrder ); - Vec_IntFreeP( &p->vAddedNew ); - sat_solver2_delete( p->pSat ); - ABC_FREE( p->pBins ); - ABC_FREE( p->pObjs ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Returns the output literal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f ) -{ - Gia_Obj_t * pObj = Gia_ManPo(p->pGia, 0); - Vta_Obj_t * pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f ); - assert( pThis != NULL && pThis->fAdded ); - if ( f == 0 && Gia_ObjIsRo(p->pGia, Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) ) - return -Vta_ObjId(p, pThis); - return Abc_Var2Lit( Vta_ObjId(p, pThis), Gia_ObjFaninC0(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Finds the set of clauses involved in the UNSAT core.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Vta_ManUnsatCore( int iLit, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls ) -{ - clock_t clk = clock(); - Vec_Int_t * vCore; - int RetValue, nConfPrev = pSat->stats.conflicts; - if ( piRetValue ) - *piRetValue = 1; - // consider special case when PO points to the flop - // this leads to immediate conflict in the first timeframe - if ( iLit < 0 ) - { - vCore = Vec_IntAlloc( 1 ); - Vec_IntPush( vCore, -iLit ); - return vCore; - } - // solve the problem - RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( pnConfls ) - *pnConfls = (int)pSat->stats.conflicts - nConfPrev; - if ( RetValue == l_Undef ) - { - if ( piRetValue ) - *piRetValue = -1; - return NULL; - } - if ( RetValue == l_True ) - { - if ( piRetValue ) - *piRetValue = 0; - return NULL; - } - if ( fVerbose ) - { -// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev ); -// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts ); -// Abc_PrintTime( 1, "Time", clock() - clk ); - } - assert( RetValue == l_False ); - // derive the UNSAT core - clk = clock(); - vCore = (Vec_Int_t *)Sat_ProofCore( pSat ); - if ( fVerbose ) - { -// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) ); -// Abc_PrintTime( 1, "Time", clock() - clk ); - } - return vCore; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames, int nConfls, int nCexes, clock_t Time, int fVerbose ) -{ - unsigned * pInfo; - int * pCountAll = NULL, * pCountUni = NULL; - int i, iFrame, iObj, Entry, fChanges = 0; - // print info about frames - if ( vCore ) - { - pCountAll = ABC_CALLOC( int, nFrames + 1 ); - pCountUni = ABC_CALLOC( int, nFrames + 1 ); - Vec_IntForEachEntry( vCore, Entry, i ) - { - iObj = (Entry & p->nObjMask); - iFrame = (Entry >> p->nObjBits); - assert( iFrame < nFrames ); - pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj ); - if ( !Abc_InfoHasBit(pInfo, iFrame) ) - { - Abc_InfoSetBit( pInfo, iFrame ); - pCountUni[iFrame+1]++; - pCountUni[0]++; - p->nSeenAll++; - } - pCountAll[iFrame+1]++; - pCountAll[0]++; - if ( !Vec_BitEntry(p->vSeenGla, iObj) ) - { - Vec_BitWriteEntry(p->vSeenGla, iObj, 1); - p->nSeenGla++; - fChanges = 1; - } - } - } - if ( !fVerbose ) - { - ABC_FREE( pCountAll ); - ABC_FREE( pCountUni ); - return fChanges; - } - - if ( Abc_FrameIsBatchMode() && !vCore ) - return fChanges; - -// Abc_Print( 1, "%5d%5d", pCountAll[0], pCountUni[0] ); - Abc_Print( 1, "%4d :", nFrames-1 ); - Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenGla / (Gia_ManRegNum(p->pGia) + Gia_ManAndNum(p->pGia) + 1)) ); - Abc_Print( 1, "%6d", p->nSeenGla ); - Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenAll / (p->nSeenGla * nFrames)) ); - Abc_Print( 1, "%8d", nConfls ); - if ( nCexes == 0 ) - Abc_Print( 1, "%5c", '-' ); - else - Abc_Print( 1, "%5d", nCexes ); -// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) ); - Abc_PrintInt( sat_solver2_nvars(p->pSat) ); - Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); - Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); - if ( vCore == NULL ) - { - Abc_Print( 1, " ..." ); -// for ( k = 0; k < 7; k++ ) -// Abc_Print( 1, " " ); - Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); - Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) ); - Abc_Print( 1, "\r" ); - } - else - { - Abc_PrintInt( pCountAll[0] ); -/* - if ( nFrames > 7 ) - { - for ( k = 0; k < 3; k++ ) - Abc_Print( 1, "%5d", pCountAll[k+1] ); - Abc_Print( 1, " ..." ); - for ( k = nFrames-3; k < nFrames; k++ ) - Abc_Print( 1, "%5d", pCountAll[k+1] ); - } - else - { - for ( k = 0; k < nFrames; k++ ) - Abc_Print( 1, "%5d", pCountAll[k+1] ); - for ( k = nFrames; k < 7; k++ ) - Abc_Print( 1, " " ); - } -*/ - Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); - Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) ); - Abc_Print( 1, "\n" ); - } - fflush( stdout ); - - if ( vCore ) - { - ABC_FREE( pCountAll ); - ABC_FREE( pCountUni ); - } - return fChanges; -} - -/**Function************************************************************* - - Synopsis [Adds clauses to the solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame ) -{ - Vta_Obj_t * pThis0, * pThis1; - Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj ); - Vta_Obj_t * pThis = Vga_ManFindOrAdd( p, iObj, iFrame ); - int iThis0, iMainVar = Vta_ObjId(p, pThis); - assert( pThis->iObj == iObj && pThis->iFrame == iFrame ); - if ( pThis->fAdded ) - return; - pThis->fAdded = 1; - Vec_IntPush( p->vAddedNew, iMainVar ); - if ( Gia_ObjIsAnd(pObj) ) - { - pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame ); - iThis0 = Vta_ObjId(p, pThis0); - pThis1 = Vga_ManFindOrAdd( p, Gia_ObjFaninId1p(p->pGia, pObj), iFrame ); - sat_solver2_add_and( p->pSat, iMainVar, iThis0, Vta_ObjId(p, pThis1), - Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0, iMainVar ); - } - else if ( Gia_ObjIsRo(p->pGia, pObj) ) - { - if ( iFrame == 0 ) - { - if ( p->pPars->fUseTermVars ) - { - pThis0 = Vga_ManFindOrAdd( p, iObj, -1 ); - sat_solver2_add_constraint( p->pSat, iMainVar, Vta_ObjId(p, pThis0), 1, 0, iMainVar ); - } - else - { - sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar ); - } - } - else - { - pObj = Gia_ObjRoToRi( p->pGia, pObj ); - pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame-1 ); - sat_solver2_add_buffer( p->pSat, iMainVar, Vta_ObjId(p, pThis0), Gia_ObjFaninC0(pObj), 0, iMainVar ); - } - } - else if ( Gia_ObjIsConst0(pObj) ) - { - sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar ); - } - else //if ( !Gia_ObjIsPi(p->pGia, pObj) ) - assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vga_ManLoadSlice( Vta_Man_t * p, Vec_Int_t * vOne, int Lift ) -{ - int i, Entry; - Vec_IntForEachEntry( vOne, Entry, i ) - Vga_ManAddClausesOne( p, Entry & p->nObjMask, (Entry >> p->nObjBits) + Lift ); - sat_solver2_simplify( p->pSat ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vga_ManPrintCore( Vta_Man_t * p, Vec_Int_t * vCore, int Lift ) -{ - int i, Entry, iObj, iFrame; - Vec_IntForEachEntry( vCore, Entry, i ) - { - iObj = (Entry & p->nObjMask); - iFrame = (Entry >> p->nObjBits); - Abc_Print( 1, "%d*%d ", iObj, iFrame+Lift ); - } - Abc_Print( 1, "\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Vga_ManRollBack( Vta_Man_t * p, int nObjOld ) -{ - Vta_Obj_t * pThis = p->pObjs + nObjOld; - Vta_Obj_t * pLimit = p->pObjs + p->nObjs; - int i, Entry; - for ( ; pThis < pLimit; pThis++ ) - Vga_ManDelete( p, pThis->iObj, pThis->iFrame ); - memset( p->pObjs + nObjOld, 0, sizeof(Vta_Obj_t) * (p->nObjs - nObjOld) ); - p->nObjs = nObjOld; - Vec_IntForEachEntry( p->vAddedNew, Entry, i ) - if ( Entry < p->nObjs ) - { - pThis = Vta_ManObj(p, Entry); - assert( pThis->fAdded == 1 ); - pThis->fAdded = 0; - } -} - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_VtaSendAbsracted( Vta_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); - Gia_Man_t * pAbs; - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Sending abstracted model...\n" ); - // create obj classes - Vec_IntFreeP( &p->pGia->vObjClasses ); - p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); - // create gate classes - Vec_IntFreeP( &p->pGia->vGateClasses ); - p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses ); - Vec_IntFreeP( &p->pGia->vObjClasses ); - // create abstrated model - pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses ); - Vec_IntFreeP( &p->pGia->vGateClasses ); - // send it out - Gia_ManToBridgeAbsNetlist( stdout, pAbs ); - Gia_ManStop( pAbs ); -} -void Gia_VtaSendCancel( Vta_Man_t * p, int fVerbose ) -{ - extern int Gia_ManToBridgeBadAbs( FILE * pFile ); - assert( Abc_FrameIsBridgeMode() ); -// if ( fVerbose ) -// Abc_Print( 1, "Cancelling previously sent model...\n" ); - Gia_ManToBridgeBadAbs( stdout ); -} - -/**Function************************************************************* - - Synopsis [Send abstracted model or send cancel.] - - Description [Counter-example will be sent automatically when &vta terminates.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_VtaDumpAbsracted( Vta_Man_t * p, int fVerbose ) -{ - char * pFileNameDef = "vabs.aig"; - char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef; - Gia_Man_t * pAbs; - if ( fVerbose ) - Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); - // create obj classes - Vec_IntFreeP( &p->pGia->vObjClasses ); - p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); - // create gate classes - Vec_IntFreeP( &p->pGia->vGateClasses ); - p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses ); - Vec_IntFreeP( &p->pGia->vObjClasses ); - // create abstrated model - pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses ); - Vec_IntFreeP( &p->pGia->vGateClasses ); - // send it out - Gia_WriteAiger( pAbs, pFileName, 0, 0 ); - Gia_ManStop( pAbs ); -} - - -/**Function************************************************************* - - Synopsis [Print memory report.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_VtaPrintMemory( Vta_Man_t * p ) -{ - double memTot = 0; - double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t); - double memSat = sat_solver2_memory( p->pSat, 1 ); - double memPro = sat_solver2_memory_proof( p->pSat ); - double memMap = p->nObjsAlloc * sizeof(Vta_Obj_t) + p->nBins * sizeof(int); - double memOth = sizeof(Vta_Man_t); - memOth += Vec_IntCap(p->vOrder) * sizeof(int); - memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vFrames ); - memOth += Vec_BitCap(p->vSeenGla) * sizeof(int); - memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCores ); - memOth += Vec_IntCap(p->vAddedNew) * sizeof(int); - memTot = memAig + memSat + memPro + memMap + memOth; - ABC_PRMP( "Memory: AIG ", memAig, memTot ); - ABC_PRMP( "Memory: SAT ", memSat, memTot ); - ABC_PRMP( "Memory: Proof ", memPro, memTot ); - ABC_PRMP( "Memory: Map ", memMap, memTot ); - ABC_PRMP( "Memory: Other ", memOth, memTot ); - ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); -} - - -/**Function************************************************************* - - Synopsis [Collect nodes/flops involved in different timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_VtaPerformInt( Gia_Man_t * pAig, Gia_ParVta_t * pPars ) -{ - Vta_Man_t * p; - Vec_Int_t * vCore; - Abc_Cex_t * pCex = NULL; - int i, f, nConfls, Status, nObjOld, RetValue = -1, nCountNoChange = 0, fOneIsSent = 0; - clock_t clk = clock(), clk2; - // preconditions - assert( Gia_ManPoNum(pAig) == 1 ); - assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax ); - if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) - { - if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) - { - printf( "Sequential miter is trivially UNSAT.\n" ); - return 1; - } - ABC_FREE( pAig->pCexSeq ); - pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); - printf( "Sequential miter is trivially SAT.\n" ); - return 0; - } - - // compute intial abstraction - if ( pAig->vObjClasses == NULL ) - { - pAig->vObjClasses = Vec_IntAlloc( 5 ); - Vec_IntPush( pAig->vObjClasses, 1 ); - Vec_IntPush( pAig->vObjClasses, 3 ); - Vec_IntPush( pAig->vObjClasses, 4 ); - Vec_IntPush( pAig->vObjClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)) ); - } - // start the manager - p = Vga_ManStart( pAig, pPars ); - // set runtime limit - if ( p->pPars->nTimeOut ) - sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() ); - // perform initial abstraction - if ( p->pPars->fVerbose ) - { - Abc_Print( 1, "Running variable-timeframe abstraction (VTA) with the following parameters:\n" ); - Abc_Print( 1, "FramePast = %d FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%\n", - pPars->nFramesPast, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin ); - Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n", - pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce ); -// Abc_Print( 1, "Frame %% Abs %% Confl Cex SatVar Core F0 F1 F2 ...\n" ); - Abc_Print( 1, " Frame %% Abs %% Confl Cex Vars Clas Lrns Core Time Mem\n" ); - } - assert( Vec_PtrSize(p->vFrames) > 0 ); - for ( f = i = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++ ) - { - int nConflsBeg = sat_solver2_nconflicts(p->pSat); - p->pPars->iFrame = f; - // realloc storage for abstraction marks - if ( f == p->nWords * 32 ) - p->nWords = Vec_IntDoubleWidth( p->vSeens, p->nWords ); - - // create bookmark to be used for rollback - nObjOld = p->nObjs; - sat_solver2_bookmark( p->pSat ); - Vec_IntClear( p->vAddedNew ); - - // load new timeframe - Vga_ManAddClausesOne( p, 0, f ); - if ( f < Vec_PtrSize(p->vFrames) ) - Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vFrames, f), 0 ); - else - { - for ( i = 1; i <= Abc_MinInt(p->pPars->nFramesPast, f); i++ ) - Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vCores, f-i), i ); - } - - // iterate as long as there are counter-examples - for ( i = 0; ; i++ ) - { - clk2 = clock(); - vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls ); - assert( (vCore != NULL) == (Status == 1) ); - if ( Status == -1 ) // resource limit is reached - { - Vga_ManRollBack( p, nObjOld ); - goto finish; - } - // check timeout - if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit ) - { - Vga_ManRollBack( p, nObjOld ); - goto finish; - } - if ( vCore != NULL ) - { - p->timeUnsat += clock() - clk2; - break; - } - p->timeSat += clock() - clk2; - assert( Status == 0 ); - p->nCexes++; - // perform the refinement - clk2 = clock(); - pCex = Vta_ManRefineAbstraction( p, f ); - p->timeCex += clock() - clk2; - if ( pCex != NULL ) - goto finish; - // print the result (do not count it towards change) - Vta_ManAbsPrintFrame( p, NULL, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose ); - } - assert( Status == 1 ); - // valid core is obtained - Vta_ManUnsatCoreRemap( p, vCore ); - Vec_IntSort( vCore, 1 ); - // update the SAT solver - sat_solver2_rollback( p->pSat ); - // update storage - Vga_ManRollBack( p, nObjOld ); - // load this timeframe - Vga_ManLoadSlice( p, vCore, 0 ); - Vec_IntFree( vCore ); - - // run SAT solver - clk2 = clock(); - vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls ); - p->timeUnsat += clock() - clk2; - assert( (vCore != NULL) == (Status == 1) ); - if ( Status == -1 ) // resource limit is reached - break; - if ( Status == 0 ) - { - Vta_ManSatVerify( p ); - // make sure, there was no initial abstraction (otherwise, it was invalid) - assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart ); - pCex = Vga_ManDeriveCex( p ); - break; - } - // add the core - Vta_ManUnsatCoreRemap( p, vCore ); - // add in direct topological order - Vec_IntSort( vCore, 1 ); - Vec_PtrPush( p->vCores, vCore ); - // print the result - if ( Vta_ManAbsPrintFrame( p, vCore, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose ) ) - { - // reset the counter of frames without change - nCountNoChange = 1; - p->pPars->nFramesNoChange = 0; - } - else if ( ++nCountNoChange == 2 ) // time to send - { - p->pPars->nFramesNoChange++; - if ( Abc_FrameIsBridgeMode() ) - { - // cancel old one if it was sent - if ( fOneIsSent ) - Gia_VtaSendCancel( p, pPars->fVerbose ); - // send new one - Gia_VtaSendAbsracted( p, pPars->fVerbose ); - fOneIsSent = 1; - } - } - // dump the model - if ( p->pPars->fDumpVabs && (f & 1) ) - { - char Command[1000]; - Abc_FrameSetStatus( -1 ); - Abc_FrameSetCex( NULL ); - Abc_FrameSetNFrames( f+1 ); - sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "vtabs.aig"), ".status") ); - Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); - Gia_VtaDumpAbsracted( p, pPars->fVerbose ); - } - // check if the number of objects is below limit - if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 ) - { - Status = -1; - break; - } - } -finish: - // analize the results - if ( pCex == NULL ) - { - if ( p->pPars->fVerbose && Status == -1 ) - printf( "\n" ); - if ( Vec_PtrSize(p->vCores) == 0 ) - Abc_Print( 1, "Abstraction is not produced because first frame is not solved. " ); - else - { - assert( Vec_PtrSize(p->vCores) > 0 ); -// if ( pAig->vObjClasses != NULL ) -// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); - Vec_IntFreeP( &pAig->vObjClasses ); - pAig->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); - if ( Status == -1 ) - { - if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) - Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange ); - else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) - Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange ); - else if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 ) - Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f ); - else - Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f ); - } - else - { - p->pPars->iFrame++; - Abc_Print( 1, "VTA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange ); - } - } - } - else - { - if ( p->pPars->fVerbose ) - printf( "\n" ); - ABC_FREE( p->pGia->pCexSeq ); - p->pGia->pCexSeq = pCex; - if ( !Gia_ManVerifyCex( p->pGia, pCex, 0 ) ) - Abc_Print( 1, " Gia_VtaPerform(): CEX verification has failed!\n" ); - Abc_Print( 1, "Counter-example detected in frame %d. ", f ); - p->pPars->iFrame = pCex->iFrame - 1; - Vec_IntFreeP( &pAig->vObjClasses ); - RetValue = 0; - } - Abc_PrintTime( 1, "Time", clock() - clk ); - - if ( p->pPars->fVerbose ) - { - p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex; - ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); - ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); - ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); - ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); - ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); - Gia_VtaPrintMemory( p ); - } - - Vga_ManStop( p ); - fflush( stdout ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Collect nodes/flops involved in different timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars ) -{ - int RetValue = -1; - if ( pAig->vObjClasses == NULL && pPars->fUseRollback ) - { - int nFramesMaxOld = pPars->nFramesMax; - pPars->nFramesMax = pPars->nFramesStart; - RetValue = Gia_VtaPerformInt( pAig, pPars ); - pPars->nFramesMax = nFramesMaxOld; - } - if ( RetValue == 0 ) - return RetValue; - return Gia_VtaPerformInt( pAig, pPars ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 9a8c1baa..b0bf9c1e 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1663,263 +1663,6 @@ Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes ) return pNew; } -/**Function************************************************************* - - Synopsis [Duplicates the AIG manager recursively.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDupAbsFlops_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); - Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin1(pObj) ); - pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Performs abstraction of the AIG to preserve the included flops.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses ) -{ - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj; - int i, nFlops = 0; - Gia_ManFillValue( p ); - // start the new manager - pNew = Gia_ManStart( 5000 ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - // create PIs - Gia_ManConst0(p)->Value = 0; - Gia_ManForEachPi( p, pObj, i ) - pObj->Value = Gia_ManAppendCi(pNew); - // create additional PIs - Gia_ManForEachRo( p, pObj, i ) - if ( !Vec_IntEntry(vFlopClasses, i) ) - pObj->Value = Gia_ManAppendCi(pNew); - // create ROs - Gia_ManForEachRo( p, pObj, i ) - if ( Vec_IntEntry(vFlopClasses, i) ) - pObj->Value = Gia_ManAppendCi(pNew); - // create POs - Gia_ManHashAlloc( pNew ); - Gia_ManForEachPo( p, pObj, i ) - { - Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - } - // create RIs - Gia_ManForEachRi( p, pObj, i ) - if ( Vec_IntEntry(vFlopClasses, i) ) - { - Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - nFlops++; - } - Gia_ManHashStop( pNew ); - Gia_ManSetRegNum( pNew, nFlops ); - // clean up - pNew = Gia_ManSeqCleanup( pTemp = pNew ); - Gia_ManStop( pTemp ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Returns the array of neighbors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Gia_GlaCollectAssigned( Gia_Man_t * p, Vec_Int_t * vGateClasses ) -{ - Vec_Int_t * vAssigned; - Gia_Obj_t * pObj; - int i, Entry; - vAssigned = Vec_IntAlloc( 1000 ); - Vec_IntForEachEntry( vGateClasses, Entry, i ) - { - if ( Entry == 0 ) - continue; - assert( Entry > 0 ); - pObj = Gia_ManObj( p, i ); - Vec_IntPush( vAssigned, Gia_ObjId(p, pObj) ); - if ( Gia_ObjIsAnd(pObj) ) - { - Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, pObj) ); - Vec_IntPush( vAssigned, Gia_ObjFaninId1p(p, pObj) ); - } - else if ( Gia_ObjIsRo(p, pObj) ) - Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, Gia_ObjRoToRi(p, pObj)) ); - else assert( Gia_ObjIsConst0(pObj) ); - } - Vec_IntUniqify( vAssigned ); - return vAssigned; -} - -/**Function************************************************************* - - Synopsis [Collects PIs and PPIs of the abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes ) -{ - Vec_Int_t * vAssigned; - Gia_Obj_t * pObj; - int i; - assert( Gia_ManPoNum(p) == 1 ); - assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) ); - // create included objects and their fanins - vAssigned = Gia_GlaCollectAssigned( p, vGateClasses ); - // create additional arrays - if ( pvPis ) *pvPis = Vec_IntAlloc( 100 ); - if ( pvPPis ) *pvPPis = Vec_IntAlloc( 100 ); - if ( pvFlops ) *pvFlops = Vec_IntAlloc( 100 ); - if ( pvNodes ) *pvNodes = Vec_IntAlloc( 1000 ); - Gia_ManForEachObjVec( vAssigned, p, pObj, i ) - { - if ( Gia_ObjIsPi(p, pObj) ) - { if ( pvPis ) Vec_IntPush( *pvPis, Gia_ObjId(p,pObj) ); } - else if ( !Vec_IntEntry(vGateClasses, Gia_ObjId(p,pObj)) ) - { if ( pvPPis ) Vec_IntPush( *pvPPis, Gia_ObjId(p,pObj) ); } - else if ( Gia_ObjIsRo(p, pObj) ) - { if ( pvFlops ) Vec_IntPush( *pvFlops, Gia_ObjId(p,pObj) ); } - else if ( Gia_ObjIsAnd(pObj) ) - { if ( pvNodes ) Vec_IntPush( *pvNodes, Gia_ObjId(p,pObj) ); } - else assert( Gia_ObjIsConst0(pObj) ); - } - Vec_IntFree( vAssigned ); -} - -/**Function************************************************************* - - Synopsis [Duplicates the AIG manager recursively.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDupAbsGates_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin0(pObj) ); - Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin1(pObj) ); - pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Performs abstraction of the AIG to preserve the included gates.] - - Description [The array contains 1 for those objects (const, RO, AND) - that are included in the abstraction; 0, otherwise.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses ) -{ - Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes; - Gia_Man_t * pNew, * pTemp; - Gia_Obj_t * pObj, * pCopy; - int i;//, nFlops = 0; - assert( Gia_ManPoNum(p) == 1 ); - assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) ); - - // create additional arrays - Gia_ManGlaCollect( p, vGateClasses, &vPis, &vPPis, &vFlops, &vNodes ); - - // start the new manager - pNew = Gia_ManStart( 5000 ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - // create constant - Gia_ManFillValue( p ); - Gia_ManConst0(p)->Value = 0; - // create PIs - Gia_ManForEachObjVec( vPis, p, pObj, i ) - pObj->Value = Gia_ManAppendCi(pNew); - // create additional PIs - Gia_ManForEachObjVec( vPPis, p, pObj, i ) - pObj->Value = Gia_ManAppendCi(pNew); - // create ROs - Gia_ManForEachObjVec( vFlops, p, pObj, i ) - pObj->Value = Gia_ManAppendCi(pNew); - // create internal nodes - Gia_ManForEachObjVec( vNodes, p, pObj, i ) - pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -// Gia_ManDupAbsGates_rec( pNew, pObj ); - // create PO - Gia_ManForEachPo( p, pObj, i ) - pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - // create RIs - Gia_ManForEachObjVec( vFlops, p, pObj, i ) - Gia_ObjRoToRi(p, pObj)->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ObjRoToRi(p, pObj)) ); - Gia_ManSetRegNum( pNew, Vec_IntSize(vFlops) ); - // clean up - pNew = Gia_ManSeqCleanup( pTemp = pNew ); - // transfer copy values: (p -> pTemp -> pNew) => (p -> pNew) - if ( Gia_ManObjNum(pTemp) != Gia_ManObjNum(pNew) ) - { -// printf( "Gia_ManDupAbsGates() Internal error: object mismatch.\n" ); - Gia_ManForEachObj( p, pObj, i ) - { - if ( !~pObj->Value ) - continue; - assert( !Abc_LitIsCompl(pObj->Value) ); - pCopy = Gia_ObjCopy( pTemp, pObj ); - if ( !~pCopy->Value ) - { - Vec_IntWriteEntry( vGateClasses, i, 0 ); - pObj->Value = ~0; - continue; - } - assert( !Abc_LitIsCompl(pCopy->Value) ); - pObj->Value = pCopy->Value; - } - } - Gia_ManStop( pTemp ); - - Vec_IntFree( vPis ); - Vec_IntFree( vPPis ); - Vec_IntFree( vFlops ); - Vec_IntFree( vNodes ); - return pNew; -} - /**Function************************************************************* Synopsis [Copy an AIG structure related to the selected POs.] diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 2b16f326..6b57e292 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -20,6 +20,7 @@ #include "gia.h" #include "misc/tim/tim.h" +#include "proof/abs/abs.h" ABC_NAMESPACE_IMPL_START @@ -165,155 +166,6 @@ void Gia_ManPrintClasses_old( Gia_Man_t * p ) } } -/**Function************************************************************* - - Synopsis [Prints stats for the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManPrintFlopClasses( Gia_Man_t * p ) -{ - int Counter0, Counter1; - if ( p->vFlopClasses == NULL ) - return; - if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) ) - { - printf( "Gia_ManPrintFlopClasses(): The number of flop map entries differs from the number of flops.\n" ); - return; - } - Counter0 = Vec_IntCountEntry( p->vFlopClasses, 0 ); - Counter1 = Vec_IntCountEntry( p->vFlopClasses, 1 ); - printf( "Flop-level abstraction: Excluded FFs = %d Included FFs = %d (%.2f %%) ", - Counter0, Counter1, 100.0*Counter1/(Counter0 + Counter1 + 1) ); - if ( Counter0 + Counter1 < Gia_ManRegNum(p) ) - printf( "and there are other FF classes..." ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints stats for the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManPrintGateClasses( Gia_Man_t * p ) -{ - Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes; - int nTotal; - if ( p->vGateClasses == NULL ) - return; - if ( Vec_IntSize(p->vGateClasses) != Gia_ManObjNum(p) ) - { - printf( "Gia_ManPrintGateClasses(): The number of flop map entries differs from the number of flops.\n" ); - return; - } - // create additional arrays - Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, &vFlops, &vNodes ); - nTotal = 1 + Vec_IntSize(vFlops) + Vec_IntSize(vNodes); - printf( "Gate-level abstraction: PI = %d PPI = %d FF = %d (%.2f %%) AND = %d (%.2f %%) Obj = %d (%.2f %%)\n", - Vec_IntSize(vPis), Vec_IntSize(vPPis), - Vec_IntSize(vFlops), 100.0*Vec_IntSize(vFlops)/(Gia_ManRegNum(p)+1), - Vec_IntSize(vNodes), 100.0*Vec_IntSize(vNodes)/(Gia_ManAndNum(p)+1), - nTotal, 100.0*nTotal /(Gia_ManRegNum(p)+Gia_ManAndNum(p)+1) ); - Vec_IntFree( vPis ); - Vec_IntFree( vPPis ); - Vec_IntFree( vFlops ); - Vec_IntFree( vNodes ); -} - -/**Function************************************************************* - - Synopsis [Prints stats for the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManPrintObjClasses( Gia_Man_t * p ) -{ - Vec_Int_t * vSeens; // objects seen so far - Vec_Int_t * vAbs = p->vObjClasses; - int i, k, Entry, iStart, iStop = -1, nFrames; - int nObjBits, nObjMask, iObj, iFrame, nWords; - unsigned * pInfo; - int * pCountAll, * pCountUni; - if ( vAbs == NULL ) - return; - nFrames = Vec_IntEntry( vAbs, 0 ); - assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) ); - pCountAll = ABC_ALLOC( int, nFrames + 1 ); - pCountUni = ABC_ALLOC( int, nFrames + 1 ); - // start storage for seen objects - nWords = Abc_BitWordNum( nFrames ); - vSeens = Vec_IntStart( Gia_ManObjNum(p) * nWords ); - // get the bitmasks - nObjBits = Abc_Base2Log( Gia_ManObjNum(p) ); - nObjMask = (1 << nObjBits) - 1; - assert( Gia_ManObjNum(p) <= nObjMask ); - // print info about frames - printf( "Frame Core F0 F1 F2 F3 ...\n" ); - for ( i = 0; i < nFrames; i++ ) - { - iStart = Vec_IntEntry( vAbs, i+1 ); - iStop = Vec_IntEntry( vAbs, i+2 ); - memset( pCountAll, 0, sizeof(int) * (nFrames + 1) ); - memset( pCountUni, 0, sizeof(int) * (nFrames + 1) ); - Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop ) - { - iObj = (Entry & nObjMask); - iFrame = (Entry >> nObjBits); - pInfo = (unsigned *)Vec_IntEntryP( vSeens, nWords * iObj ); - if ( Abc_InfoHasBit(pInfo, iFrame) == 0 ) - { - Abc_InfoSetBit( pInfo, iFrame ); - pCountUni[iFrame+1]++; - pCountUni[0]++; - } - pCountAll[iFrame+1]++; - pCountAll[0]++; - } - assert( pCountAll[0] == (iStop - iStart) ); -// printf( "%5d%5d ", pCountAll[0], pCountUni[0] ); - printf( "%3d :", i ); - printf( "%7d", pCountAll[0] ); - if ( i >= 10 ) - { - for ( k = 0; k < 4; k++ ) - printf( "%5d", pCountAll[k+1] ); - printf( " ..." ); - for ( k = i-4; k <= i; k++ ) - printf( "%5d", pCountAll[k+1] ); - } - else - { - for ( k = 0; k <= i; k++ ) - if ( k <= i ) - printf( "%5d", pCountAll[k+1] ); - } -// for ( k = 0; k < nFrames; k++ ) -// if ( k <= i ) -// printf( "%5d", pCountAll[k+1] ); - printf( "\n" ); - } - assert( iStop == Vec_IntSize(vAbs) ); - Vec_IntFree( vSeens ); - ABC_FREE( pCountAll ); - ABC_FREE( pCountUni ); -} - /**Function************************************************************* Synopsis [Prints stats for the AIG.] diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index ea3ca24d..89af261a 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -1,13 +1,4 @@ SRC += src/aig/gia/gia.c \ - src/aig/gia/giaAbs.c \ - src/aig/gia/giaAbsGla.c \ - src/aig/gia/giaAbsGla2.c \ - src/aig/gia/giaAbsIter.c \ - src/aig/gia/giaAbsOut.c \ - src/aig/gia/giaAbsPth.c \ - src/aig/gia/giaAbsRef.c \ - src/aig/gia/giaAbsRef2.c \ - src/aig/gia/giaAbsVta.c \ src/aig/gia/giaAig.c \ src/aig/gia/giaAiger.c \ src/aig/gia/giaBidec.c \ diff --git a/src/aig/saig/module.make b/src/aig/saig/module.make index 42e3c090..edf5798e 100644 --- a/src/aig/saig/module.make +++ b/src/aig/saig/module.make @@ -1,9 +1,4 @@ -SRC += src/aig/saig/saigAbs.c \ - src/aig/saig/saigAbsCba.c \ - src/aig/saig/saigAbsPba.c \ - src/aig/saig/saigAbsStart.c \ - src/aig/saig/saigAbsVfa.c \ - src/aig/saig/saigBmc.c \ +SRC += src/aig/saig/saigBmc.c \ src/aig/saig/saigBmc2.c \ src/aig/saig/saigBmc3.c \ src/aig/saig/saigCexMin.c \ @@ -12,9 +7,6 @@ SRC += src/aig/saig/saigAbs.c \ src/aig/saig/saigConstr2.c \ src/aig/saig/saigDual.c \ src/aig/saig/saigDup.c \ - src/aig/saig/saigGlaCba.c \ - src/aig/saig/saigGlaPba.c \ - src/aig/saig/saigGlaPba2.c \ src/aig/saig/saigHaig.c \ src/aig/saig/saigInd.c \ src/aig/saig/saigIoa.c \ @@ -24,13 +16,10 @@ SRC += src/aig/saig/saigAbs.c \ src/aig/saig/saigMiter.c \ src/aig/saig/saigOutDec.c \ src/aig/saig/saigPhase.c \ - src/aig/saig/saigRefSat.c \ src/aig/saig/saigRetFwd.c \ src/aig/saig/saigRetMin.c \ src/aig/saig/saigRetStep.c \ src/aig/saig/saigScl.c \ - src/aig/saig/saigSimExt.c \ - src/aig/saig/saigSimExt2.c \ src/aig/saig/saigSimFast.c \ src/aig/saig/saigSimMv.c \ src/aig/saig/saigSimSeq.c \ diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index e7cdea90..8823dcac 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////// #include "aig/aig/aig.h" -#include "aig/gia/giaAbs.h" ABC_NAMESPACE_HEADER_START @@ -35,10 +34,6 @@ ABC_NAMESPACE_HEADER_START /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#define SAIG_ZER 1 -#define SAIG_ONE 2 -#define SAIG_UND 3 - //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// @@ -131,20 +126,6 @@ static inline int Saig_ObjRegId( Aig_Man_t * p, Aig_Obj_t * pObj ) { /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== sswAbs.c ==========================================================*/ -extern Vec_Int_t * Saig_ManClasses2Flops( Vec_Int_t * vFlopClasses ); -extern Vec_Int_t * Saig_ManFlops2Classes( int nRegs, Vec_Int_t * vFlops ); -extern Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs ); -/*=== sswAbsCba.c ==========================================================*/ -extern Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect ); -extern Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ); -extern Vec_Int_t * Saig_ManCbaFilterInputs( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ); -extern Vec_Int_t * Saig_ManCbaPerform( Aig_Man_t * pAig, int nInputs, Saig_ParBmc_t * pPars ); -/*=== sswAbsPba.c ==========================================================*/ -extern Vec_Int_t * Saig_ManPbaDerive( Aig_Man_t * pAig, int nInputs, int nStart, int nFrames, int nConfLimit, int nTimeLimit, int fVerbose, int * piFrame ); -/*=== sswAbsStart.c ==========================================================*/ -extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vFlopClasses, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ); -extern Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); /*=== saigBmc.c ==========================================================*/ extern int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ); extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames, int fSilent ); @@ -203,8 +184,6 @@ extern int Saig_ManDemiterNew( Aig_Man_t * pMan ); extern Aig_Man_t * Saig_ManDecPropertyOutput( Aig_Man_t * pAig, int nLits, int fVerbose ); /*=== saigPhase.c ==========================================================*/ extern Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrames, int nPref, int fIgnore, int fPrint, int fVerbose ); -/*=== saigRefSat.c ==========================================================*/ -extern Vec_Int_t * Saig_ManExtendCounterExampleTest3( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ); /*=== saigRetFwd.c ==========================================================*/ extern void Saig_ManMarkAutonomous( Aig_Man_t * p ); extern Aig_Man_t * Saig_ManRetimeForward( Aig_Man_t * p, int nMaxIters, int fVerbose ); @@ -215,11 +194,6 @@ extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, in extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs ); /*=== saigScl.c ==========================================================*/ extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); -/*=== saigSimExt.c ==========================================================*/ -extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ); -extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fTryFour, int fVerbose ); -/*=== saigSimExt.c ==========================================================*/ -extern Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); /*=== saigSimMv.c ==========================================================*/ extern Vec_Ptr_t * Saig_MvManSimulate( Aig_Man_t * pAig, int nFramesSymb, int nFramesSatur, int fVerbose, int fVeryVerbose ); /*=== saigStrSim.c ==========================================================*/ diff --git a/src/aig/saig/saigAbs.c b/src/aig/saig/saigAbs.c deleted file mode 100644 index f30963a8..00000000 --- a/src/aig/saig/saigAbs.c +++ /dev/null @@ -1,133 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigAbs.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Intergrated abstraction procedure.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Transform flop map into flop list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManClasses2Flops( Vec_Int_t * vFlopClasses ) -{ - Vec_Int_t * vFlops; - int i, Entry; - vFlops = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vFlopClasses, Entry, i ) - if ( Entry ) - Vec_IntPush( vFlops, i ); - return vFlops; -} - -/**Function************************************************************* - - Synopsis [Transform flop list into flop map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManFlops2Classes( int nRegs, Vec_Int_t * vFlops ) -{ - Vec_Int_t * vFlopClasses; - int i, Entry; - vFlopClasses = Vec_IntStart( nRegs ); - Vec_IntForEachEntry( vFlops, Entry, i ) - Vec_IntWriteEntry( vFlopClasses, Entry, 1 ); - return vFlopClasses; -} - -/**Function************************************************************* - - Synopsis [Derive a new counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs ) -{ - Abc_Cex_t * pCex; - Aig_Obj_t * pObj; - int i, f; - if ( !Saig_ManVerifyCex( pAbs, pCexAbs ) ) - printf( "Saig_ManCexRemap(): The initial counter-example is invalid.\n" ); -// else -// printf( "Saig_ManCexRemap(): The initial counter-example is correct.\n" ); - // start the counter-example - pCex = Abc_CexAlloc( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); - pCex->iFrame = pCexAbs->iFrame; - pCex->iPo = pCexAbs->iPo; - // copy the bit data - for ( f = 0; f <= pCexAbs->iFrame; f++ ) - { - Saig_ManForEachPi( pAbs, pObj, i ) - { - if ( i == Saig_ManPiNum(p) ) - break; - if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) ) - Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + i ); - } - } - // verify the counter example - if ( !Saig_ManVerifyCex( p, pCex ) ) - { - printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" ); - Abc_CexFree( pCex ); - pCex = NULL; - } - else - { - Abc_Print( 1, "Counter-example verification is successful.\n" ); - Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame ); - } - return pCex; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigAbsCba.c b/src/aig/saig/saigAbsCba.c deleted file mode 100644 index 8f2cafaa..00000000 --- a/src/aig/saig/saigAbsCba.c +++ /dev/null @@ -1,874 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigAbsCba.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [CEX-based abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigAbsCba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "aig/gia/giaAig.h" -#include "aig/ioa/ioa.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// local manager -typedef struct Saig_ManCba_t_ Saig_ManCba_t; -struct Saig_ManCba_t_ -{ - // user data - Aig_Man_t * pAig; // user's AIG - Abc_Cex_t * pCex; // user's CEX - int nInputs; // the number of first inputs to skip - int fVerbose; // verbose flag - // unrolling - Aig_Man_t * pFrames; // unrolled timeframes - Vec_Int_t * vMapPiF2A; // mapping of frame PIs into real PIs - // additional information - Vec_Vec_t * vReg2Frame; // register to frame mapping - Vec_Vec_t * vReg2Value; // register to value mapping -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - - -/**Function************************************************************* - - Synopsis [Selects the best flops from the given array.] - - Description [Selects the best 'nFfsToSelect' flops among the array - 'vAbsFfsToAdd' of flops that should be added to the abstraction. - To this end, this procedure simulates the original AIG (pAig) using - the given CEX (pAbsCex), which was detected for the abstraction.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect ) -{ - Aig_Obj_t * pObj, * pObjRi, * pObjRo; - Vec_Int_t * vMapEntries, * vFlopCosts, * vFlopAddCosts, * vFfsToAddBest; - int i, k, f, Entry, iBit, * pPerm; - assert( Aig_ManRegNum(pAig) == Vec_IntSize(vFlopClasses) ); - assert( Vec_IntSize(vAbsFfsToAdd) > nFfsToSelect ); - // map previously abstracted flops into their original numbers - vMapEntries = Vec_IntAlloc( Vec_IntSize(vFlopClasses) ); - Vec_IntForEachEntry( vFlopClasses, Entry, i ) - if ( Entry == 0 ) - Vec_IntPush( vMapEntries, i ); - // simulate one frame at a time - assert( Saig_ManPiNum(pAig) + Vec_IntSize(vMapEntries) == pAbsCex->nPis ); - vFlopCosts = Vec_IntStart( Vec_IntSize(vMapEntries) ); - // initialize the flops - Aig_ManCleanMarkB(pAig); - Aig_ManConst1(pAig)->fMarkB = 1; - Saig_ManForEachLo( pAig, pObj, i ) - pObj->fMarkB = 0; - for ( f = 0; f < pAbsCex->iFrame; f++ ) - { - // override the flop values according to the cex - iBit = pAbsCex->nRegs + f * pAbsCex->nPis + Saig_ManPiNum(pAig); - Vec_IntForEachEntry( vMapEntries, Entry, k ) - Saig_ManLo(pAig, Entry)->fMarkB = Abc_InfoHasBit(pAbsCex->pData, iBit + k); - // simulate - Aig_ManForEachNode( pAig, pObj, k ) - pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & - (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj)); - Aig_ManForEachCo( pAig, pObj, k ) - pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); - // transfer - Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k ) - pObjRo->fMarkB = pObjRi->fMarkB; - // compare - iBit = pAbsCex->nRegs + (f + 1) * pAbsCex->nPis + Saig_ManPiNum(pAig); - Vec_IntForEachEntry( vMapEntries, Entry, k ) - if ( Saig_ManLi(pAig, Entry)->fMarkB != (unsigned)Abc_InfoHasBit(pAbsCex->pData, iBit + k) ) - Vec_IntAddToEntry( vFlopCosts, k, 1 ); - } -// Vec_IntForEachEntry( vFlopCosts, Entry, i ) -// printf( "%d ", Entry ); -// printf( "\n" ); - // remap the cost - vFlopAddCosts = Vec_IntAlloc( Vec_IntSize(vAbsFfsToAdd) ); - Vec_IntForEachEntry( vAbsFfsToAdd, Entry, i ) - Vec_IntPush( vFlopAddCosts, -Vec_IntEntry(vFlopCosts, Entry) ); - // sort the flops - pPerm = Abc_MergeSortCost( Vec_IntArray(vFlopAddCosts), Vec_IntSize(vFlopAddCosts) ); - // shrink the array - vFfsToAddBest = Vec_IntAlloc( nFfsToSelect ); - for ( i = 0; i < nFfsToSelect; i++ ) - { -// printf( "%d ", Vec_IntEntry(vFlopAddCosts, pPerm[i]) ); - Vec_IntPush( vFfsToAddBest, Vec_IntEntry(vAbsFfsToAdd, pPerm[i]) ); - } -// printf( "\n" ); - // cleanup - ABC_FREE( pPerm ); - Vec_IntFree( vMapEntries ); - Vec_IntFree( vFlopCosts ); - Vec_IntFree( vFlopAddCosts ); - Aig_ManCleanMarkB(pAig); - // return the computed flops - return vFfsToAddBest; -} - - -/**Function************************************************************* - - Synopsis [Duplicate with literals.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_ManDupWithCubes( Aig_Man_t * pAig, Vec_Vec_t * vReg2Value ) -{ - Vec_Int_t * vLevel; - Aig_Man_t * pAigNew; - Aig_Obj_t * pObj, * pMiter; - int i, k, Lit; - assert( pAig->nConstrs == 0 ); - // start the new manager - pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) + Vec_VecSizeSize(vReg2Value) ); - pAigNew->pName = Abc_UtilStrsav( pAig->pName ); - // map the constant node - Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); - // create variables for PIs - Aig_ManForEachCi( pAig, pObj, i ) - pObj->pData = Aig_ObjCreateCi( pAigNew ); - // add internal nodes of this frame - Aig_ManForEachNode( pAig, pObj, i ) - pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - // create POs for cubes - Vec_VecForEachLevelInt( vReg2Value, vLevel, i ) - { - pMiter = Aig_ManConst1( pAigNew ); - Vec_IntForEachEntry( vLevel, Lit, k ) - { - pObj = Saig_ManLi( pAig, Abc_Lit2Var(Lit) ); - pMiter = Aig_And( pAigNew, pMiter, Aig_NotCond(Aig_ObjChild0Copy(pObj), Abc_LitIsCompl(Lit)) ); - } - Aig_ObjCreateCo( pAigNew, pMiter ); - } - // transfer to register outputs - Saig_ManForEachLi( pAig, pObj, i ) - Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) ); - // finalize - Aig_ManCleanup( pAigNew ); - Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) ); - return pAigNew; -} - -/**Function************************************************************* - - Synopsis [Maps array of frame PI IDs into array of additional PI IDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCbaReason2Inputs( Saig_ManCba_t * p, Vec_Int_t * vReasons ) -{ - Vec_Int_t * vOriginal, * vVisited; - int i, Entry; - vOriginal = Vec_IntAlloc( Saig_ManPiNum(p->pAig) ); - vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) ); - Vec_IntForEachEntry( vReasons, Entry, i ) - { - int iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); - assert( iInput >= p->nInputs && iInput < Aig_ManCiNum(p->pAig) ); - if ( Vec_IntEntry(vVisited, iInput) == 0 ) - Vec_IntPush( vOriginal, iInput - p->nInputs ); - Vec_IntAddToEntry( vVisited, iInput, 1 ); - } - Vec_IntFree( vVisited ); - return vOriginal; -} - -/**Function************************************************************* - - Synopsis [Creates the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManCbaReason2Cex( Saig_ManCba_t * p, Vec_Int_t * vReasons ) -{ - Abc_Cex_t * pCare; - int i, Entry, iInput, iFrame; - pCare = Abc_CexDup( p->pCex, p->pCex->nRegs ); - memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); - Vec_IntForEachEntry( vReasons, Entry, i ) - { - assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pFrames) ); - iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); - iFrame = Vec_IntEntry( p->vMapPiF2A, 2*Entry+1 ); - Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput ); - } -/* - for ( iFrame = 0; iFrame <= pCare->iFrame; iFrame++ ) - { - int Count = 0; - for ( i = 0; i < pCare->nPis; i++ ) - Count += Abc_InfoHasBit(pCare->pData, pCare->nRegs + pCare->nPis * iFrame + i); - printf( "%d ", Count ); - } -printf( "\n" ); -*/ - return pCare; -} - -/**Function************************************************************* - - Synopsis [Returns reasons for the property to fail.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManCbaFindReason_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vPrios, Vec_Int_t * vReasons ) -{ - if ( Aig_ObjIsTravIdCurrent(p, pObj) ) - return; - Aig_ObjSetTravIdCurrent(p, pObj); - if ( Aig_ObjIsConst1(pObj) ) - return; - if ( Aig_ObjIsCi(pObj) ) - { - Vec_IntPush( vReasons, Aig_ObjCioId(pObj) ); - return; - } - assert( Aig_ObjIsNode(pObj) ); - if ( pObj->fPhase ) - { - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); - } - else - { - int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; - int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; - assert( !fPhase0 || !fPhase1 ); - if ( !fPhase0 && fPhase1 ) - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); - else if ( fPhase0 && !fPhase1 ) - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); - else - { - int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); - int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); - if ( iPrio0 <= iPrio1 ) - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); - else - Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); - } - } -} - -/**Function************************************************************* - - Synopsis [Returns reasons for the property to fail.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCbaFindReason( Saig_ManCba_t * p ) -{ - Aig_Obj_t * pObj; - Vec_Int_t * vPrios, * vReasons; - int i; - - // set PI values according to CEX - vPrios = Vec_IntStartFull( Aig_ManObjNumMax(p->pFrames) ); - Aig_ManConst1(p->pFrames)->fPhase = 1; - Aig_ManForEachCi( p->pFrames, pObj, i ) - { - int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i ); - int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 ); - pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); - Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), i ); - } - - // traverse and set the priority - Aig_ManForEachNode( p->pFrames, pObj, i ) - { - int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; - int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; - int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); - int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); - pObj->fPhase = fPhase0 && fPhase1; - if ( fPhase0 && fPhase1 ) // both are one - Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MaxInt(iPrio0, iPrio1) ); - else if ( !fPhase0 && fPhase1 ) - Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio0 ); - else if ( fPhase0 && !fPhase1 ) - Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio1 ); - else // both are zero - Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MinInt(iPrio0, iPrio1) ); - } - // check the property output - pObj = Aig_ManCo( p->pFrames, 0 ); - pObj->fPhase = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; - assert( !pObj->fPhase ); - - // select the reason - vReasons = Vec_IntAlloc( 100 ); - Aig_ManIncrementTravId( p->pFrames ); - Saig_ManCbaFindReason_rec( p->pFrames, Aig_ObjFanin0(pObj), vPrios, vReasons ); - Vec_IntFree( vPrios ); -// assert( !Aig_ObjIsTravIdCurrent(p->pFrames, Aig_ManConst1(p->pFrames)) ); - return vReasons; -} - - -/**Function************************************************************* - - Synopsis [Collect nodes in the unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManCbaUnrollCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots ) -{ - if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) - return; - Aig_ObjSetTravIdCurrent(pAig, pObj); - if ( Aig_ObjIsCo(pObj) ) - Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); - else if ( Aig_ObjIsNode(pObj) ) - { - Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); - Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots ); - } - if ( vRoots && Saig_ObjIsLo( pAig, pObj ) ) - Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) ); - Vec_IntPush( vObjs, Aig_ObjId(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_ManCbaUnrollWithCex( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, Vec_Int_t ** pvMapPiF2A, Vec_Vec_t ** pvReg2Frame ) -{ - Aig_Man_t * pFrames; // unrolled timeframes - Vec_Vec_t * vFrameCos; // the list of COs per frame - Vec_Vec_t * vFrameObjs; // the list of objects per frame - Vec_Int_t * vRoots, * vObjs; - Aig_Obj_t * pObj; - int i, f; - // sanity checks - assert( Saig_ManPiNum(pAig) == pCex->nPis ); -// assert( Saig_ManRegNum(pAig) == pCex->nRegs ); - assert( pCex->iPo >= 0 && pCex->iPo < Saig_ManPoNum(pAig) ); - - // map PIs of the unrolled frames into PIs of the original design - *pvMapPiF2A = Vec_IntAlloc( 1000 ); - - // collect COs and Objs visited in each frame - vFrameCos = Vec_VecStart( pCex->iFrame+1 ); - vFrameObjs = Vec_VecStart( pCex->iFrame+1 ); - // initialized the topmost frame - pObj = Aig_ManCo( pAig, pCex->iPo ); - Vec_VecPushInt( vFrameCos, pCex->iFrame, Aig_ObjId(pObj) ); - for ( f = pCex->iFrame; f >= 0; f-- ) - { - // collect nodes starting from the roots - Aig_ManIncrementTravId( pAig ); - vRoots = Vec_VecEntryInt( vFrameCos, f ); - Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) - Saig_ManCbaUnrollCollect_rec( pAig, pObj, - Vec_VecEntryInt(vFrameObjs, f), - (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) ); - } - - // derive unrolled timeframes - pFrames = Aig_ManStart( 10000 ); - pFrames->pName = Abc_UtilStrsav( pAig->pName ); - pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec ); - // initialize the flops - if ( Saig_ManRegNum(pAig) == pCex->nRegs ) - { - Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, i) ); - } - else // this is the case when synthesis was applied, assume all-0 init state - { - Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), 1 ); - } - // iterate through the frames - for ( f = 0; f <= pCex->iFrame; f++ ) - { - // construct - vObjs = Vec_VecEntryInt( vFrameObjs, f ); - Aig_ManForEachObjVec( vObjs, pAig, pObj, i ) - { - if ( Aig_ObjIsNode(pObj) ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - else if ( Aig_ObjIsCo(pObj) ) - pObj->pData = Aig_ObjChild0Copy(pObj); - else if ( Aig_ObjIsConst1(pObj) ) - pObj->pData = Aig_ManConst1(pFrames); - else if ( Saig_ObjIsPi(pAig, pObj) ) - { - if ( Aig_ObjCioId(pObj) < nInputs ) - { - int iBit = pCex->nRegs + f * pCex->nPis + Aig_ObjCioId(pObj); - pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, iBit) ); - } - else - { - pObj->pData = Aig_ObjCreateCi( pFrames ); - Vec_IntPush( *pvMapPiF2A, Aig_ObjCioId(pObj) ); - Vec_IntPush( *pvMapPiF2A, f ); - } - } - } - if ( f == pCex->iFrame ) - break; - // transfer - vRoots = Vec_VecEntryInt( vFrameCos, f ); - Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) - { - Saig_ObjLiToLo( pAig, pObj )->pData = pObj->pData; - if ( *pvReg2Frame ) - { - Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjId(pObj) ); // record LO - Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjToLit((Aig_Obj_t *)pObj->pData) ); // record its literal - } - } - } - // create output - pObj = Aig_ManCo( pAig, pCex->iPo ); - Aig_ObjCreateCo( pFrames, Aig_Not((Aig_Obj_t *)pObj->pData) ); - Aig_ManSetRegNum( pFrames, 0 ); - // cleanup - Vec_VecFree( vFrameCos ); - Vec_VecFree( vFrameObjs ); - // finallize - Aig_ManCleanup( pFrames ); - // return - return pFrames; -} - -/**Function************************************************************* - - Synopsis [Creates refinement manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Saig_ManCba_t * Saig_ManCbaStart( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ) -{ - Saig_ManCba_t * p; - p = ABC_CALLOC( Saig_ManCba_t, 1 ); - p->pAig = pAig; - p->pCex = pCex; - p->nInputs = nInputs; - p->fVerbose = fVerbose; - return p; -} - -/**Function************************************************************* - - Synopsis [Destroys refinement manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManCbaStop( Saig_ManCba_t * p ) -{ - Vec_VecFreeP( &p->vReg2Frame ); - Vec_VecFreeP( &p->vReg2Value ); - Aig_ManStopP( &p->pFrames ); - Vec_IntFreeP( &p->vMapPiF2A ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Destroys refinement manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManCbaShrink( Saig_ManCba_t * p ) -{ - Aig_Man_t * pManNew; - Aig_Obj_t * pObjLi, * pObjFrame; - Vec_Int_t * vLevel, * vLevel2; - int f, k, ObjId, Lit; - // assuming that important objects are labeled in Saig_ManCbaFindReason() - Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, f ) - { - Vec_IntForEachEntryDouble( vLevel, ObjId, Lit, k ) - { - pObjFrame = Aig_ManObj( p->pFrames, Abc_Lit2Var(Lit) ); - if ( pObjFrame == NULL || (!Aig_ObjIsConst1(pObjFrame) && !Aig_ObjIsTravIdCurrent(p->pFrames, pObjFrame)) ) - continue; - pObjLi = Aig_ManObj( p->pAig, ObjId ); - assert( Saig_ObjIsLi(p->pAig, pObjLi) ); - Vec_VecPushInt( p->vReg2Value, f, Abc_Var2Lit( Aig_ObjCioId(pObjLi) - Saig_ManPoNum(p->pAig), Abc_LitIsCompl(Lit) ^ !pObjFrame->fPhase ) ); - } - } - // print statistics - Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, k ) - { - vLevel2 = Vec_VecEntryInt( p->vReg2Value, k ); - printf( "Level = %4d StateBits = %4d (%6.2f %%) CareBits = %4d (%6.2f %%)\n", k, - Vec_IntSize(vLevel)/2, 100.0 * (Vec_IntSize(vLevel)/2) / Aig_ManRegNum(p->pAig), - Vec_IntSize(vLevel2), 100.0 * Vec_IntSize(vLevel2) / Aig_ManRegNum(p->pAig) ); - } - // try reducing the frames - pManNew = Saig_ManDupWithCubes( p->pAig, p->vReg2Value ); - Ioa_WriteAiger( pManNew, "aigcube.aig", 0, 0 ); - Aig_ManStop( pManNew ); -} - -static inline void Saig_ObjCexMinSet0( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 0; } -static inline void Saig_ObjCexMinSet1( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; pObj->fMarkB = 1; } -static inline void Saig_ObjCexMinSetX( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 1; } - -static inline int Saig_ObjCexMinGet0( Aig_Obj_t * pObj ) { return pObj->fMarkA && !pObj->fMarkB; } -static inline int Saig_ObjCexMinGet1( Aig_Obj_t * pObj ) { return !pObj->fMarkA && pObj->fMarkB; } -static inline int Saig_ObjCexMinGetX( Aig_Obj_t * pObj ) { return pObj->fMarkA && pObj->fMarkB; } - -static inline int Saig_ObjCexMinGet0Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); } -static inline int Saig_ObjCexMinGet1Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); } - -static inline int Saig_ObjCexMinGet0Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); } -static inline int Saig_ObjCexMinGet1Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); } - -static inline void Saig_ObjCexMinSim( Aig_Obj_t * pObj ) -{ - if ( Aig_ObjIsAnd(pObj) ) - { - if ( Saig_ObjCexMinGet0Fanin0(pObj) || Saig_ObjCexMinGet0Fanin1(pObj) ) - Saig_ObjCexMinSet0( pObj ); - else if ( Saig_ObjCexMinGet1Fanin0(pObj) && Saig_ObjCexMinGet1Fanin1(pObj) ) - Saig_ObjCexMinSet1( pObj ); - else - Saig_ObjCexMinSetX( pObj ); - } - else if ( Aig_ObjIsCo(pObj) ) - { - if ( Saig_ObjCexMinGet0Fanin0(pObj) ) - Saig_ObjCexMinSet0( pObj ); - else if ( Saig_ObjCexMinGet1Fanin0(pObj) ) - Saig_ObjCexMinSet1( pObj ); - else - Saig_ObjCexMinSetX( pObj ); - } - else assert( 0 ); -} - -static inline void Saig_ObjCexMinPrint( Aig_Obj_t * pObj ) -{ - if ( Saig_ObjCexMinGet0(pObj) ) - printf( "0" ); - else if ( Saig_ObjCexMinGet1(pObj) ) - printf( "1" ); - else if ( Saig_ObjCexMinGetX(pObj) ) - printf( "X" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManCexVerifyUsingTernary( Aig_Man_t * pAig, Abc_Cex_t * pCex, Abc_Cex_t * pCare ) -{ - Aig_Obj_t * pObj, * pObjRi, * pObjRo; - int i, f, iBit = 0; - assert( pCex->iFrame == pCare->iFrame ); - assert( pCex->nBits == pCare->nBits ); - assert( pCex->iPo < Saig_ManPoNum(pAig) ); - Saig_ObjCexMinSet1( Aig_ManConst1(pAig) ); - // set flops to the init state - Saig_ManForEachLo( pAig, pObj, i ) - { - assert( !Abc_InfoHasBit(pCex->pData, iBit) ); - assert( !Abc_InfoHasBit(pCare->pData, iBit) ); -// if ( Abc_InfoHasBit(pCare->pData, iBit++) ) - Saig_ObjCexMinSet0( pObj ); -// else -// Saig_ObjCexMinSetX( pObj ); - } - iBit = pCex->nRegs; - for ( f = 0; f <= pCex->iFrame; f++ ) - { - // init inputs - Saig_ManForEachPi( pAig, pObj, i ) - { - if ( Abc_InfoHasBit(pCare->pData, iBit++) ) - { - if ( Abc_InfoHasBit(pCex->pData, iBit-1) ) - Saig_ObjCexMinSet1( pObj ); - else - Saig_ObjCexMinSet0( pObj ); - } - else - Saig_ObjCexMinSetX( pObj ); - } - // simulate internal nodes - Aig_ManForEachNode( pAig, pObj, i ) - Saig_ObjCexMinSim( pObj ); - // simulate COs - Aig_ManForEachCo( pAig, pObj, i ) - Saig_ObjCexMinSim( pObj ); -/* - Aig_ManForEachObj( pAig, pObj, i ) - { - Aig_ObjPrint(pAig, pObj); - printf( " Value = " ); - Saig_ObjCexMinPrint( pObj ); - printf( "\n" ); - } -*/ - // transfer - Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, i ) - pObjRo->fMarkA = pObjRi->fMarkA, - pObjRo->fMarkB = pObjRi->fMarkB; - } - assert( iBit == pCex->nBits ); - return Saig_ObjCexMinGet1( Aig_ManCo( pAig, pCex->iPo ) ); -} - -/**Function************************************************************* - - Synopsis [SAT-based refinement of the counter-example.] - - Description [The first parameter (nInputs) indicates how many first - primary inputs to skip without considering as care candidates.] - - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ) -{ - Saig_ManCba_t * p; - Vec_Int_t * vReasons; - Abc_Cex_t * pCare; - clock_t clk = clock(); - - clk = clock(); - p = Saig_ManCbaStart( pAig, pCex, nInputs, fVerbose ); - -// p->vReg2Frame = Vec_VecStart( pCex->iFrame ); -// p->vReg2Value = Vec_VecStart( pCex->iFrame ); - p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, nInputs, &p->vMapPiF2A, &p->vReg2Frame ); - vReasons = Saig_ManCbaFindReason( p ); - if ( p->vReg2Frame ) - Saig_ManCbaShrink( p ); - - -//if ( fVerbose ) -//Aig_ManPrintStats( p->pFrames ); - - if ( fVerbose ) - { - Vec_Int_t * vRes = Saig_ManCbaReason2Inputs( p, vReasons ); - printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", - Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), - Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); - Vec_IntFree( vRes ); -ABC_PRT( "Time", clock() - clk ); - } - - pCare = Saig_ManCbaReason2Cex( p, vReasons ); - Vec_IntFree( vReasons ); - Saig_ManCbaStop( p ); - -if ( fVerbose ) -{ -printf( "Real " ); -Abc_CexPrintStats( pCex ); -} -if ( fVerbose ) -{ -printf( "Care " ); -Abc_CexPrintStats( pCare ); -} -/* - // verify the reduced counter-example using ternary simulation - if ( !Saig_ManCexVerifyUsingTernary( pAig, pCex, pCare ) ) - printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification has failed!!!\n" ); - else if ( fVerbose ) - printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification is successful.\n" ); -*/ - Aig_ManCleanMarkAB( pAig ); - return pCare; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCbaFilterInputs( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) -{ - Saig_ManCba_t * p; - Vec_Int_t * vRes, * vReasons; - clock_t clk; - if ( Saig_ManPiNum(pAig) != pCex->nPis ) - { - printf( "Saig_ManCbaFilterInputs(): The PI count of AIG (%d) does not match that of cex (%d).\n", - Aig_ManCiNum(pAig), pCex->nPis ); - return NULL; - } - -clk = clock(); - p = Saig_ManCbaStart( pAig, pCex, iFirstFlopPi, fVerbose ); - p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, iFirstFlopPi, &p->vMapPiF2A, &p->vReg2Frame ); - vReasons = Saig_ManCbaFindReason( p ); - vRes = Saig_ManCbaReason2Inputs( p, vReasons ); - if ( fVerbose ) - { - printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", - Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), - Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); -ABC_PRT( "Time", clock() - clk ); - } - - Vec_IntFree( vReasons ); - Saig_ManCbaStop( p ); - return vRes; -} - - - - -/**Function************************************************************* - - Synopsis [Checks the abstracted model for a counter-example.] - - Description [Returns the array of abstracted flops that should be added - to the abstraction.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCbaPerform( Aig_Man_t * pAbs, int nInputs, Saig_ParBmc_t * pPars ) -{ - Vec_Int_t * vAbsFfsToAdd; - int RetValue; - clock_t clk = clock(); -// assert( pAbs->nRegs > 0 ); - // perform BMC - RetValue = Saig_ManBmcScalable( pAbs, pPars ); - if ( RetValue == -1 ) // time out - nothing to add - { - printf( "Resource limit is reached during BMC.\n" ); - assert( pAbs->pSeqModel == NULL ); - return Vec_IntAlloc( 0 ); - } - if ( pAbs->pSeqModel == NULL ) - { - printf( "BMC did not detect a CEX with the given depth.\n" ); - return Vec_IntAlloc( 0 ); - } - if ( pPars->fVerbose ) - Abc_CexPrintStats( pAbs->pSeqModel ); - // CEX is detected - refine the flops - vAbsFfsToAdd = Saig_ManCbaFilterInputs( pAbs, nInputs, pAbs->pSeqModel, pPars->fVerbose ); - if ( Vec_IntSize(vAbsFfsToAdd) == 0 ) - { - Vec_IntFree( vAbsFfsToAdd ); - return NULL; - } - if ( pPars->fVerbose ) - { - printf( "Adding %d registers to the abstraction (total = %d). ", - Vec_IntSize(vAbsFfsToAdd), Aig_ManRegNum(pAbs)+Vec_IntSize(vAbsFfsToAdd) ); - Abc_PrintTime( 1, "Time", clock() - clk ); - } - return vAbsFfsToAdd; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigAbsPba.c b/src/aig/saig/saigAbsPba.c deleted file mode 100644 index 34e1decf..00000000 --- a/src/aig/saig/saigAbsPba.c +++ /dev/null @@ -1,374 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigAbsPba.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Proof-based abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigAbsPba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "sat/cnf/cnf.h" -#include "sat/bsat/satSolver.h" -#include "aig/gia/giaAig.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Collect nodes in the unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManUnrollForPba_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots ) -{ - if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) - return; - Aig_ObjSetTravIdCurrent(pAig, pObj); - if ( Aig_ObjIsCo(pObj) ) - Saig_ManUnrollForPba_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); - else if ( Aig_ObjIsNode(pObj) ) - { - Saig_ManUnrollForPba_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); - Saig_ManUnrollForPba_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots ); - } - if ( vRoots && Saig_ObjIsLo( pAig, pObj ) ) - Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) ); - Vec_IntPush( vObjs, Aig_ObjId(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Derives unrolled timeframes for PBA.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_ManUnrollForPba( Aig_Man_t * pAig, int nStart, int nFrames, Vec_Int_t ** pvPiVarMap ) -{ - Aig_Man_t * pFrames; // unrolled timeframes - Vec_Vec_t * vFrameCos; // the list of COs per frame - Vec_Vec_t * vFrameObjs; // the list of objects per frame - Vec_Int_t * vRoots, * vObjs; - Aig_Obj_t * pObj, * pObjNew; - int i, f; - assert( nStart <= nFrames ); - // collect COs and Objs visited in each frame - vFrameCos = Vec_VecStart( nFrames ); - vFrameObjs = Vec_VecStart( nFrames ); - for ( f = nFrames-1; f >= 0; f-- ) - { - // add POs of this frame - vRoots = Vec_VecEntryInt( vFrameCos, f ); - Saig_ManForEachPo( pAig, pObj, i ) - Vec_IntPush( vRoots, Aig_ObjId(pObj) ); - // collect nodes starting from the roots - Aig_ManIncrementTravId( pAig ); - Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) - Saig_ManUnrollForPba_rec( pAig, pObj, - Vec_VecEntryInt( vFrameObjs, f ), - (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) ); - } - // derive unrolled timeframes - pFrames = Aig_ManStart( 10000 ); - pFrames->pName = Abc_UtilStrsav( pAig->pName ); - pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec ); - // create activation variables - Saig_ManForEachLo( pAig, pObj, i ) - Aig_ObjCreateCi( pFrames ); - // initialize the flops - Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_Mux( pFrames, Aig_ManCi(pFrames,i), Aig_ObjCreateCi(pFrames), Aig_ManConst0(pFrames) ); - // iterate through the frames - *pvPiVarMap = Vec_IntStartFull( nFrames * Saig_ManPiNum(pAig) ); - pObjNew = Aig_ManConst0(pFrames); - for ( f = 0; f < nFrames; f++ ) - { - // construct - vObjs = Vec_VecEntryInt( vFrameObjs, f ); - Aig_ManForEachObjVec( vObjs, pAig, pObj, i ) - { - if ( Aig_ObjIsNode(pObj) ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - else if ( Aig_ObjIsCo(pObj) ) - pObj->pData = Aig_ObjChild0Copy(pObj); - else if ( Saig_ObjIsPi(pAig, pObj) ) - { - Vec_IntWriteEntry( *pvPiVarMap, f * Saig_ManPiNum(pAig) + Aig_ObjCioId(pObj), Aig_ManCiNum(pFrames) ); - pObj->pData = Aig_ObjCreateCi( pFrames ); - } - else if ( Aig_ObjIsConst1(pObj) ) - pObj->pData = Aig_ManConst1(pFrames); - else if ( !Saig_ObjIsLo(pAig, pObj) ) - assert( 0 ); - } - // create output - if ( f >= nStart ) - { - Saig_ManForEachPo( pAig, pObj, i ) - pObjNew = Aig_Or( pFrames, pObjNew, (Aig_Obj_t *)pObj->pData ); - } - // transfer - if ( f == nFrames - 1 ) - break; - vRoots = Vec_VecEntryInt( vFrameCos, f ); - Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) - { - if ( Saig_ObjIsLi(pAig, pObj) ) - { - int iFlopNum = Aig_ObjCioId(pObj) - Saig_ManPoNum(pAig); - assert( iFlopNum >= 0 && iFlopNum < Aig_ManRegNum(pAig) ); - Saig_ObjLiToLo(pAig, pObj)->pData = Aig_Mux( pFrames, Aig_ManCi(pFrames,iFlopNum), Aig_ObjCreateCi(pFrames), (Aig_Obj_t *)pObj->pData ); - } - } - } - // cleanup - Vec_VecFree( vFrameCos ); - Vec_VecFree( vFrameObjs ); - // create output - Aig_ObjCreateCo( pFrames, pObjNew ); - Aig_ManSetRegNum( pFrames, 0 ); - // finallize - Aig_ManCleanup( pFrames ); - return pFrames; -} - -/**Function************************************************************* - - Synopsis [Derives the counter-example from the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManPbaDeriveCex( Aig_Man_t * pAig, sat_solver * pSat, Cnf_Dat_t * pCnf, int nFrames, Vec_Int_t * vPiVarMap ) -{ - Abc_Cex_t * pCex; - Aig_Obj_t * pObj, * pObjRi, * pObjRo; - int i, f, Entry, iBit = 0; - pCex = Abc_CexAlloc( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), nFrames ); - pCex->iPo = -1; - pCex->iFrame = -1; - Vec_IntForEachEntry( vPiVarMap, Entry, i ) - { - if ( Entry >= 0 ) - { - int iSatVar = pCnf->pVarNums[ Aig_ObjId(Aig_ManCi(pCnf->pMan, Entry)) ]; - if ( sat_solver_var_value( pSat, iSatVar ) ) - Abc_InfoSetBit( pCex->pData, Aig_ManRegNum(pAig) + i ); - } - } - // check what frame has failed - Aig_ManCleanMarkB(pAig); - Aig_ManConst1(pAig)->fMarkB = 1; - Saig_ManForEachLo( pAig, pObj, i ) - pObj->fMarkB = Abc_InfoHasBit(pCex->pData, iBit++); - for ( f = 0; f < nFrames; f++ ) - { - // compute new state - Saig_ManForEachPi( pAig, pObj, i ) - pObj->fMarkB = Abc_InfoHasBit(pCex->pData, iBit++); - Aig_ManForEachNode( pAig, pObj, i ) - pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & - (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj)); - Aig_ManForEachCo( pAig, pObj, i ) - pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); - Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, i ) - pObjRo->fMarkB = pObjRi->fMarkB; - // check the outputs - Saig_ManForEachPo( pAig, pObj, i ) - { - if ( pObj->fMarkB ) - { - pCex->iPo = i; - pCex->iFrame = f; - pCex->nBits = pCex->nRegs + pCex->nPis * (f+1); - break; - } - } - if ( i < Saig_ManPoNum(pAig) ) - break; - } - Aig_ManCleanMarkB(pAig); - if ( f == nFrames ) - { - Abc_Print( -1, "Saig_ManPbaDeriveCex(): Internal error! Cannot find a failed primary outputs.\n" ); - Abc_CexFree( pCex ); - pCex = NULL; - } - if ( !Saig_ManVerifyCex( pAig, pCex ) ) - { - Abc_Print( -1, "Saig_ManPbaDeriveCex(): Internal error! Counter-example is invalid.\n" ); - Abc_CexFree( pCex ); - pCex = NULL; - } - return pCex; -} - -/**Function************************************************************* - - Synopsis [Derive unrolled timeframes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManPbaDerive( Aig_Man_t * pAig, int nInputs, int nStart, int nFrames, int nConfLimit, int TimeLimit, int fVerbose, int * piFrame ) -{ - Vec_Int_t * vFlops = NULL, * vMapVar2FF, * vAssumps, * vPiVarMap; - Aig_Man_t * pFrames; - sat_solver * pSat; - Cnf_Dat_t * pCnf; - Aig_Obj_t * pObj; - int nCoreLits, * pCoreLits; - int i, iVar, RetValue; - clock_t clk; -if ( fVerbose ) -{ -if ( TimeLimit ) - printf( "Abstracting from frame %d to frame %d with timeout %d sec.\n", nStart, nFrames, TimeLimit ); -else - printf( "Abstracting from frame %d to frame %d with no timeout.\n", nStart, nFrames ); -} - // create SAT solver -clk = clock(); - pFrames = Saig_ManUnrollForPba( pAig, nStart, nFrames, &vPiVarMap ); -if ( fVerbose ) -Aig_ManPrintStats( pFrames ); -// pCnf = Cnf_DeriveSimple( pFrames, 0 ); -// pCnf = Cnf_Derive( pFrames, 0 ); - pCnf = Cnf_DeriveFast( pFrames, 0 ); - pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); - if ( pSat == NULL ) - { - Aig_ManStop( pFrames ); - Cnf_DataFree( pCnf ); - return NULL; - } -if ( fVerbose ) -Abc_PrintTime( 1, "Preparing", clock() - clk ); - - // map activation variables into flop numbers - vAssumps = Vec_IntAlloc( Aig_ManRegNum(pAig) ); - vMapVar2FF = Vec_IntStartFull( pCnf->nVars ); - Aig_ManForEachCi( pFrames, pObj, i ) - { - if ( i >= Aig_ManRegNum(pAig) ) - break; - iVar = pCnf->pVarNums[Aig_ObjId(pObj)]; - Vec_IntPush( vAssumps, toLitCond(iVar, 1) ); - Vec_IntWriteEntry( vMapVar2FF, iVar, i ); - } - - // set runtime limit - if ( TimeLimit ) - sat_solver_set_runtime_limit( pSat, TimeLimit ? TimeLimit * CLOCKS_PER_SEC + clock(): 0 ); - - // run SAT solver -clk = clock(); - RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), - (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); -if ( fVerbose ) -Abc_PrintTime( 1, "Solving", clock() - clk ); - if ( RetValue != l_False ) - { - if ( RetValue == l_True ) - { - Vec_Int_t * vAbsFfsToAdd; - ABC_FREE( pAig->pSeqModel ); - pAig->pSeqModel = Saig_ManPbaDeriveCex( pAig, pSat, pCnf, nFrames, vPiVarMap ); - printf( "The problem is SAT in frame %d. Performing CEX-based refinement.\n", pAig->pSeqModel->iFrame ); - *piFrame = pAig->pSeqModel->iFrame; - // CEX is detected - refine the flops - vAbsFfsToAdd = Saig_ManCbaFilterInputs( pAig, nInputs, pAig->pSeqModel, fVerbose ); - if ( Vec_IntSize(vAbsFfsToAdd) == 0 ) - { - Vec_IntFree( vAbsFfsToAdd ); - goto finish; - } - if ( fVerbose ) - { - printf( "Adding %d registers to the abstraction (total = %d). ", Vec_IntSize(vAbsFfsToAdd), Aig_ManRegNum(pAig)+Vec_IntSize(vAbsFfsToAdd) ); - Abc_PrintTime( 1, "Time", clock() - clk ); - } - vFlops = vAbsFfsToAdd; - } - else - { - printf( "Saig_ManPerformPba(): SAT solver timed out. Current abstraction is not changed.\n" ); - } - goto finish; - } - assert( RetValue == l_False ); // UNSAT - *piFrame = nFrames; - - // get relevant SAT literals - nCoreLits = sat_solver_final( pSat, &pCoreLits ); - assert( nCoreLits > 0 ); - if ( fVerbose ) - printf( "AnalizeFinal after %d frames selected %d assumptions (out of %d). Conflicts = %d.\n", - nFrames, nCoreLits, Vec_IntSize(vAssumps), (int)pSat->stats.conflicts ); - - // collect flops - vFlops = Vec_IntAlloc( nCoreLits ); - for ( i = 0; i < nCoreLits; i++ ) - { - iVar = Vec_IntEntry( vMapVar2FF, lit_var(pCoreLits[i]) ); - assert( iVar >= 0 && iVar < Aig_ManRegNum(pAig) ); - Vec_IntPush( vFlops, iVar ); - } - Vec_IntSort( vFlops, 0 ); - - // cleanup -finish: - Vec_IntFree( vPiVarMap ); - Vec_IntFree( vAssumps ); - Vec_IntFree( vMapVar2FF ); - sat_solver_delete( pSat ); - Cnf_DataFree( pCnf ); - Aig_ManStop( pFrames ); - return vFlops; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigAbsStart.c b/src/aig/saig/saigAbsStart.c deleted file mode 100644 index 90efef26..00000000 --- a/src/aig/saig/saigAbsStart.c +++ /dev/null @@ -1,310 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigAbsStart.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Counter-example-based abstraction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigAbsStart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "proof/ssw/ssw.h" -#include "proof/fra/fra.h" -#include "proof/bbr/bbr.h" -#include "proof/pdr/pdr.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Find the first PI corresponding to the flop.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManCexFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) -{ - Aig_Obj_t * pObj; - int i; - assert( pAbs->vCiNumsOrig != NULL ); - Aig_ManForEachCi( p, pObj, i ) - { - if ( Vec_IntEntry(pAbs->vCiNumsOrig, i) >= Saig_ManPiNum(p) ) - return i; - } - return -1; -} - -/**Function************************************************************* - - Synopsis [Refines abstraction using one step.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int fVerbose, int * pnUseStart, int * piRetValue, int * pnFrames ) -{ - extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames, int fSilent ); - Vec_Int_t * vFlopsNew; - int i, Entry, RetValue; - *piRetValue = -1; - if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 ) - { -/* - Fra_Sec_t SecPar, * pSecPar = &SecPar; - Fra_SecSetDefaultParams( pSecPar ); - pSecPar->fVerbose = fVerbose; - RetValue = Fra_FraigSec( pAbs, pSecPar, NULL ); -*/ - Abc_Cex_t * pCex = NULL; - Aig_Man_t * pAbsOrpos = Saig_ManDupOrpos( pAbs ); - Pdr_Par_t Pars, * pPars = &Pars; - Pdr_ManSetDefaultParams( pPars ); - pPars->nTimeOut = 10; - pPars->fVerbose = fVerbose; - if ( pPars->fVerbose ) - printf( "Running property directed reachability...\n" ); - RetValue = Pdr_ManSolve( pAbsOrpos, pPars, &pCex ); - if ( pCex ) - pCex->iPo = Saig_ManFindFailedPoCex( pAbs, pCex ); - Aig_ManStop( pAbsOrpos ); - pAbs->pSeqModel = pCex; - if ( RetValue ) - *piRetValue = 1; - - } - else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) ) - { - Saig_ParBbr_t Pars, * pPars = &Pars; - Bbr_ManSetDefaultParams( pPars ); - pPars->TimeLimit = 0; - pPars->nBddMax = 1000000; - pPars->nIterMax = nFrames; - pPars->fPartition = 1; - pPars->fReorder = 1; - pPars->fReorderImage = 1; - pPars->fVerbose = fVerbose; - pPars->fSilent = 0; - RetValue = Aig_ManVerifyUsingBdds( pAbs, pPars ); - if ( RetValue ) - *piRetValue = 1; - } - else - { - Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 0, nConfMaxOne, 0, fVerbose, 0, pnFrames, 0 ); - } - if ( pAbs->pSeqModel == NULL ) - return NULL; - if ( pnUseStart ) - *pnUseStart = pAbs->pSeqModel->iFrame; -// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, 1, fVerbose ); - vFlopsNew = Saig_ManExtendCounterExampleTest3( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); - if ( vFlopsNew == NULL ) - return NULL; - if ( Vec_IntSize(vFlopsNew) == 0 ) - { - printf( "Discovered a true counter-example!\n" ); - p->pSeqModel = Saig_ManCexRemap( p, pAbs, pAbs->pSeqModel ); - Vec_IntFree( vFlopsNew ); - *piRetValue = 0; - return NULL; - } - // vFlopsNew contains PI numbers that should be kept in pAbs - if ( fVerbose ) - printf( "Adding %d registers to the abstraction (total = %d).\n\n", Vec_IntSize(vFlopsNew), Aig_ManRegNum(pAbs)+Vec_IntSize(vFlopsNew) ); - // add to the abstraction - Vec_IntForEachEntry( vFlopsNew, Entry, i ) - { - Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); - assert( Entry >= Saig_ManPiNum(p) ); - assert( Entry < Aig_ManCiNum(p) ); - Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); - } - Vec_IntFree( vFlopsNew ); - - Vec_IntSort( vFlops, 0 ); - Vec_IntForEachEntryStart( vFlops, Entry, i, 1 ) - assert( Vec_IntEntry(vFlops, i-1) != Entry ); - - return Saig_ManDupAbstraction( p, vFlops ); -} - -/**Function************************************************************* - - Synopsis [Refines abstraction using one step.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vFlopClasses, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ) -{ - Aig_Man_t * pAbs; - Vec_Int_t * vFlopsNew; - int i, Entry; - clock_t clk = clock(); - pAbs = Saig_ManDupAbstraction( p, vFlops ); - if ( fSensePath ) - vFlopsNew = Saig_ManExtendCounterExampleTest2( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); - else -// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fTryFour, fVerbose ); - vFlopsNew = Saig_ManExtendCounterExampleTest3( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); - if ( vFlopsNew == NULL ) - { - Aig_ManStop( pAbs ); - return 0; - } - if ( Vec_IntSize(vFlopsNew) == 0 ) - { - printf( "Refinement did not happen. Discovered a true counter-example.\n" ); - printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManCiNum(pAbs), Aig_ManCiNum(p) ); - p->pSeqModel = Saig_ManCexRemap( p, pAbs, pCex ); - Vec_IntFree( vFlopsNew ); - Aig_ManStop( pAbs ); - return 0; - } - if ( fVerbose ) - { - printf( "Adding %d registers to the abstraction (total = %d). ", Vec_IntSize(vFlopsNew), Aig_ManRegNum(p)+Vec_IntSize(vFlopsNew) ); - Abc_PrintTime( 1, "Time", clock() - clk ); - } - // vFlopsNew contains PI numbers that should be kept in pAbs - // select the most useful flops among those to be added - if ( nFfToAddMax > 0 && Vec_IntSize(vFlopsNew) > nFfToAddMax ) - { - Vec_Int_t * vFlopsNewBest; - // shift the indices - Vec_IntForEachEntry( vFlopsNew, Entry, i ) - Vec_IntAddToEntry( vFlopsNew, i, -Saig_ManPiNum(p) ); - // create new flops - vFlopsNewBest = Saig_ManCbaFilterFlops( p, pCex, vFlopClasses, vFlopsNew, nFfToAddMax ); - assert( Vec_IntSize(vFlopsNewBest) == nFfToAddMax ); - printf( "Filtering flops based on cost (%d -> %d).\n", Vec_IntSize(vFlopsNew), Vec_IntSize(vFlopsNewBest) ); - // update - Vec_IntFree( vFlopsNew ); - vFlopsNew = vFlopsNewBest; - // shift the indices - Vec_IntForEachEntry( vFlopsNew, Entry, i ) - Vec_IntAddToEntry( vFlopsNew, i, Saig_ManPiNum(p) ); - } - // add to the abstraction - Vec_IntForEachEntry( vFlopsNew, Entry, i ) - { - Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); - assert( Entry >= Saig_ManPiNum(p) ); - assert( Entry < Aig_ManCiNum(p) ); - Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); - } - Vec_IntFree( vFlopsNew ); - Aig_ManStop( pAbs ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes the flops to remain after abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ) -{ - int nUseStart = 0; - Aig_Man_t * pAbs, * pTemp; - Vec_Int_t * vFlops; - int Iter;//, clk = clock(), clk2 = clock();//, iFlop; - assert( Aig_ManRegNum(p) > 0 ); - if ( pPars->fVerbose ) - printf( "Performing counter-example-based refinement.\n" ); - Aig_ManSetCioIds( p ); - vFlops = Vec_IntStartNatural( 1 ); -/* - iFlop = Saig_ManFindFirstFlop( p ); - assert( iFlop >= 0 ); - vFlops = Vec_IntAlloc( 1 ); - Vec_IntPush( vFlops, iFlop ); -*/ - // create the resulting AIG - pAbs = Saig_ManDupAbstraction( p, vFlops ); - if ( !pPars->fVerbose ) - { - printf( "Init : " ); - Aig_ManPrintStats( pAbs ); - } - printf( "Refining abstraction...\n" ); - for ( Iter = 0; ; Iter++ ) - { - pTemp = Saig_ManCexRefine( p, pAbs, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fVerbose, pPars->fUseStart?&nUseStart:NULL, &pPars->Status, &pPars->nFramesDone ); - if ( pTemp == NULL ) - { - ABC_FREE( p->pSeqModel ); - p->pSeqModel = pAbs->pSeqModel; - pAbs->pSeqModel = NULL; - Aig_ManStop( pAbs ); - break; - } - Aig_ManStop( pAbs ); - pAbs = pTemp; - printf( "ITER %4d : ", Iter ); - if ( !pPars->fVerbose ) - Aig_ManPrintStats( pAbs ); - // output the intermediate result of abstraction - Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); -// printf( "Intermediate abstracted model was written into file \"%s\".\n", "gabs.aig" ); - // check if the ratio is reached - if ( 100.0*(Aig_ManRegNum(p)-Aig_ManRegNum(pAbs))/Aig_ManRegNum(p) < 1.0*pPars->nRatio ) - { - printf( "Refinements is stopped because flop reduction is less than %d%%\n", pPars->nRatio ); - Aig_ManStop( pAbs ); - pAbs = NULL; - Vec_IntFree( vFlops ); - vFlops = NULL; - break; - } - } - return vFlops; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigAbsVfa.c b/src/aig/saig/saigAbsVfa.c deleted file mode 100644 index 2c3ebbff..00000000 --- a/src/aig/saig/saigAbsVfa.c +++ /dev/null @@ -1,329 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigAbsVfa.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Intergrated abstraction procedure.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigAbsVfa.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "sat/cnf/cnf.h" -#include "sat/bsat/satSolver.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Abs_VfaMan_t_ Abs_VfaMan_t; -struct Abs_VfaMan_t_ -{ - Aig_Man_t * pAig; - int nConfLimit; - int fVerbose; - // unrolling info - int iFrame; - int nFrames; - Vec_Int_t * vObj2Vec; // maps obj ID into its vec ID - Vec_Int_t * vVec2Var; // maps vec ID into its sat Var (nFrames per vec ID) - Vec_Int_t * vVar2Inf; // maps sat Var into its frame and obj ID - Vec_Int_t * vFra2Var; // maps frame number into the first variable - // SAT solver - sat_solver * pSat; - Cnf_Dat_t * pCnf; - Vec_Int_t * vAssumps; - Vec_Int_t * vCore; -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adds CNF clauses for the MUX.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_VfaManSatMux( sat_solver * pSat, int VarF, int VarI, int VarT, int VarE ) -{ - int RetValue, pLits[3]; - - // 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); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); - - pLits[0] = toLitCond(VarI, 1); - pLits[1] = toLitCond(VarT, 0); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); - - pLits[0] = toLitCond(VarI, 0); - pLits[1] = toLitCond(VarE, 1); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); - - pLits[0] = toLitCond(VarI, 0); - pLits[1] = toLitCond(VarE, 0); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); - - // two additional clauses - // t' & e' -> f' - // t & e -> f - - // t + e + f' - // t' + e' + f - assert( VarT != VarE ); - - pLits[0] = toLitCond(VarT, 0); - pLits[1] = toLitCond(VarE, 0); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); - - pLits[0] = toLitCond(VarT, 1); - pLits[1] = toLitCond(VarE, 1); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( RetValue ); -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abs_VfaManAddVar( Abs_VfaMan_t * p, Aig_Obj_t * pObj, int f, int * pfNew ) -{ - int i, SatId, VecId = Vec_IntEntry( p->vObj2Vec, Aig_ObjId(pObj) ); - *pfNew = 0; - if ( VecId == -1 ) - return -1; - if ( VecId == 0 ) - { - VecId = Vec_IntSize( p->vVec2Var ) / p->nFrames; - for ( i = 0; i < p->nFrames; i++ ) - Vec_IntPush( p->vVec2Var, 0 ); - Vec_IntWriteEntry( p->vObj2Vec, Aig_ObjId(pObj), VecId ); - } - SatId = Vec_IntEntry( p->vVec2Var, p->nFrames * VecId + f ); - if ( SatId ) - return SatId; - SatId = Vec_IntSize( p->vVar2Inf ) / 2; - // save SatId - Vec_IntWriteEntry( p->vVec2Var, p->nFrames * VecId + f, SatId ); - Vec_IntPush( p->vVar2Inf, Aig_ObjId(pObj) ); - Vec_IntPush( p->vVar2Inf, f ); - if ( Saig_ObjIsLo( p->pAig, pObj ) ) // reserve IDs for aux vars - { - Vec_IntPush( p->vVar2Inf, -1 ); - Vec_IntPush( p->vVar2Inf, f ); - Vec_IntPush( p->vVar2Inf, -2 ); - Vec_IntPush( p->vVar2Inf, f ); - } - *pfNew = 1; - return SatId; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abs_VfaManCreateFrame_rec( Abs_VfaMan_t * p, Aig_Obj_t * pObj, int f ) -{ - int SatVar, fNew; - if ( Aig_ObjIsConst1(pObj) ) - return -1; - SatVar = Abs_VfaManAddVar( p, pObj, f, &fNew ); - if ( (SatVar > 0 && !fNew) || Saig_ObjIsPi(p->pAig, pObj) || (Aig_ObjIsCi(pObj) && f==0) ) - return SatVar; - if ( Aig_ObjIsCo(pObj) ) - return Abs_VfaManCreateFrame_rec( p, Aig_ObjFanin0(pObj), f ); - if ( Aig_ObjIsCi(pObj) ) - return Abs_VfaManCreateFrame_rec( p, Saig_ObjLoToLi(p->pAig, pObj), f-1 ); - assert( Aig_ObjIsAnd(pObj) ); - Abs_VfaManCreateFrame_rec( p, Aig_ObjFanin0(pObj), f ); - Abs_VfaManCreateFrame_rec( p, Aig_ObjFanin1(pObj), f ); - return SatVar; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_VfaManCreateFrame( Abs_VfaMan_t * p, int f ) -{ - Aig_Obj_t * pObj; - int i; - clock_t clk = clock(); - - Saig_ManForEachPo( p->pAig, pObj, i ) - Abs_VfaManCreateFrame_rec( p, pObj, f ); - - Vec_IntPush( p->vFra2Var, Vec_IntSize( p->vVar2Inf ) / 2 ); - - printf( "Frame = %3d : ", f ); - printf( "Vecs = %8d ", Vec_IntSize( p->vVec2Var ) / p->nFrames ); - printf( "Vars = %8d ", Vec_IntSize( p->vVar2Inf ) / 2 ); - Abc_PrintTime( 1, "Time", clock() - clk ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abs_VfaMan_t * Abs_VfaManStart( Aig_Man_t * pAig ) -{ - Abs_VfaMan_t * p; - int i; - - p = ABC_CALLOC( Abs_VfaMan_t, 1 ); - p->pAig = pAig; - p->vObj2Vec = Vec_IntStart( Aig_ManObjNumMax(pAig) ); - p->vVec2Var = Vec_IntAlloc( 1 << 20 ); - p->vVar2Inf = Vec_IntAlloc( 1 << 20 ); - p->vFra2Var = Vec_IntStart( 1 ); - - // skip the first variable - Vec_IntPush( p->vVar2Inf, -3 ); - Vec_IntPush( p->vVar2Inf, -3 ); - for ( i = 0; i < p->nFrames; i++ ) - Vec_IntPush( p->vVec2Var, -1 ); - - // transfer values from CNF - p->pCnf = Cnf_DeriveOther( pAig, 0 ); - for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ ) - if ( p->pCnf->pObj2Clause[i] == -1 ) - Vec_IntWriteEntry( p->vObj2Vec, i, -1 ); - - p->vAssumps = Vec_IntAlloc( 100 ); - p->vCore = Vec_IntAlloc( 100 ); - return p; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_VfaManStop( Abs_VfaMan_t * p ) -{ - Vec_IntFreeP( &p->vObj2Vec ); - Vec_IntFreeP( &p->vVec2Var ); - Vec_IntFreeP( &p->vVar2Inf ); - Vec_IntFreeP( &p->vFra2Var ); - Vec_IntFreeP( &p->vAssumps ); - Vec_IntFreeP( &p->vCore ); - if ( p->pCnf ) - Cnf_DataFree( p->pCnf ); - if ( p->pSat ) - sat_solver_delete( p->pSat ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Perform variable frame abstraction.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_VfaManTest( Aig_Man_t * pAig, int nFrames, int nConfLimit, int fVerbose ) -{ - Abs_VfaMan_t * p; - int i; - - p = Abs_VfaManStart( pAig ); - p->nFrames = nFrames; - p->nConfLimit = nConfLimit; - p->fVerbose = fVerbose; - - - // create unrolling for the given number of frames - for ( i = 0; i < p->nFrames; i++ ) - Abs_VfaManCreateFrame( p, i ); - - - Abs_VfaManStop( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigSimExt.c b/src/aig/saig/saigSimExt.c deleted file mode 100644 index 1a5ec7e5..00000000 --- a/src/aig/saig/saigSimExt.c +++ /dev/null @@ -1,556 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigSimExt.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Extending simulation trace to contain ternary values.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigSimExt.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "proof/ssw/ssw.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Saig_ManSimInfoNot( int Value ) -{ - if ( Value == SAIG_ZER ) - return SAIG_ONE; - if ( Value == SAIG_ONE ) - return SAIG_ZER; - return SAIG_UND; -} - -static inline int Saig_ManSimInfoAnd( int Value0, int Value1 ) -{ - if ( Value0 == SAIG_ZER || Value1 == SAIG_ZER ) - return SAIG_ZER; - if ( Value0 == SAIG_ONE && Value1 == SAIG_ONE ) - return SAIG_ONE; - return SAIG_UND; -} - -static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); - return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); -} - -static inline void Saig_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) -{ - unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); - assert( Value >= SAIG_ZER && Value <= SAIG_UND ); - Value ^= Saig_ManSimInfoGet( vSimInfo, pObj, iFrame ); - pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs ternary simulation for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - int Value0, Value1, Value; - Value0 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin0(pObj), iFrame ); - if ( Aig_ObjFaninC0(pObj) ) - Value0 = Saig_ManSimInfoNot( Value0 ); - if ( Aig_ObjIsCo(pObj) ) - { - Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); - return Value0; - } - assert( Aig_ObjIsNode(pObj) ); - Value1 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin1(pObj), iFrame ); - if ( Aig_ObjFaninC1(pObj) ) - Value1 = Saig_ManSimInfoNot( Value1 ); - Value = Saig_ManSimInfoAnd( Value0, Value1 ); - Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - return Value; -} - -/**Function************************************************************* - - Synopsis [Performs ternary simulation for one design.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ) -{ - Aig_Obj_t * pObj, * pObjLi, * pObjLo; - int i, f, Entry, iBit = 0; - Saig_ManForEachLo( p, pObj, i ) - Saig_ManSimInfoSet( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER ); - for ( f = 0; f <= pCex->iFrame; f++ ) - { - Saig_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE ); - Saig_ManForEachPi( p, pObj, i ) - Saig_ManSimInfoSet( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER ); - if ( vRes ) - Vec_IntForEachEntry( vRes, Entry, i ) - Saig_ManSimInfoSet( vSimInfo, Aig_ManCi(p, Entry), f, SAIG_UND ); - Aig_ManForEachNode( p, pObj, i ) - Saig_ManExtendOneEval( vSimInfo, pObj, f ); - Aig_ManForEachCo( p, pObj, i ) - Saig_ManExtendOneEval( vSimInfo, pObj, f ); - if ( f == pCex->iFrame ) - break; - Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) - Saig_ManSimInfoSet( vSimInfo, pObjLo, f+1, Saig_ManSimInfoGet(vSimInfo, pObjLi, f) ); - } - // make sure the output of the property failed - pObj = Aig_ManCo( p, pCex->iPo ); - return Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame ); -} - -/**Function************************************************************* - - Synopsis [Tries to assign ternary value to one of the primary inputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManExtendOne( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, - int iPi, int iFrame, Vec_Int_t * vUndo, Vec_Int_t * vVis, Vec_Int_t * vVis2 ) -{ - Aig_Obj_t * pFanout, * pObj = Aig_ManCi(p, iPi); - int i, k, f, iFanout = -1, Value, Value2, Entry; - // save original value - Value = Saig_ManSimInfoGet( vSimInfo, pObj, iFrame ); - assert( Value == SAIG_ZER || Value == SAIG_ONE ); - Vec_IntPush( vUndo, Aig_ObjId(pObj) ); - Vec_IntPush( vUndo, iFrame ); - Vec_IntPush( vUndo, Value ); - // update original value - Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, SAIG_UND ); - // traverse - Vec_IntClear( vVis ); - Vec_IntPush( vVis, Aig_ObjId(pObj) ); - for ( f = iFrame; f <= pCex->iFrame; f++ ) - { - Vec_IntClear( vVis2 ); - Vec_IntForEachEntry( vVis, Entry, i ) - { - pObj = Aig_ManObj( p, Entry ); - Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k ) - { - assert( Aig_ObjId(pObj) < Aig_ObjId(pFanout) ); - Value = Saig_ManSimInfoGet( vSimInfo, pFanout, f ); - if ( Value == SAIG_UND ) - continue; - Value2 = Saig_ManExtendOneEval( vSimInfo, pFanout, f ); - if ( Value2 == Value ) - continue; - assert( Value2 == SAIG_UND ); -// assert( Vec_IntFind(vVis, Aig_ObjId(pFanout)) == -1 ); - if ( Aig_ObjIsNode(pFanout) ) - Vec_IntPushOrder( vVis, Aig_ObjId(pFanout) ); - else if ( Saig_ObjIsLi(p, pFanout) ) - Vec_IntPush( vVis2, Aig_ObjId(pFanout) ); - Vec_IntPush( vUndo, Aig_ObjId(pFanout) ); - Vec_IntPush( vUndo, f ); - Vec_IntPush( vUndo, Value ); - } - } - if ( Vec_IntSize(vVis2) == 0 ) - break; - if ( f == pCex->iFrame ) - break; - // transfer - Vec_IntClear( vVis ); - Vec_IntForEachEntry( vVis2, Entry, i ) - { - pObj = Aig_ManObj( p, Entry ); - assert( Saig_ObjIsLi(p, pObj) ); - pFanout = Saig_ObjLiToLo( p, pObj ); - Vec_IntPushOrder( vVis, Aig_ObjId(pFanout) ); - Value = Saig_ManSimInfoGet( vSimInfo, pObj, f ); - Saig_ManSimInfoSet( vSimInfo, pFanout, f+1, Value ); - } - } - // check the output - pObj = Aig_ManCo( p, pCex->iPo ); - Value = Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame ); - assert( Value == SAIG_ONE || Value == SAIG_UND ); - return (int)(Value == SAIG_ONE); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManExtendUndo( Aig_Man_t * p, Vec_Ptr_t * vSimInfo, Vec_Int_t * vUndo ) -{ - Aig_Obj_t * pObj; - int i, iFrame, Value; - for ( i = 0; i < Vec_IntSize(vUndo); i += 3 ) - { - pObj = Aig_ManObj( p, Vec_IntEntry(vUndo, i) ); - iFrame = Vec_IntEntry(vUndo, i+1); - Value = Vec_IntEntry(vUndo, i+2); - assert( Saig_ManSimInfoGet(vSimInfo, pObj, iFrame) == SAIG_UND ); - Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - } -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample0( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); - assert( Value == SAIG_ONE ); - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - vVis = Vec_IntAlloc( 1000 ); - vVis2 = Vec_IntAlloc( 1000 ); - vUndo = Vec_IntAlloc( 1000 ); - for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) - { - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - Vec_IntFree( vVis ); - Vec_IntFree( vVis2 ); - Vec_IntFree( vUndo ); - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample1( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); - assert( Value == SAIG_ONE ); - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - vVis = Vec_IntAlloc( 1000 ); - vVis2 = Vec_IntAlloc( 1000 ); - vUndo = Vec_IntAlloc( 1000 ); - for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) - { - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - Vec_IntFree( vVis ); - Vec_IntFree( vVis2 ); - Vec_IntFree( vUndo ); - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); - assert( Value == SAIG_ONE ); - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - vVis = Vec_IntAlloc( 1000 ); - vVis2 = Vec_IntAlloc( 1000 ); - vUndo = Vec_IntAlloc( 1000 ); - for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) - { - if ( i % 2 == 0 ) - continue; - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) - { - if ( i % 2 == 1 ) - continue; - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - Vec_IntFree( vVis ); - Vec_IntFree( vVis2 ); - Vec_IntFree( vUndo ); - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample3( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); - assert( Value == SAIG_ONE ); - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - vVis = Vec_IntAlloc( 1000 ); - vVis2 = Vec_IntAlloc( 1000 ); - vUndo = Vec_IntAlloc( 1000 ); - for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) - { - if ( i % 2 == 0 ) - continue; - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) - { - if ( i % 2 == 1 ) - continue; - Vec_IntClear( vUndo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) - { - Saig_ManExtendUndo( p, vSimInfo, vUndo ); - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - Vec_IntFree( vVis ); - Vec_IntFree( vVis2 ); - Vec_IntFree( vUndo ); - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Vec_Int_t * vRes0 = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - Vec_Int_t * vRes1 = Saig_ManExtendCounterExample1( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - Vec_Int_t * vRes2 = Saig_ManExtendCounterExample2( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - Vec_Int_t * vRes3 = Saig_ManExtendCounterExample3( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - Vec_Int_t * vRes = vRes0; -// if ( fVerbose ) - printf( "Removable flops: Order0 =%3d. Order1 =%3d. Order2 =%3d. Order3 =%3d.\n", - Vec_IntSize(vRes0), Vec_IntSize(vRes1), Vec_IntSize(vRes2), Vec_IntSize(vRes3) ); - if ( Vec_IntSize(vRes1) < Vec_IntSize(vRes) ) - vRes = vRes1; - if ( Vec_IntSize(vRes2) < Vec_IntSize(vRes) ) - vRes = vRes2; - if ( Vec_IntSize(vRes3) < Vec_IntSize(vRes) ) - vRes = vRes3; - vRes = Vec_IntDup( vRes ); - Vec_IntFree( vRes0 ); - Vec_IntFree( vRes1 ); - Vec_IntFree( vRes2 ); - Vec_IntFree( vRes3 ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fTryFour, int fVerbose ) -{ - Vec_Int_t * vRes; - Vec_Ptr_t * vSimInfo; - clock_t clk; - if ( Saig_ManPiNum(p) != pCex->nPis ) - { - printf( "Saig_ManExtendCounterExampleTest(): The PI count of AIG (%d) does not match that of cex (%d).\n", - Aig_ManCiNum(p), pCex->nPis ); - return NULL; - } - Aig_ManFanoutStart( p ); - vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) ); - Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) ); - -clk = clock(); - if ( fTryFour ) - vRes = Saig_ManExtendCounterExample( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - else - vRes = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - if ( fVerbose ) - { - printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); -ABC_PRT( "Time", clock() - clk ); - } - Vec_PtrFree( vSimInfo ); - Aig_ManFanoutStop( p ); - return vRes; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/saig/saigSimExt2.c b/src/aig/saig/saigSimExt2.c deleted file mode 100644 index ca46c0b3..00000000 --- a/src/aig/saig/saigSimExt2.c +++ /dev/null @@ -1,481 +0,0 @@ -/**CFile**************************************************************** - - FileName [saigSimExt2.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential AIG package.] - - Synopsis [Extending simulation trace to contain ternary values.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: saigSimExt2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "saig.h" -#include "proof/ssw/ssw.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define SAIG_ZER_NEW 0 // 0 not visited -#define SAIG_ONE_NEW 1 // 1 not visited -#define SAIG_ZER_OLD 2 // 0 visited -#define SAIG_ONE_OLD 3 // 1 visited - -static inline int Saig_ManSimInfo2IsOld( int Value ) -{ - return Value == SAIG_ZER_OLD || Value == SAIG_ONE_OLD; -} - -static inline int Saig_ManSimInfo2SetOld( int Value ) -{ - if ( Value == SAIG_ZER_NEW ) - return SAIG_ZER_OLD; - if ( Value == SAIG_ONE_NEW ) - return SAIG_ONE_OLD; - assert( 0 ); - return 0; -} - -static inline int Saig_ManSimInfo2Not( int Value ) -{ - if ( Value == SAIG_ZER_NEW ) - return SAIG_ONE_NEW; - if ( Value == SAIG_ONE_NEW ) - return SAIG_ZER_NEW; - if ( Value == SAIG_ZER_OLD ) - return SAIG_ONE_OLD; - if ( Value == SAIG_ONE_OLD ) - return SAIG_ZER_OLD; - assert( 0 ); - return 0; -} - -static inline int Saig_ManSimInfo2And( int Value0, int Value1 ) -{ - if ( Value0 == SAIG_ZER_NEW || Value1 == SAIG_ZER_NEW ) - return SAIG_ZER_NEW; - if ( Value0 == SAIG_ONE_NEW && Value1 == SAIG_ONE_NEW ) - return SAIG_ONE_NEW; - assert( 0 ); - return 0; -} - -static inline int Saig_ManSimInfo2Get( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); - return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); -} - -static inline void Saig_ManSimInfo2Set( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) -{ - unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); - Value ^= Saig_ManSimInfo2Get( vSimInfo, pObj, iFrame ); - pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); -} - -// performs ternary simulation -extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs ternary simulation for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManExtendOneEval2( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - int Value0, Value1, Value; - Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pObj), iFrame ); - if ( Aig_ObjFaninC0(pObj) ) - Value0 = Saig_ManSimInfo2Not( Value0 ); - if ( Aig_ObjIsCo(pObj) ) - { - Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value0 ); - return Value0; - } - assert( Aig_ObjIsNode(pObj) ); - Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pObj), iFrame ); - if ( Aig_ObjFaninC1(pObj) ) - Value1 = Saig_ManSimInfo2Not( Value1 ); - Value = Saig_ManSimInfo2And( Value0, Value1 ); - Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value ); - return Value; -} - -/**Function************************************************************* - - Synopsis [Performs sensitization analysis for one design.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_ManSimDataInit2( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo ) -{ - Aig_Obj_t * pObj, * pObjLi, * pObjLo; - int i, f, iBit = 0; - Saig_ManForEachLo( p, pObj, i ) - Saig_ManSimInfo2Set( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); - for ( f = 0; f <= pCex->iFrame; f++ ) - { - Saig_ManSimInfo2Set( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE_NEW ); - Saig_ManForEachPi( p, pObj, i ) - Saig_ManSimInfo2Set( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); - Aig_ManForEachNode( p, pObj, i ) - Saig_ManExtendOneEval2( vSimInfo, pObj, f ); - Aig_ManForEachCo( p, pObj, i ) - Saig_ManExtendOneEval2( vSimInfo, pObj, f ); - if ( f == pCex->iFrame ) - break; - Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) - Saig_ManSimInfo2Set( vSimInfo, pObjLo, f+1, Saig_ManSimInfo2Get(vSimInfo, pObjLi, f) ); - } - // make sure the output of the property failed - pObj = Aig_ManCo( p, pCex->iPo ); - return Saig_ManSimInfo2Get( vSimInfo, pObj, pCex->iFrame ); -} - -/**Function************************************************************* - - Synopsis [Drive implications of the given node towards primary outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) -{ - Aig_Obj_t * pFanout; - int k, iFanout = -1, Value0, Value1; - int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); - assert( !Saig_ManSimInfo2IsOld( Value ) ); - Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) ); - if ( (Aig_ObjIsCo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) ) - return; - if ( Saig_ObjIsLi( p, pObj ) ) - { - assert( f < fMax ); - pFanout = Saig_ObjLiToLo(p, pObj); - Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 ); - if ( !Saig_ManSimInfo2IsOld( Value ) ) - Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo ); - return; - } - assert( Aig_ObjIsCi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) ); - Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k ) - { - Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f ); - if ( Saig_ManSimInfo2IsOld( Value ) ) - continue; - if ( Aig_ObjIsCo(pFanout) ) - { - Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); - continue; - } - assert( Aig_ObjIsNode(pFanout) ); - Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f ); - Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f ); - if ( Aig_ObjFaninC0(pFanout) ) - Value0 = Saig_ManSimInfo2Not( Value0 ); - if ( Aig_ObjFaninC1(pFanout) ) - Value1 = Saig_ManSimInfo2Not( Value1 ); - if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD || - (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) ) - Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); - } -} - -/**Function************************************************************* - - Synopsis [Performs recursive sensetization analysis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_ManExplorePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) -{ - int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); - if ( Saig_ManSimInfo2IsOld( Value ) ) - return; - Saig_ManSetAndDriveImplications_rec( p, pObj, f, fMax, vSimInfo ); - assert( !Aig_ObjIsConst1(pObj) ); - if ( Saig_ObjIsLo(p, pObj) && f == 0 ) - return; - if ( Saig_ObjIsPi(p, pObj) ) - { - // propagate implications of this assignment - int i, iPiNum = Aig_ObjCioId(pObj); - for ( i = fMax; i >= 0; i-- ) - if ( i != f ) - Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, iPiNum), i, fMax, vSimInfo ); - return; - } - if ( Saig_ObjIsLo( p, pObj ) ) - { - assert( f > 0 ); - Saig_ManExplorePaths_rec( p, Saig_ObjLoToLi(p, pObj), f-1, fMax, vSimInfo ); - return; - } - if ( Aig_ObjIsCo(pObj) ) - { - Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); - return; - } - assert( Aig_ObjIsNode(pObj) ); - if ( Value == SAIG_ZER_OLD ) - { -// if ( (Aig_ObjId(pObj) & 1) == 0 ) - Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); -// else -// Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); - } - else - { - Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); - Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); - } -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManProcessCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Aig_Obj_t * pObj; - Vec_Int_t * vRes, * vResInv; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit2( p, pCex, vSimInfo ); - assert( Value == SAIG_ONE_NEW ); - // derive implications of constants and primary inputs - Saig_ManForEachLo( p, pObj, i ) - Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - { - Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo ); - for ( i = 0; i < iFirstFlopPi; i++ ) - Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo ); - } - // recursively compute justification - Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo ); - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) - { - for ( f = pCex->iFrame; f >= 0; f-- ) - { - Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f ); - if ( Saig_ManSimInfo2IsOld( Value ) ) - break; - } - if ( f >= 0 ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - return vRes; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) -{ - Vec_Int_t * vRes; - Vec_Ptr_t * vSimInfo; - clock_t clk; - if ( Saig_ManPiNum(p) != pCex->nPis ) - { - printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", - Aig_ManCiNum(p), pCex->nPis ); - return NULL; - } - Aig_ManFanoutStart( p ); - vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) ); - Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) ); - -clk = clock(); - vRes = Saig_ManProcessCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - if ( fVerbose ) - { - printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); -ABC_PRT( "Time", clock() - clk ); - } - Vec_PtrFree( vSimInfo ); - Aig_ManFanoutStop( p ); - return vRes; -} - - - - - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManDeriveCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) -{ - Abc_Cex_t * pCare; - Aig_Obj_t * pObj; - Vec_Int_t * vRes, * vResInv; - int i, f, Value; -// assert( Aig_ManRegNum(p) > 0 ); - assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); - // start simulation data - Value = Saig_ManSimDataInit2( p, pCex, vSimInfo ); - assert( Value == SAIG_ONE_NEW ); - // derive implications of constants and primary inputs - Saig_ManForEachLo( p, pObj, i ) - Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo ); - for ( f = pCex->iFrame; f >= 0; f-- ) - { - Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo ); - for ( i = 0; i < iFirstFlopPi; i++ ) - Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo ); - } - // recursively compute justification - Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo ); - - // create CEX - pCare = Abc_CexDup( pCex, pCex->nRegs ); - memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); - - // select the result - vRes = Vec_IntAlloc( 1000 ); - vResInv = Vec_IntAlloc( 1000 ); - for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) - { - int fFound = 0; - for ( f = pCex->iFrame; f >= 0; f-- ) - { - Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f ); - if ( Saig_ManSimInfo2IsOld( Value ) ) - { - fFound = 1; - Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * f + i ); - } - } - if ( fFound ) - Vec_IntPush( vRes, i ); - else - Vec_IntPush( vResInv, i ); - } - // resimulate to make sure it is valid - Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); - assert( Value == SAIG_ONE ); - Vec_IntFree( vResInv ); - Vec_IntFree( vRes ); - - return pCare; -} - -/**Function************************************************************* - - Synopsis [Returns the array of PIs for flops that should not be absracted.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Cex_t * Saig_ManFindCexCareBitsSense( Aig_Man_t * p, Abc_Cex_t * pCex, int iFirstFlopPi, int fVerbose ) -{ - Abc_Cex_t * pCare; - Vec_Ptr_t * vSimInfo; - clock_t clk; - if ( Saig_ManPiNum(p) != pCex->nPis ) - { - printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", - Aig_ManCiNum(p), pCex->nPis ); - return NULL; - } - Aig_ManFanoutStart( p ); - vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) ); - Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) ); - -clk = clock(); - pCare = Saig_ManDeriveCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); - if ( fVerbose ) - { -// printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); -Abc_CexPrintStats( pCex ); -Abc_CexPrintStats( pCare ); -ABC_PRT( "Time", clock() - clk ); - } - - Vec_PtrFree( vSimInfo ); - Aig_ManFanoutStop( p ); - return pCare; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1ecab451..7ea474f7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -49,6 +49,7 @@ #include "proof/bbr/bbr.h" #include "map/cov/cov.h" #include "base/cmd/cmd.h" +#include "proof/abs/abs.h" #ifdef _WIN32 //#include @@ -350,14 +351,12 @@ static int Abc_CommandAbc9Trace ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Era ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Dch ( Abc_Frame_t * pAbc, int argc, char ** argv ); -//static int Abc_CommandAbc9AbsStart ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9AbsDerive ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9AbsRefine ( Abc_Frame_t * pAbc, int argc, char ** argv ); //static int Abc_CommandAbc9AbsCba ( Abc_Frame_t * pAbc, int argc, char ** argv ); //static int Abc_CommandAbc9AbsPba ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GlaDerive ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GlaRefine ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandAbc9GlaPurify ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GlaShrink ( Abc_Frame_t * pAbc, int argc, char ** argv ); //static int Abc_CommandAbc9GlaCba ( Abc_Frame_t * pAbc, int argc, char ** argv ); //static int Abc_CommandAbc9GlaPba ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -811,14 +810,12 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&speedup", Abc_CommandAbc9Speedup, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&era", Abc_CommandAbc9Era, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&dch", Abc_CommandAbc9Dch, 0 ); -// Cmd_CommandAdd( pAbc, "ABC9", "&abs_start", Abc_CommandAbc9AbsStart, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&abs_derive", Abc_CommandAbc9AbsDerive, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&abs_refine", Abc_CommandAbc9AbsRefine, 0 ); // Cmd_CommandAdd( pAbc, "ABC9", "&abs_cba", Abc_CommandAbc9AbsCba, 0 ); // Cmd_CommandAdd( pAbc, "ABC9", "&abs_pba", Abc_CommandAbc9AbsPba, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&gla_derive", Abc_CommandAbc9GlaDerive, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&gla_refine", Abc_CommandAbc9GlaRefine, 0 ); - Cmd_CommandAdd( pAbc, "ABC9", "&gla_purify", Abc_CommandAbc9GlaPurify, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&gla_shrink", Abc_CommandAbc9GlaShrink, 0 ); // Cmd_CommandAdd( pAbc, "ABC9", "&gla_cba", Abc_CommandAbc9GlaCba, 0 ); // Cmd_CommandAdd( pAbc, "ABC9", "&gla_pba", Abc_CommandAbc9GlaPba, 0 ); @@ -27245,127 +27242,6 @@ usage: return 1; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandAbc9AbsStart( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Gia_ParAbs_t Pars, * pPars = &Pars; - int c; - // set defaults - Gia_ManAbsSetDefaultParams( pPars ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCRrpfvh" ) ) != EOF ) - { - switch ( c ) - { - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFramesBmc = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFramesBmc < 0 ) - goto usage; - break; -/* - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nStableMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nStableMax < 0 ) - goto usage; - break; -*/ - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfMaxBmc = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfMaxBmc < 0 ) - goto usage; - break; - case 'R': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRatio = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRatio < 0 ) - goto usage; - break; - case 'r': - pPars->fUseBdds ^= 1; - break; - case 'p': - pPars->fUseDprove ^= 1; - break; - case 'f': - pPars->fUseStart ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9AbsStart(): There is no AIG.\n" ); - return 1; - } - if ( Gia_ManRegNum(pAbc->pGia) == 0 ) - { - Abc_Print( -1, "Abc_CommandAbc9AbsStart(): The AIG is combinational.\n" ); - return 0; - } - if ( !(0 <= pPars->nRatio && pPars->nRatio <= 100) ) - { - Abc_Print( -1, "Abc_CommandAbc9AbsStart(): Wrong value of parameter \"-R \".\n" ); - return 0; - } - Gia_ManCexAbstractionStart( pAbc->pGia, pPars ); - pAbc->Status = pPars->Status; - pAbc->nFrames = pPars->nFramesDone; - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); - return 0; -usage: - Abc_Print( -2, "usage: &abs_start [-FCR num] [-rpfvh]\n" ); - Abc_Print( -2, "\t initializes flop map using cex-based abstraction\n" ); - Abc_Print( -2, "\t-F num : the max number of timeframes for BMC [default = %d]\n", pPars->nFramesBmc ); -// Abc_Print( -2, "\t-S num : the max number of stable frames for BMC [default = %d]\n", pPars->nStableMax ); - Abc_Print( -2, "\t-C num : the max number of conflicts by SAT solver for BMC [default = %d]\n", pPars->nConfMaxBmc ); - Abc_Print( -2, "\t-R num : the %% of abstracted flops when refinement stops (0<=num<=100) [default = %d]\n", pPars->nRatio ); - Abc_Print( -2, "\t-r : toggle using BDD-based reachability for filtering [default = %s]\n", pPars->fUseBdds? "yes": "no" ); -// Abc_Print( -2, "\t-p : toggle using \"dprove\" for filtering [default = %s]\n", pPars->fUseDprove? "yes": "no" ); - Abc_Print( -2, "\t-p : toggle using \"pdr\" for filtering [default = %s]\n", pPars->fUseDprove? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle starting BMC from a later frame [default = %s]\n", pPars->fUseStart? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} /**Function************************************************************* @@ -27504,6 +27380,8 @@ usage: return 1; } +#if 0 + /**Function************************************************************* Synopsis [] @@ -27737,6 +27615,8 @@ usage: return 1; } +#endif + /**Function************************************************************* Synopsis [] @@ -27885,75 +27765,6 @@ usage: return 1; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandAbc9GlaPurify( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern void Gia_ManGlaPurify( Gia_Man_t * p, int nPurifyRatio, int fVerbose ); - int fMinCut = 0; - int nPurifyRatio = 0; - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Rmvh" ) ) != EOF ) - { - switch ( c ) - { - case 'R': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); - goto usage; - } - nPurifyRatio = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( nPurifyRatio < 0 ) - goto usage; - break; - case 'm': - fMinCut ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9GlaPurify(): There is no AIG.\n" ); - return 1; - } - if ( pAbc->pGia->vGateClasses == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9GlaPurify(): There is no gate-level abstraction.\n" ); - return 0; - } - Gia_ManGlaPurify( pAbc->pGia, nPurifyRatio, fVerbose ); - return 0; - -usage: - Abc_Print( -2, "usage: &gla_purify [-R num] [-vh]\n" ); - Abc_Print( -2, "\t purifies gate-level abstraction by removing less frequent objects\n" ); -// Abc_Print( -2, "\t-R num : the percetage of rare objects to remove [default = %d]\n", nPurifyRatio ); - Abc_Print( -2, "\t-R num : remove objects with usage count less or equal than this [default = %d]\n", nPurifyRatio ); -// Abc_Print( -2, "\t-m : toggle using min-cut to derive the refinements [default = %s]\n", fMinCut? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - /**Function************************************************************* Synopsis [] @@ -27967,7 +27778,6 @@ usage: ***********************************************************************/ int Abc_CommandAbc9GlaShrink( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Gia_Man_t * Gia_IterImprove( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose ); int fUsePdr = 0; int fUseSat = 1; int fUseBdd = 0; @@ -28029,7 +27839,7 @@ int Abc_CommandAbc9GlaShrink( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9GlaShrink(): There is no gate-level abstraction.\n" ); return 0; } - Gia_IterImprove( pAbc->pGia, nFrameMax, nTimeOut, fUsePdr, fUseSat, fUseBdd, fVerbose ); + Gia_ManShrinkGla( pAbc->pGia, nFrameMax, nTimeOut, fUsePdr, fUseSat, fUseBdd, fVerbose ); return 0; usage: @@ -28045,274 +27855,6 @@ usage: return 1; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandAbc9GlaCba( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Saig_ParBmc_t Pars, * pPars = &Pars; - int c, fNaiveCnf = 0; - Saig_ParBmcSetDefaultParams( pPars ); - pPars->nStart = (pAbc->nFrames >= 0) ? pAbc->nFrames : 0; - pPars->nFramesMax = 0; - pPars->nConfLimit = 0; - pPars->nTimeOut = 60; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "SFCMTcvh" ) ) != EOF ) - { - switch ( c ) - { - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nStart = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nStart < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFramesMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFramesMax < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfLimit < 0 ) - goto usage; - break; - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFfToAddMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFfToAddMax < 0 ) - goto usage; - break; - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOut = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOut < 0 ) - goto usage; - break; - case 'c': - fNaiveCnf ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9AbsCba(): There is no AIG.\n" ); - return 1; - } - if ( Gia_ManRegNum(pAbc->pGia) == 0 ) - { - Abc_Print( -1, "The network is combinational.\n" ); - return 0; - } - if ( Gia_ManPoNum(pAbc->pGia) > 1 ) - { - Abc_Print( 1, "The network is more than one PO (run \"orpos\").\n" ); - return 0; - } - if ( pPars->nFramesMax < 0 ) - { - Abc_Print( 1, "The number of frames should be a positive integer.\n" ); - return 0; - } - if ( pPars->nStart > 0 && pPars->nFramesMax > 0 && pPars->nStart >= pPars->nFramesMax ) - { - Abc_Print( 1, "The starting frame is larger than the max number of frames.\n" ); - return 0; - } - pAbc->Status = Gia_ManGlaCbaPerform( pAbc->pGia, pPars, fNaiveCnf ); -// if ( pPars->nStart == 0 ) - pAbc->nFrames = pPars->iFrame; - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); - return 0; - -usage: - Abc_Print( -2, "usage: &gla_cba [-SFCT num] [-cvh]\n" ); - Abc_Print( -2, "\t refines abstracted object map with CEX-based abstraction\n" ); - Abc_Print( -2, "\t-S num : the starting time frame (0=unused) [default = %d]\n", pPars->nStart ); - Abc_Print( -2, "\t-F num : the max number of timeframes to unroll (0=unused) [default = %d]\n", pPars->nFramesMax ); - Abc_Print( -2, "\t-C num : the max number of SAT solver conflicts (0=unused) [default = %d]\n", pPars->nConfLimit ); -// Abc_Print( -2, "\t-M num : the max number of flops to add (0 = not used) [default = %d]\n", pPars->nFfToAddMax ); - Abc_Print( -2, "\t-T num : an approximate timeout in seconds (0=unused) [default = %d]\n", pPars->nTimeOut ); - Abc_Print( -2, "\t-c : toggle using naive CNF computation [default = %s]\n", fNaiveCnf? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandAbc9GlaPba( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Saig_ParBmc_t Pars, * pPars = &Pars; - int c; - int fNewSolver = 0; - Saig_ParBmcSetDefaultParams( pPars ); - pPars->nStart = 0; - pPars->nFramesMax = (pAbc->nFrames >= 0) ? pAbc->nFrames : 10; - pPars->nConfLimit = 0; - pPars->fSkipRand = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "SFCTrnvh" ) ) != EOF ) - { - switch ( c ) - { - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nStart = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nStart < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFramesMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFramesMax < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfLimit < 0 ) - goto usage; - break; - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOut = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOut < 0 ) - goto usage; - break; - case 'r': - pPars->fSkipRand ^= 1; - break; - case 'n': - fNewSolver ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9AbsCba(): There is no AIG.\n" ); - return 1; - } - if ( Gia_ManRegNum(pAbc->pGia) == 0 ) - { - Abc_Print( -1, "The network is combinational.\n" ); - return 0; - } - if ( Gia_ManPoNum(pAbc->pGia) > 1 ) - { - Abc_Print( 1, "The network is more than one PO (run \"orpos\").\n" ); - return 0; - } - if ( pPars->nFramesMax < 1 ) - { - Abc_Print( 1, "The number of frames should be a positive integer.\n" ); - return 0; - } - if ( pPars->nStart >= pPars->nFramesMax ) - { - Abc_Print( 1, "The starting frame is larger than the max number of frames.\n" ); - return 0; - } - if ( pPars->nStart ) - Abc_Print( 0, "The starting frame is specified. The resulting abstraction may be unsound.\n" ); - pAbc->Status = Gia_ManGlaPbaPerform( pAbc->pGia, pPars, fNewSolver ); -// if ( pPars->nStart == 0 ) - pAbc->nFrames = pPars->iFrame; - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); - return 0; - -usage: - Abc_Print( -2, "usage: &gla_pba [-SFCT num] [-rnvh]\n" ); - Abc_Print( -2, "\t refines abstracted object map with proof-based abstraction\n" ); - Abc_Print( -2, "\t-S num : the starting time frame (0=unused) [default = %d]\n", pPars->nStart ); - Abc_Print( -2, "\t-F num : the max number of timeframes to unroll [default = %d]\n", pPars->nFramesMax ); - Abc_Print( -2, "\t-C num : the max number of SAT solver conflicts (0=unused) [default = %d]\n", pPars->nConfLimit ); - Abc_Print( -2, "\t-T num : an approximate timeout, in seconds [default = %d]\n", pPars->nTimeOut ); - Abc_Print( -2, "\t-r : toggle using random decisiont during SAT solving [default = %s]\n", !pPars->fSkipRand? "yes": "no" ); - Abc_Print( -2, "\t-n : toggle using on-the-fly proof-logging [default = %s]\n", fNewSolver? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} /**Function************************************************************* @@ -28327,9 +27869,9 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Gla( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Gia_ParVta_t Pars, * pPars = &Pars; + Abs_Par_t Pars, * pPars = &Pars; int c, fStartVta = 0, fNewAlgo = 1; - Gia_VtaSetDefaultParams( pPars ); + Abs_ParSetDefaults( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "FSCLDETRPBAtrfkadmnscbpqwvh" ) ) != EOF ) { @@ -28533,9 +28075,9 @@ int Abc_CommandAbc9Gla( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } if ( fNewAlgo ) - pAbc->Status = Ga2_ManPerform( pAbc->pGia, pPars ); + pAbc->Status = Gia_ManPerformGla( pAbc->pGia, pPars ); else - pAbc->Status = Gia_GlaPerform( pAbc->pGia, pPars, fStartVta ); + pAbc->Status = Gia_ManPerformGlaOld( pAbc->pGia, pPars, fStartVta ); pAbc->nFrames = pPars->iFrame; Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); return 0; @@ -28585,9 +28127,9 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Vta( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Gia_ParVta_t Pars, * pPars = &Pars; + Abs_Par_t Pars, * pPars = &Pars; int c; - Gia_VtaSetDefaultParams( pPars ); + Abs_ParSetDefaults( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "FSPCLDETRAtradvh" ) ) != EOF ) { diff --git a/src/base/io/io.c b/src/base/io/io.c index 55965642..aed809b3 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -21,6 +21,7 @@ #include "ioAbc.h" #include "base/main/mainInt.h" #include "aig/saig/saig.h" +#include "proof/abs/abs.h" ABC_NAMESPACE_IMPL_START diff --git a/src/opt/nwk/nwkAig.c b/src/opt/nwk/nwkAig.c index 55cff367..5b0aaf20 100644 --- a/src/opt/nwk/nwkAig.c +++ b/src/opt/nwk/nwkAig.c @@ -105,7 +105,7 @@ Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose -#include "aig/gia/gia.h" +#include "proof/abs/abs.h" /**Function************************************************************* diff --git a/src/proof/abs/abs.c b/src/proof/abs/abs.c new file mode 100644 index 00000000..3ba1abfb --- /dev/null +++ b/src/proof/abs/abs.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [abs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/abs.h b/src/proof/abs/abs.h new file mode 100644 index 00000000..eeeda583 --- /dev/null +++ b/src/proof/abs/abs.h @@ -0,0 +1,131 @@ +/**CFile**************************************************************** + + FileName [abs.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__proof_abs__Abs_h +#define ABC__proof_abs__Abs_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "aig/gia/giaAig.h" +#include "aig/saig/saig.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// abstraction parameters +typedef struct Abs_Par_t_ Abs_Par_t; +struct Abs_Par_t_ +{ + int nFramesMax; // maximum frames + int nFramesStart; // starting frame + int nFramesPast; // overlap frames + int nConfLimit; // conflict limit + int nLearnedMax; // max number of learned clauses + int nLearnedStart; // max number of learned clauses + int nLearnedDelta; // delta increase of learned clauses + int nLearnedPerce; // percentage of clauses to leave + int nTimeOut; // timeout in seconds + int nRatioMin; // stop when less than this % of object is abstracted + int nRatioMax; // restart when the number of abstracted object is more than this + int fUseTermVars; // use terminal variables + int fUseRollback; // use rollback to the starting number of frames + int fPropFanout; // propagate fanout implications + int fAddLayer; // refinement strategy by adding layers + int fUseSkip; // skip proving intermediate timeframes + int fUseSimple; // use simple CNF construction + int fSkipHash; // skip hashing CNF while unrolling + int fUseFullProof; // use full proof for UNSAT cores + int fDumpVabs; // dumps the abstracted model + int fDumpMabs; // dumps the original AIG with abstraction map + int fCallProver; // calls the prover + char * pFileVabs; // dumps the abstracted model into this file + int fVerbose; // verbose flag + int fVeryVerbose; // print additional information + int iFrame; // the number of frames covered + int iFrameProved; // the number of frames proved + int nFramesNoChange; // the number of last frames without changes + int nFramesNoChangeLim; // the number of last frames without changes to dump abstraction +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== abs.c =========================================================*/ +/*=== absDup.c =========================================================*/ +extern Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses ); +extern Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses ); +extern void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes ); +extern void Gia_ManPrintFlopClasses( Gia_Man_t * p ); +extern void Gia_ManPrintObjClasses( Gia_Man_t * p ); +extern void Gia_ManPrintGateClasses( Gia_Man_t * p ); +/*=== absGla.c =========================================================*/ +extern int Gia_ManPerformGla( Gia_Man_t * p, Abs_Par_t * pPars ); +/*=== absGlaOld.c =========================================================*/ +extern int Gia_ManPerformGlaOld( Gia_Man_t * p, Abs_Par_t * pPars, int fStartVta ); +/*=== absIter.c =========================================================*/ +extern Gia_Man_t * Gia_ManShrinkGla( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose ); +/*=== absVta.c =========================================================*/ +extern int Gia_VtaPerform( Gia_Man_t * pAig, Abs_Par_t * pPars ); +/*=== absUtil.c =========================================================*/ +extern void Abs_ParSetDefaults( Abs_Par_t * p ); +extern Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta ); +extern Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames ); +extern Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla ); +extern Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla ); +extern int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla ); +extern int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla ); + +/*=== absOldCex.c ==========================================================*/ +extern Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect ); +extern Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ); +/*=== absOldRef.c ==========================================================*/ +extern int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ); +/*=== absOldSat.c ==========================================================*/ +extern Vec_Int_t * Saig_ManExtendCounterExampleTest3( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ); +/*=== absOldSim.c ==========================================================*/ +extern Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); + + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/proof/abs/absDup.c b/src/proof/abs/absDup.c new file mode 100644 index 00000000..247137bd --- /dev/null +++ b/src/proof/abs/absDup.c @@ -0,0 +1,445 @@ +/**CFile**************************************************************** + + FileName [absDup.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Duplication procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absDup.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Duplicates the AIG manager recursively.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupAbsFlops_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Performs abstraction of the AIG to preserve the included flops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, nFlops = 0; + Gia_ManFillValue( p ); + // start the new manager + pNew = Gia_ManStart( 5000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + // create PIs + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // create additional PIs + Gia_ManForEachRo( p, pObj, i ) + if ( !Vec_IntEntry(vFlopClasses, i) ) + pObj->Value = Gia_ManAppendCi(pNew); + // create ROs + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_IntEntry(vFlopClasses, i) ) + pObj->Value = Gia_ManAppendCi(pNew); + // create POs + Gia_ManHashAlloc( pNew ); + Gia_ManForEachPo( p, pObj, i ) + { + Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + // create RIs + Gia_ManForEachRi( p, pObj, i ) + if ( Vec_IntEntry(vFlopClasses, i) ) + { + Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + nFlops++; + } + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, nFlops ); + // clean up + pNew = Gia_ManSeqCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns the array of neighbors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_GlaCollectAssigned( Gia_Man_t * p, Vec_Int_t * vGateClasses ) +{ + Vec_Int_t * vAssigned; + Gia_Obj_t * pObj; + int i, Entry; + vAssigned = Vec_IntAlloc( 1000 ); + Vec_IntForEachEntry( vGateClasses, Entry, i ) + { + if ( Entry == 0 ) + continue; + assert( Entry > 0 ); + pObj = Gia_ManObj( p, i ); + Vec_IntPush( vAssigned, Gia_ObjId(p, pObj) ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, pObj) ); + Vec_IntPush( vAssigned, Gia_ObjFaninId1p(p, pObj) ); + } + else if ( Gia_ObjIsRo(p, pObj) ) + Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, Gia_ObjRoToRi(p, pObj)) ); + else assert( Gia_ObjIsConst0(pObj) ); + } + Vec_IntUniqify( vAssigned ); + return vAssigned; +} + +/**Function************************************************************* + + Synopsis [Collects PIs and PPIs of the abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes ) +{ + Vec_Int_t * vAssigned; + Gia_Obj_t * pObj; + int i; + assert( Gia_ManPoNum(p) == 1 ); + assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) ); + // create included objects and their fanins + vAssigned = Gia_GlaCollectAssigned( p, vGateClasses ); + // create additional arrays + if ( pvPis ) *pvPis = Vec_IntAlloc( 100 ); + if ( pvPPis ) *pvPPis = Vec_IntAlloc( 100 ); + if ( pvFlops ) *pvFlops = Vec_IntAlloc( 100 ); + if ( pvNodes ) *pvNodes = Vec_IntAlloc( 1000 ); + Gia_ManForEachObjVec( vAssigned, p, pObj, i ) + { + if ( Gia_ObjIsPi(p, pObj) ) + { if ( pvPis ) Vec_IntPush( *pvPis, Gia_ObjId(p,pObj) ); } + else if ( !Vec_IntEntry(vGateClasses, Gia_ObjId(p,pObj)) ) + { if ( pvPPis ) Vec_IntPush( *pvPPis, Gia_ObjId(p,pObj) ); } + else if ( Gia_ObjIsRo(p, pObj) ) + { if ( pvFlops ) Vec_IntPush( *pvFlops, Gia_ObjId(p,pObj) ); } + else if ( Gia_ObjIsAnd(pObj) ) + { if ( pvNodes ) Vec_IntPush( *pvNodes, Gia_ObjId(p,pObj) ); } + else assert( Gia_ObjIsConst0(pObj) ); + } + Vec_IntFree( vAssigned ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG manager recursively.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupAbsGates_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Performs abstraction of the AIG to preserve the included gates.] + + Description [The array contains 1 for those objects (const, RO, AND) + that are included in the abstraction; 0, otherwise.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses ) +{ + Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes; + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pCopy; + int i;//, nFlops = 0; + assert( Gia_ManPoNum(p) == 1 ); + assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) ); + + // create additional arrays + Gia_ManGlaCollect( p, vGateClasses, &vPis, &vPPis, &vFlops, &vNodes ); + + // start the new manager + pNew = Gia_ManStart( 5000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + // create constant + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + // create PIs + Gia_ManForEachObjVec( vPis, p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // create additional PIs + Gia_ManForEachObjVec( vPPis, p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // create ROs + Gia_ManForEachObjVec( vFlops, p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // create internal nodes + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +// Gia_ManDupAbsGates_rec( pNew, pObj ); + // create PO + Gia_ManForEachPo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + // create RIs + Gia_ManForEachObjVec( vFlops, p, pObj, i ) + Gia_ObjRoToRi(p, pObj)->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ObjRoToRi(p, pObj)) ); + Gia_ManSetRegNum( pNew, Vec_IntSize(vFlops) ); + // clean up + pNew = Gia_ManSeqCleanup( pTemp = pNew ); + // transfer copy values: (p -> pTemp -> pNew) => (p -> pNew) + if ( Gia_ManObjNum(pTemp) != Gia_ManObjNum(pNew) ) + { +// printf( "Gia_ManDupAbsGates() Internal error: object mismatch.\n" ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( !~pObj->Value ) + continue; + assert( !Abc_LitIsCompl(pObj->Value) ); + pCopy = Gia_ObjCopy( pTemp, pObj ); + if ( !~pCopy->Value ) + { + Vec_IntWriteEntry( vGateClasses, i, 0 ); + pObj->Value = ~0; + continue; + } + assert( !Abc_LitIsCompl(pCopy->Value) ); + pObj->Value = pCopy->Value; + } + } + Gia_ManStop( pTemp ); + + Vec_IntFree( vPis ); + Vec_IntFree( vPPis ); + Vec_IntFree( vFlops ); + Vec_IntFree( vNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintFlopClasses( Gia_Man_t * p ) +{ + int Counter0, Counter1; + if ( p->vFlopClasses == NULL ) + return; + if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) ) + { + printf( "Gia_ManPrintFlopClasses(): The number of flop map entries differs from the number of flops.\n" ); + return; + } + Counter0 = Vec_IntCountEntry( p->vFlopClasses, 0 ); + Counter1 = Vec_IntCountEntry( p->vFlopClasses, 1 ); + printf( "Flop-level abstraction: Excluded FFs = %d Included FFs = %d (%.2f %%) ", + Counter0, Counter1, 100.0*Counter1/(Counter0 + Counter1 + 1) ); + if ( Counter0 + Counter1 < Gia_ManRegNum(p) ) + printf( "and there are other FF classes..." ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintGateClasses( Gia_Man_t * p ) +{ + Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes; + int nTotal; + if ( p->vGateClasses == NULL ) + return; + if ( Vec_IntSize(p->vGateClasses) != Gia_ManObjNum(p) ) + { + printf( "Gia_ManPrintGateClasses(): The number of flop map entries differs from the number of flops.\n" ); + return; + } + // create additional arrays + Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, &vFlops, &vNodes ); + nTotal = 1 + Vec_IntSize(vFlops) + Vec_IntSize(vNodes); + printf( "Gate-level abstraction: PI = %d PPI = %d FF = %d (%.2f %%) AND = %d (%.2f %%) Obj = %d (%.2f %%)\n", + Vec_IntSize(vPis), Vec_IntSize(vPPis), + Vec_IntSize(vFlops), 100.0*Vec_IntSize(vFlops)/(Gia_ManRegNum(p)+1), + Vec_IntSize(vNodes), 100.0*Vec_IntSize(vNodes)/(Gia_ManAndNum(p)+1), + nTotal, 100.0*nTotal /(Gia_ManRegNum(p)+Gia_ManAndNum(p)+1) ); + Vec_IntFree( vPis ); + Vec_IntFree( vPPis ); + Vec_IntFree( vFlops ); + Vec_IntFree( vNodes ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintObjClasses( Gia_Man_t * p ) +{ + Vec_Int_t * vSeens; // objects seen so far + Vec_Int_t * vAbs = p->vObjClasses; + int i, k, Entry, iStart, iStop = -1, nFrames; + int nObjBits, nObjMask, iObj, iFrame, nWords; + unsigned * pInfo; + int * pCountAll, * pCountUni; + if ( vAbs == NULL ) + return; + nFrames = Vec_IntEntry( vAbs, 0 ); + assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) ); + pCountAll = ABC_ALLOC( int, nFrames + 1 ); + pCountUni = ABC_ALLOC( int, nFrames + 1 ); + // start storage for seen objects + nWords = Abc_BitWordNum( nFrames ); + vSeens = Vec_IntStart( Gia_ManObjNum(p) * nWords ); + // get the bitmasks + nObjBits = Abc_Base2Log( Gia_ManObjNum(p) ); + nObjMask = (1 << nObjBits) - 1; + assert( Gia_ManObjNum(p) <= nObjMask ); + // print info about frames + printf( "Frame Core F0 F1 F2 F3 ...\n" ); + for ( i = 0; i < nFrames; i++ ) + { + iStart = Vec_IntEntry( vAbs, i+1 ); + iStop = Vec_IntEntry( vAbs, i+2 ); + memset( pCountAll, 0, sizeof(int) * (nFrames + 1) ); + memset( pCountUni, 0, sizeof(int) * (nFrames + 1) ); + Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop ) + { + iObj = (Entry & nObjMask); + iFrame = (Entry >> nObjBits); + pInfo = (unsigned *)Vec_IntEntryP( vSeens, nWords * iObj ); + if ( Abc_InfoHasBit(pInfo, iFrame) == 0 ) + { + Abc_InfoSetBit( pInfo, iFrame ); + pCountUni[iFrame+1]++; + pCountUni[0]++; + } + pCountAll[iFrame+1]++; + pCountAll[0]++; + } + assert( pCountAll[0] == (iStop - iStart) ); +// printf( "%5d%5d ", pCountAll[0], pCountUni[0] ); + printf( "%3d :", i ); + printf( "%7d", pCountAll[0] ); + if ( i >= 10 ) + { + for ( k = 0; k < 4; k++ ) + printf( "%5d", pCountAll[k+1] ); + printf( " ..." ); + for ( k = i-4; k <= i; k++ ) + printf( "%5d", pCountAll[k+1] ); + } + else + { + for ( k = 0; k <= i; k++ ) + if ( k <= i ) + printf( "%5d", pCountAll[k+1] ); + } +// for ( k = 0; k < nFrames; k++ ) +// if ( k <= i ) +// printf( "%5d", pCountAll[k+1] ); + printf( "\n" ); + } + assert( iStop == Vec_IntSize(vAbs) ); + Vec_IntFree( vSeens ); + ABC_FREE( pCountAll ); + ABC_FREE( pCountUni ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absGla.c b/src/proof/abs/absGla.c new file mode 100644 index 00000000..b026c6e3 --- /dev/null +++ b/src/proof/abs/absGla.c @@ -0,0 +1,1899 @@ +/**CFile**************************************************************** + + FileName [absGla2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Scalable gate-level abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absGla2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sat/cnf/cnf.h" +#include "sat/bsat/satSolver2.h" +#include "base/main/main.h" +#include "abs.h" +#include "absRef.h" +//#include "absRef2.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define GA2_BIG_NUM 0x3FFFFFF0 + +typedef struct Ga2_Man_t_ Ga2_Man_t; // manager +struct Ga2_Man_t_ +{ + // user data + Gia_Man_t * pGia; // working AIG manager + Abs_Par_t * pPars; // parameters + // markings + Vec_Ptr_t * vCnfs; // for each object: CNF0, CNF1 + // abstraction + Vec_Int_t * vIds; // abstraction ID for each GIA object + Vec_Int_t * vProofIds; // mapping of GIA objects into their proof IDs + Vec_Int_t * vAbs; // array of abstracted objects + Vec_Int_t * vValues; // array of objects with abstraction ID assigned + int nProofIds; // the counter of proof IDs + int LimAbs; // limit value for starting abstraction objects + int LimPpi; // limit value for starting PPI objects + int nMarked; // total number of marked nodes and flops + // refinement + Rnm_Man_t * pRnm; // refinement manager +// Rf2_Man_t * pRf2; // refinement manager + // SAT solver and variables + Vec_Ptr_t * vId2Lit; // mapping, for each timeframe, of object ID into SAT literal + sat_solver2 * pSat; // incremental SAT solver + int nSatVars; // the number of SAT variables + int nCexes; // the number of counter-examples + int nObjAdded; // objs added during refinement + // hash table + int * pTable; + int nTable; + int nHashHit; + int nHashMiss; + int nHashOver; + // temporaries + Vec_Int_t * vLits; + Vec_Int_t * vIsopMem; + char * pSopSizes, ** pSops; // CNF representation + // statistics + clock_t timeStart; + clock_t timeInit; + clock_t timeSat; + clock_t timeUnsat; + clock_t timeCex; + clock_t timeOther; +}; + +static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); } +static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); } +static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); } +static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); } +static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); } +static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; } + +static inline int Ga2_ObjId( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vIds, Gia_ObjId(p->pGia, pObj)); } +static inline void Ga2_ObjSetId( Ga2_Man_t * p, Gia_Obj_t * pObj, int i ) { Vec_IntWriteEntry(p->vIds, Gia_ObjId(p->pGia, pObj), i); } + +static inline Vec_Int_t * Ga2_ObjCnf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj) ); } +static inline Vec_Int_t * Ga2_ObjCnf1( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj)+1 ); } + +static inline int Ga2_ObjIsAbs0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < p->LimAbs; } +static inline int Ga2_ObjIsLeaf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= p->LimAbs && Ga2_ObjId(p,pObj) < p->LimPpi; } +static inline int Ga2_ObjIsAbs( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjCnf0(p,pObj); } +static inline int Ga2_ObjIsLeaf( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && !Ga2_ObjCnf0(p,pObj); } + +static inline Vec_Int_t * Ga2_MapFrameMap( Ga2_Man_t * p, int f ) { return (Vec_Int_t *)Vec_PtrEntry( p->vId2Lit, f ); } + +// returns literal of this object, or -1 if SAT variable of the object is not assigned +static inline int Ga2_ObjFindLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) +{ +// int Id = Ga2_ObjId(p,pObj); + assert( Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < Vec_IntSize(p->vValues) ); + return Vec_IntEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj) ); +} +// inserts literal of this object +static inline void Ga2_ObjAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int Lit ) +{ +// assert( Lit > 1 ); + assert( Ga2_ObjFindLit(p, pObj, f) == -1 ); + Vec_IntSetEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj), Lit ); +} +// returns or inserts-and-returns literal of this object +static inline int Ga2_ObjFindOrAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + int Lit = Ga2_ObjFindLit( p, pObj, f ); + if ( Lit == -1 ) + { + Lit = toLitCond( p->nSatVars++, 0 ); + Ga2_ObjAddLit( p, pObj, f, Lit ); + } +// assert( Lit > 1 ); + return Lit; +} + + +// calling pthreads +extern void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ); +extern void Gia_Ga2ProveCancel( int fVerbose ); +extern int Gia_Ga2ProveCheck( int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes truth table for the marked node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ga2_ObjComputeTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst ) +{ + unsigned Val0, Val1; + if ( pObj->fPhase && !fFirst ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Val0 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin0(pObj), 0 ); + Val1 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin1(pObj), 0 ); + return (Gia_ObjFaninC0(pObj) ? ~Val0 : Val0) & (Gia_ObjFaninC1(pObj) ? ~Val1 : Val1); +} +unsigned Ga2_ManComputeTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves ) +{ + static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + Gia_Obj_t * pObj; + unsigned Res; + int i; + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + pObj->Value = uTruth5[i]; + Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + pObj->Value = 0; + return Res; +} + +/**Function************************************************************* + + Synopsis [Returns AIG marked for CNF generation.] + + Description [The marking satisfies the following requirements: + Each marked node has the number of marked fanins no more than N.] + + SideEffects [Uses pObj->fPhase to store the markings.] + + SeeAlso [] + +***********************************************************************/ +int Ga2_ManBreakTree_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst, int N ) +{ // breaks a tree rooted at the node into N-feasible subtrees + int Val0, Val1; + if ( pObj->fPhase && !fFirst ) + return 1; + Val0 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin0(pObj), 0, N ); + Val1 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin1(pObj), 0, N ); + if ( Val0 + Val1 < N ) + return Val0 + Val1; + if ( Val0 + Val1 == N ) + { + pObj->fPhase = 1; + return 1; + } + assert( Val0 + Val1 > N ); + assert( Val0 < N && Val1 < N ); + if ( Val0 >= Val1 ) + { + Gia_ObjFanin0(pObj)->fPhase = 1; + Val0 = 1; + } + else + { + Gia_ObjFanin1(pObj)->fPhase = 1; + Val1 = 1; + } + if ( Val0 + Val1 < N ) + return Val0 + Val1; + if ( Val0 + Val1 == N ) + { + pObj->fPhase = 1; + return 1; + } + assert( 0 ); + return -1; +} +int Ga2_ManCheckNodesAnd( Gia_Man_t * p, Vec_Int_t * vNodes ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + if ( (!Gia_ObjFanin0(pObj)->fPhase && Gia_ObjFaninC0(pObj)) || + (!Gia_ObjFanin1(pObj)->fPhase && Gia_ObjFaninC1(pObj)) ) + return 0; + return 1; +} +void Ga2_ManCollectNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes, int fFirst ) +{ + if ( pObj->fPhase && !fFirst ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Ga2_ManCollectNodes_rec( p, Gia_ObjFanin0(pObj), vNodes, 0 ); + Ga2_ManCollectNodes_rec( p, Gia_ObjFanin1(pObj), vNodes, 0 ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + +} +void Ga2_ManCollectLeaves_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, int fFirst ) +{ + if ( pObj->fPhase && !fFirst ) + { + Vec_IntPushUnique( vLeaves, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin0(pObj), vLeaves, 0 ); + Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin1(pObj), vLeaves, 0 ); +} +int Ga2_ManMarkup( Gia_Man_t * p, int N, int fSimple ) +{ + static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; +// clock_t clk = clock(); + Vec_Int_t * vLeaves; + Gia_Obj_t * pObj; + int i, k, Leaf, CountMarks; + + vLeaves = Vec_IntAlloc( 100 ); + + if ( fSimple ) + { + Gia_ManForEachObj( p, pObj, i ) + pObj->fPhase = !Gia_ObjIsCo(pObj); + } + else + { + // label nodes with multiple fanouts and inputs MUXes + Gia_ManForEachObj( p, pObj, i ) + { + pObj->Value = 0; + if ( !Gia_ObjIsAnd(pObj) ) + continue; + Gia_ObjFanin0(pObj)->Value++; + Gia_ObjFanin1(pObj)->Value++; + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + Gia_ObjFanin0(Gia_ObjFanin0(pObj))->Value++; + Gia_ObjFanin1(Gia_ObjFanin0(pObj))->Value++; + Gia_ObjFanin0(Gia_ObjFanin1(pObj))->Value++; + Gia_ObjFanin1(Gia_ObjFanin1(pObj))->Value++; + } + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fPhase = 0; + if ( Gia_ObjIsAnd(pObj) ) + pObj->fPhase = (pObj->Value > 1); + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fPhase = 1; + else + pObj->fPhase = 1; + } + // add marks when needed + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !pObj->fPhase ) + continue; + Vec_IntClear( vLeaves ); + Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 ); + if ( Vec_IntSize(vLeaves) > N ) + Ga2_ManBreakTree_rec( p, pObj, 1, N ); + } + } + + // verify that the tree is split correctly + Vec_IntFreeP( &p->vMapping ); + p->vMapping = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManForEachRo( p, pObj, i ) + { + Gia_Obj_t * pObjRi = Gia_ObjRoToRi(p, pObj); + assert( pObj->fPhase ); + assert( Gia_ObjFanin0(pObjRi)->fPhase ); + // create map + Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); + Vec_IntPush( p->vMapping, 1 ); + Vec_IntPush( p->vMapping, Gia_ObjFaninId0p(p, pObjRi) ); + Vec_IntPush( p->vMapping, Gia_ObjFaninC0(pObjRi) ? 0x55555555 : 0xAAAAAAAA ); + Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter + } + CountMarks = Gia_ManRegNum(p); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !pObj->fPhase ) + continue; + Vec_IntClear( vLeaves ); + Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 ); + assert( Vec_IntSize(vLeaves) <= N ); + // create map + Vec_IntWriteEntry( p->vMapping, i, Vec_IntSize(p->vMapping) ); + Vec_IntPush( p->vMapping, Vec_IntSize(vLeaves) ); + Vec_IntForEachEntry( vLeaves, Leaf, k ) + { + Vec_IntPush( p->vMapping, Leaf ); + Gia_ManObj(p, Leaf)->Value = uTruth5[k]; + assert( Gia_ManObj(p, Leaf)->fPhase ); + } + Vec_IntPush( p->vMapping, (int)Ga2_ObjComputeTruth_rec( p, pObj, 1 ) ); + Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter + CountMarks++; + } +// Abc_PrintTime( 1, "Time", clock() - clk ); + Vec_IntFree( vLeaves ); + Gia_ManCleanValue( p ); + return CountMarks; +} +void Ga2_ManComputeTest( Gia_Man_t * p ) +{ + clock_t clk; +// unsigned uTruth; + Gia_Obj_t * pObj; + int i, Counter = 0; + clk = clock(); + Ga2_ManMarkup( p, 5, 0 ); + Abc_PrintTime( 1, "Time", clock() - clk ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !pObj->fPhase ) + continue; +// uTruth = Ga2_ObjTruth( p, pObj ); +// printf( "%6d : ", Counter ); +// Kit_DsdPrintFromTruth( &uTruth, Ga2_ObjLeaveNum(p, pObj) ); +// printf( "\n" ); + Counter++; + } + Abc_Print( 1, "Marked AND nodes = %6d. ", Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ga2_Man_t * Ga2_ManStart( Gia_Man_t * pGia, Abs_Par_t * pPars ) +{ + Ga2_Man_t * p; + p = ABC_CALLOC( Ga2_Man_t, 1 ); + p->timeStart = clock(); + // user data + p->pGia = pGia; + p->pPars = pPars; + // markings + p->nMarked = Ga2_ManMarkup( pGia, 5, pPars->fUseSimple ); + p->vCnfs = Vec_PtrAlloc( 1000 ); + Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) ); + Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) ); + // abstraction + p->vIds = Vec_IntStartFull( Gia_ManObjNum(pGia) ); + p->vProofIds = Vec_IntAlloc( 0 ); + p->vAbs = Vec_IntAlloc( 1000 ); + p->vValues = Vec_IntAlloc( 1000 ); + // add constant node to abstraction + Ga2_ObjSetId( p, Gia_ManConst0(pGia), 0 ); + Vec_IntPush( p->vValues, 0 ); + Vec_IntPush( p->vAbs, 0 ); + // refinement + p->pRnm = Rnm_ManStart( pGia ); +// p->pRf2 = Rf2_ManStart( pGia ); + // SAT solver and variables + p->vId2Lit = Vec_PtrAlloc( 1000 ); + // temporaries + p->vLits = Vec_IntAlloc( 100 ); + p->vIsopMem = Vec_IntAlloc( 100 ); + Cnf_ReadMsops( &p->pSopSizes, &p->pSops ); + // hash table + p->nTable = Abc_PrimeCudd(1<<18); + p->pTable = ABC_CALLOC( int, 6 * p->nTable ); + return p; +} + +void Ga2_ManDumpStats( Gia_Man_t * pGia, Abs_Par_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN ) +{ + FILE * pFile; + char pFileName[32]; + sprintf( pFileName, "stats_gla%s%s.txt", fUseN ? "n":"", pPars->fUseFullProof ? "p":"" ); + + pFile = fopen( pFileName, "a+" ); + + fprintf( pFile, "%s pi=%d ff=%d and=%d mem=%d bmc=%d", + pGia->pName, + Gia_ManPiNum(pGia), Gia_ManRegNum(pGia), Gia_ManAndNum(pGia), + (int)(1 + sat_solver2_memory_proof(pSat)/(1<<20)), + iFrame ); + + if ( pGia->vGateClasses ) + fprintf( pFile, " ff=%d and=%d", + Gia_GlaCountFlops( pGia, pGia->vGateClasses ), + Gia_GlaCountNodes( pGia, pGia->vGateClasses ) ); + + fprintf( pFile, "\n" ); + fclose( pFile ); +} +void Ga2_ManReportMemory( Ga2_Man_t * p ) +{ + double memTot = 0; + double memAig = 1.0 * p->pGia->nObjsAlloc * sizeof(Gia_Obj_t) + Vec_IntMemory(p->pGia->vMapping); + double memSat = sat_solver2_memory( p->pSat, 1 ); + double memPro = sat_solver2_memory_proof( p->pSat ); + double memMap = Vec_VecMemoryInt( (Vec_Vec_t *)p->vId2Lit ); + double memRef = Rnm_ManMemoryUsage( p->pRnm ); + double memHash= sizeof(int) * 6 * p->nTable; + double memOth = sizeof(Ga2_Man_t); + memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCnfs ); + memOth += Vec_IntMemory( p->vIds ); + memOth += Vec_IntMemory( p->vProofIds ); + memOth += Vec_IntMemory( p->vAbs ); + memOth += Vec_IntMemory( p->vValues ); + memOth += Vec_IntMemory( p->vLits ); + memOth += Vec_IntMemory( p->vIsopMem ); + memOth += 336450 + (sizeof(char) + sizeof(char*)) * 65536; + memTot = memAig + memSat + memPro + memMap + memRef + memHash + memOth; + ABC_PRMP( "Memory: AIG ", memAig, memTot ); + ABC_PRMP( "Memory: SAT ", memSat, memTot ); + ABC_PRMP( "Memory: Proof ", memPro, memTot ); + ABC_PRMP( "Memory: Map ", memMap, memTot ); + ABC_PRMP( "Memory: Refine ", memRef, memTot ); + ABC_PRMP( "Memory: Hash ", memHash,memTot ); + ABC_PRMP( "Memory: Other ", memOth, memTot ); + ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); +} +void Ga2_ManStop( Ga2_Man_t * p ) +{ + Vec_IntFreeP( &p->pGia->vMapping ); + Gia_ManSetPhase( p->pGia ); + if ( p->pPars->fVerbose ) + Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d ObjsAdded = %d\n", + sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), + sat_solver2_nconflicts(p->pSat), sat_solver2_nlearnts(p->pSat), + p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Hash hits = %d. Hash misses = %d. Hash overs = %d.\n", + p->nHashHit, p->nHashMiss, p->nHashOver ); + + if( p->pSat ) sat_solver2_delete( p->pSat ); + Vec_VecFree( (Vec_Vec_t *)p->vCnfs ); + Vec_VecFree( (Vec_Vec_t *)p->vId2Lit ); + Vec_IntFree( p->vIds ); + Vec_IntFree( p->vProofIds ); + Vec_IntFree( p->vAbs ); + Vec_IntFree( p->vValues ); + Vec_IntFree( p->vLits ); + Vec_IntFree( p->vIsopMem ); + Rnm_ManStop( p->pRnm, 0 ); +// Rf2_ManStop( p->pRf2, p->pPars->fVerbose ); + ABC_FREE( p->pTable ); + ABC_FREE( p->pSopSizes ); + ABC_FREE( p->pSops[1] ); + ABC_FREE( p->pSops ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Computes a minimized truth table.] + + Description [Input literals can be 0/1 (const 0/1), non-trivial literals + (integers that are more than 1) and unassigned literals (large integers). + This procedure computes the truth table that essentially depends on input + variables ordered in the increasing order of their positive literals.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Ga2_ObjTruthDepends( unsigned t, int v ) +{ + static unsigned uInvTruth5[5] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF }; + assert( v >= 0 && v <= 4 ); + return ((t ^ (t >> (1 << v))) & uInvTruth5[v]); +} +unsigned Ga2_ObjComputeTruthSpecial( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vLits ) +{ + int fVerbose = 0; + static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + unsigned Res; + Gia_Obj_t * pObj; + int i, Entry; +// int Id = Gia_ObjId(p, pRoot); + assert( Gia_ObjIsAnd(pRoot) ); + + if ( fVerbose ) + printf( "Object %d.\n", Gia_ObjId(p, pRoot) ); + + // assign elementary truth tables + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + { + Entry = Vec_IntEntry( vLits, i ); + assert( Entry >= 0 ); + if ( Entry == 0 ) + pObj->Value = 0; + else if ( Entry == 1 ) + pObj->Value = ~0; + else // non-trivial literal + pObj->Value = uTruth5[i]; + if ( fVerbose ) + printf( "%d ", Entry ); + } + + if ( fVerbose ) + { + Res = Ga2_ObjTruth( p, pRoot ); +// Kit_DsdPrintFromTruth( &Res, Vec_IntSize(vLeaves) ); + printf( "\n" ); + } + + // compute truth table + Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); + if ( Res != 0 && Res != ~0 ) + { + // find essential variables + int nUsed = 0, pUsed[5]; + for ( i = 0; i < Vec_IntSize(vLeaves); i++ ) + if ( Ga2_ObjTruthDepends( Res, i ) ) + pUsed[nUsed++] = i; + assert( nUsed > 0 ); + // order positions by literal value + Vec_IntSelectSortCost( pUsed, nUsed, vLits ); + assert( Vec_IntEntry(vLits, pUsed[0]) <= Vec_IntEntry(vLits, pUsed[nUsed-1]) ); + // assign elementary truth tables to the leaves + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + { + Entry = Vec_IntEntry( vLits, i ); + assert( Entry >= 0 ); + if ( Entry == 0 ) + pObj->Value = 0; + else if ( Entry == 1 ) + pObj->Value = ~0; + else // non-trivial literal + pObj->Value = 0xDEADCAFE; // not important + } + for ( i = 0; i < nUsed; i++ ) + { + Entry = Vec_IntEntry( vLits, pUsed[i] ); + assert( Entry > 1 ); + pObj = Gia_ManObj( p, Vec_IntEntry(vLeaves, pUsed[i]) ); + pObj->Value = Abc_LitIsCompl(Entry) ? ~uTruth5[i] : uTruth5[i]; +// pObj->Value = uTruth5[i]; + // remember this literal + pUsed[i] = Abc_LitRegular(Entry); +// pUsed[i] = Entry; + } + // compute truth table + Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 ); + // reload the literals + Vec_IntClear( vLits ); + for ( i = 0; i < nUsed; i++ ) + { + Vec_IntPush( vLits, pUsed[i] ); + assert( Ga2_ObjTruthDepends(Res, i) ); + if ( fVerbose ) + printf( "%d ", pUsed[i] ); + } + for ( ; i < 5; i++ ) + assert( !Ga2_ObjTruthDepends(Res, i) ); + +if ( fVerbose ) +{ +// Kit_DsdPrintFromTruth( &Res, nUsed ); + printf( "\n" ); +} + + } + else + { + +if ( fVerbose ) +{ + Vec_IntClear( vLits ); + printf( "Const %d\n", Res > 0 ); +} + + } + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + pObj->Value = 0; + return Res; +} + +/**Function************************************************************* + + Synopsis [Returns CNF of the function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover ) +{ + extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ); + int RetValue; + assert( nVars <= 5 ); + // transform truth table into the SOP + RetValue = Kit_TruthIsop( &uTruth, nVars, vCover, 0 ); + assert( RetValue == 0 ); + // check the case of constant cover + return Vec_IntDup( vCover ); +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Ga2_ManCnfAddDynamic( Ga2_Man_t * p, int uTruth, int Lits[], int iLitOut, int ProofId ) +{ + int i, k, b, Cube, nClaLits, ClaLits[6]; +// assert( uTruth > 0 && uTruth < 0xffff ); + for ( i = 0; i < 2; i++ ) + { + if ( i ) + uTruth = 0xffff & ~uTruth; +// Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); + for ( k = 0; k < p->pSopSizes[uTruth]; k++ ) + { + nClaLits = 0; + ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut; + Cube = p->pSops[uTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( Cube % 3 == 0 ) // value 0 --> add positive literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = Lits[b]; + } + else if ( Cube % 3 == 1 ) // value 1 --> add negative literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = lit_neg(Lits[b]); + } + Cube = Cube / 3; + } + sat_solver2_addclause( p->pSat, ClaLits, ClaLits+nClaLits, ProofId ); + } + } +} +void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int Lits[], int iLitOut, int ProofId ) +{ + Vec_Int_t * vCnf; + int i, k, b, Cube, Literal, nClaLits, ClaLits[6]; + for ( i = 0; i < 2; i++ ) + { + vCnf = i ? vCnf1 : vCnf0; + Vec_IntForEachEntry( vCnf, Cube, k ) + { + nClaLits = 0; + ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut; + for ( b = 0; b < 5; b++ ) + { + Literal = 3 & (Cube >> (b << 1)); + if ( Literal == 1 ) // value 0 --> add positive literal + { +// assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = Lits[b]; + } + else if ( Literal == 2 ) // value 1 --> add negative literal + { +// assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = lit_neg(Lits[b]); + } + else if ( Literal != 0 ) + assert( 0 ); + } + sat_solver2_addclause( pSat, ClaLits, ClaLits+nClaLits, ProofId ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Saig_ManBmcHashKey( int * pArray ) +{ + static int s_Primes[5] = { 12582917, 25165843, 50331653, 100663319, 201326611 }; + unsigned i, Key = 0; + for ( i = 0; i < 5; i++ ) + Key += pArray[i] * s_Primes[i]; + return Key; +} +static inline int * Saig_ManBmcLookup( Ga2_Man_t * p, int * pArray ) +{ + int * pTable = p->pTable + 6 * (Saig_ManBmcHashKey(pArray) % p->nTable); + if ( memcmp( pTable, pArray, 20 ) ) + { + if ( pTable[0] == 0 ) + p->nHashMiss++; + else + p->nHashOver++; + memcpy( pTable, pArray, 20 ); + pTable[5] = 0; + } + else + p->nHashHit++; + assert( pTable + 5 < pTable + 6 * p->nTable ); + return pTable + 5; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Ga2_ManSetupNode( Ga2_Man_t * p, Gia_Obj_t * pObj, int fAbs ) +{ + unsigned uTruth; + int nLeaves; +// int Id = Gia_ObjId(p->pGia, pObj); + assert( pObj->fPhase ); + assert( Vec_PtrSize(p->vCnfs) == 2 * Vec_IntSize(p->vValues) ); + // assign abstraction ID to the node + if ( Ga2_ObjId(p,pObj) == -1 ) + { + Ga2_ObjSetId( p, pObj, Vec_IntSize(p->vValues) ); + Vec_IntPush( p->vValues, Gia_ObjId(p->pGia, pObj) ); + Vec_PtrPush( p->vCnfs, NULL ); + Vec_PtrPush( p->vCnfs, NULL ); + } + assert( Ga2_ObjCnf0(p, pObj) == NULL ); + if ( !fAbs ) + return; + Vec_IntPush( p->vAbs, Gia_ObjId(p->pGia, pObj) ); + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); + // compute parameters + nLeaves = Ga2_ObjLeaveNum(p->pGia, pObj); + uTruth = Ga2_ObjTruth( p->pGia, pObj ); + // create CNF for pos/neg phases + Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), Ga2_ManCnfCompute( uTruth, nLeaves, p->vIsopMem) ); + Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, Ga2_ManCnfCompute(~uTruth, nLeaves, p->vIsopMem) ); +} + +static inline void Ga2_ManAddToAbsOneStatic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int fUseId ) +{ + Vec_Int_t * vLeaves; + Gia_Obj_t * pLeaf; + int k, Lit, iLitOut = Ga2_ObjFindOrAddLit( p, pObj, f ); + assert( iLitOut > 1 ); + assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); + if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) ) + { + iLitOut = Abc_LitNot( iLitOut ); + sat_solver2_addclause( p->pSat, &iLitOut, &iLitOut + 1, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 ); + } + else + { + int fUseStatic = 1; + Vec_IntClear( p->vLits ); + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, k ) + { + Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f - Gia_ObjIsRo(p->pGia, pObj) ); + Vec_IntPush( p->vLits, Lit ); + if ( Lit < 2 ) + fUseStatic = 0; + } + if ( fUseStatic || Gia_ObjIsRo(p->pGia, pObj) ) + Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), iLitOut, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 ); + else + { + unsigned uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits ); + Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), iLitOut, Gia_ObjId(p->pGia, pObj) ); + } + } +} +static inline void Ga2_ManAddToAbsOneDynamic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) +{ +// int Id = Gia_ObjId(p->pGia, pObj); + Vec_Int_t * vLeaves; + Gia_Obj_t * pLeaf; + unsigned uTruth; + int i, Lit; + + assert( Ga2_ObjIsAbs0(p, pObj) ); + assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); + if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) ) + { + Ga2_ObjAddLit( p, pObj, f, 0 ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + // if flop is included in the abstraction, but its driver is not + // flop input driver has no variable assigned -- we assign it here + pLeaf = Gia_ObjRoToRi( p->pGia, pObj ); + Lit = Ga2_ObjFindOrAddLit( p, Gia_ObjFanin0(pLeaf), f-1 ); + assert( Lit >= 0 ); + Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(pLeaf) ); + Ga2_ObjAddLit( p, pObj, f, Lit ); + } + else + { + assert( Gia_ObjIsAnd(pObj) ); + Vec_IntClear( p->vLits ); + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i ) + { + if ( Ga2_ObjIsAbs0(p, pLeaf) ) // belongs to original abstraction + { + Lit = Ga2_ObjFindLit( p, pLeaf, f ); + assert( Lit >= 0 ); + } + else if ( Ga2_ObjIsLeaf0(p, pLeaf) ) // belongs to original PPIs + { + Lit = Ga2_ObjFindLit( p, pLeaf, f ); +// Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); + if ( Lit == -1 ) + { + Lit = GA2_BIG_NUM + 2*i; +// assert( 0 ); + } + } + else assert( 0 ); + Vec_IntPush( p->vLits, Lit ); + } + + // minimize truth table + uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits ); + if ( uTruth == 0 || uTruth == ~0 ) // const 0 / 1 + { + Lit = (uTruth > 0); + Ga2_ObjAddLit( p, pObj, f, Lit ); + } + else if ( uTruth == 0xAAAAAAAA || uTruth == 0x55555555 ) // buffer / inverter + { + Lit = Vec_IntEntry( p->vLits, 0 ); + if ( Lit >= GA2_BIG_NUM ) + { + pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) ); + Lit = Ga2_ObjFindLit( p, pLeaf, f ); + assert( Lit == -1 ); + Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); + } + assert( Lit >= 0 ); + Lit = Abc_LitNotCond( Lit, uTruth == 0x55555555 ); + Ga2_ObjAddLit( p, pObj, f, Lit ); + assert( Lit < 10000000 ); + } + else + { + assert( Vec_IntSize(p->vLits) > 1 && Vec_IntSize(p->vLits) < 6 ); + // replace literals + Vec_IntForEachEntry( p->vLits, Lit, i ) + { + if ( Lit >= GA2_BIG_NUM ) + { + pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) ); + Lit = Ga2_ObjFindLit( p, pLeaf, f ); + assert( Lit == -1 ); + Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f ); + Vec_IntWriteEntry( p->vLits, i, Lit ); + } + assert( Lit < 10000000 ); + } + + // add new nodes + if ( Vec_IntSize(p->vLits) == 5 ) + { + Vec_IntClear( p->vLits ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i ) + Vec_IntPush( p->vLits, Ga2_ObjFindOrAddLit( p, pLeaf, f ) ); + Lit = Ga2_ObjFindOrAddLit(p, pObj, f); + Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), Lit, -1 ); + } + else + { +// int fUseHash = 1; + if ( !p->pPars->fSkipHash ) + { + int * pLookup, nSize = Vec_IntSize(p->vLits); + assert( Vec_IntSize(p->vLits) < 5 ); + assert( Vec_IntEntry(p->vLits, 0) <= Vec_IntEntryLast(p->vLits) ); + assert( Ga2_ObjFindLit(p, pObj, f) == -1 ); + for ( i = Vec_IntSize(p->vLits); i < 4; i++ ) + Vec_IntPush( p->vLits, GA2_BIG_NUM ); + Vec_IntPush( p->vLits, (int)uTruth ); + assert( Vec_IntSize(p->vLits) == 5 ); + + // perform structural hashing here!!! + pLookup = Saig_ManBmcLookup( p, Vec_IntArray(p->vLits) ); + if ( *pLookup == 0 ) + { + *pLookup = Ga2_ObjFindOrAddLit(p, pObj, f); + Vec_IntShrink( p->vLits, nSize ); + Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), *pLookup, -1 ); + } + else + Ga2_ObjAddLit( p, pObj, f, *pLookup ); + + } + else + { + Lit = Ga2_ObjFindOrAddLit(p, pObj, f); + Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), Lit, -1 ); + } + } + } + } +} + +void Ga2_ManAddAbsClauses( Ga2_Man_t * p, int f ) +{ + int fSimple = 0; + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) + { + if ( i == p->LimAbs ) + break; + if ( fSimple ) + Ga2_ManAddToAbsOneStatic( p, pObj, f, 0 ); + else + Ga2_ManAddToAbsOneDynamic( p, pObj, f ); + } + Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) + if ( i >= p->LimAbs ) + Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 ); +// sat_solver2_simplify( p->pSat ); +} + +void Ga2_ManAddToAbs( Ga2_Man_t * p, Vec_Int_t * vToAdd ) +{ + Vec_Int_t * vLeaves; + Gia_Obj_t * pObj, * pFanin; + int f, i, k; + // add abstraction objects + Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) + { + Ga2_ManSetupNode( p, pObj, 1 ); + if ( p->pSat->pPrf2 ) + Vec_IntWriteEntry( p->vProofIds, Gia_ObjId(p->pGia, pObj), p->nProofIds++ ); + } + // add PPI objects + Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) + { + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + if ( Ga2_ObjId( p, pFanin ) == -1 ) + Ga2_ManSetupNode( p, pFanin, 0 ); + } + // add new clauses to the timeframes + for ( f = 0; f <= p->pPars->iFrame; f++ ) + { + Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 ); + Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i ) + Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 ); + } +// sat_solver2_simplify( p->pSat ); +} + +void Ga2_ManShrinkAbs( Ga2_Man_t * p, int nAbs, int nValues, int nSatVars ) +{ + Vec_Int_t * vMap; + Gia_Obj_t * pObj; + int i, k, Entry; + assert( nAbs > 0 ); + assert( nValues > 0 ); + assert( nSatVars > 0 ); + // shrink abstraction + Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) + { + if ( !i ) continue; + assert( Ga2_ObjCnf0(p, pObj) != NULL ); + assert( Ga2_ObjCnf1(p, pObj) != NULL ); + if ( i < nAbs ) + continue; + Vec_IntFree( Ga2_ObjCnf0(p, pObj) ); + Vec_IntFree( Ga2_ObjCnf1(p, pObj) ); + Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), NULL ); + Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, NULL ); + } + Vec_IntShrink( p->vAbs, nAbs ); + // shrink values + Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) + { + assert( Ga2_ObjId(p,pObj) >= 0 ); + if ( i < nValues ) + continue; + Ga2_ObjSetId( p, pObj, -1 ); + } + Vec_IntShrink( p->vValues, nValues ); + Vec_PtrShrink( p->vCnfs, 2 * nValues ); + // hack to clear constant + if ( nValues == 1 ) + nValues = 0; + // clean mapping for each timeframe + Vec_PtrForEachEntry( Vec_Int_t *, p->vId2Lit, vMap, i ) + { + Vec_IntShrink( vMap, nValues ); + Vec_IntForEachEntryStart( vMap, Entry, k, p->LimAbs ) + if ( Entry >= 2*nSatVars ) + Vec_IntWriteEntry( vMap, k, -1 ); + } + // shrink SAT variables + p->nSatVars = nSatVars; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ga2_ManAbsTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vClasses, int fFirst ) +{ + if ( pObj->fPhase && !fFirst ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin0(pObj), vClasses, 0 ); + Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin1(pObj), vClasses, 0 ); + Vec_IntWriteEntry( vClasses, Gia_ObjId(p, pObj), 1 ); +} + +Vec_Int_t * Ga2_ManAbsTranslate( Ga2_Man_t * p ) +{ + Vec_Int_t * vGateClasses; + Gia_Obj_t * pObj; + int i; + vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) ); + Vec_IntWriteEntry( vGateClasses, 0, 1 ); + Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Ga2_ManAbsTranslate_rec( p->pGia, pObj, vGateClasses, 1 ); + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + Vec_IntWriteEntry( vGateClasses, Gia_ObjId(p->pGia, pObj), 1 ); + else if ( !Gia_ObjIsConst0(pObj) ) + assert( 0 ); +// Gia_ObjPrint( p->pGia, pObj ); + } + return vGateClasses; +} + +Vec_Int_t * Ga2_ManAbsDerive( Gia_Man_t * p ) +{ + Vec_Int_t * vToAdd; + Gia_Obj_t * pObj; + int i; + vToAdd = Vec_IntAlloc( 1000 ); + Gia_ManForEachRo( p, pObj, i ) + if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)) ) + Vec_IntPush( vToAdd, Gia_ObjId(p, pObj) ); + Gia_ManForEachAnd( p, pObj, i ) + if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, i) ) + Vec_IntPush( vToAdd, i ); + return vToAdd; +} + +void Ga2_ManRestart( Ga2_Man_t * p ) +{ + Vec_Int_t * vToAdd; + int Lit = 1; + assert( p->pGia != NULL && p->pGia->vGateClasses != NULL ); + assert( Gia_ManPi(p->pGia, 0)->fPhase ); // marks are set + // clear SAT variable numbers (begin with 1) + if ( p->pSat ) sat_solver2_delete( p->pSat ); + p->pSat = sat_solver2_new(); + p->pSat->nLearntStart = p->pPars->nLearnedStart; + p->pSat->nLearntDelta = p->pPars->nLearnedDelta; + p->pSat->nLearntRatio = p->pPars->nLearnedPerce; + p->pSat->nLearntMax = p->pSat->nLearntStart; + // add clause x0 = 0 (lit0 = 1; lit1 = 0) + sat_solver2_addclause( p->pSat, &Lit, &Lit + 1, -1 ); + // remove previous abstraction + Ga2_ManShrinkAbs( p, 1, 1, 1 ); + // start new abstraction + vToAdd = Ga2_ManAbsDerive( p->pGia ); + assert( p->pSat->pPrf2 == NULL ); + assert( p->pPars->iFrame < 0 ); + Ga2_ManAddToAbs( p, vToAdd ); + Vec_IntFree( vToAdd ); + p->LimAbs = Vec_IntSize(p->vAbs); + p->LimPpi = Vec_IntSize(p->vValues); + // set runtime limit + if ( p->pPars->nTimeOut ) + sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + p->timeStart ); + // clean the hash table + memset( p->pTable, 0, 6 * sizeof(int) * p->nTable ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vec_IntCheckUnique( Vec_Int_t * p ) +{ + int RetValue; + Vec_Int_t * pDup = Vec_IntDup( p ); + Vec_IntUniqify( pDup ); + RetValue = Vec_IntSize(p) - Vec_IntSize(pDup); + Vec_IntFree( pDup ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ga2_ObjSatValue( Ga2_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + int Lit = Ga2_ObjFindLit( p, pObj, f ); + assert( !Gia_ObjIsConst0(pObj) ); + if ( Lit == -1 ) + return 0; + if ( Abc_Lit2Var(Lit) >= p->pSat->size ) + return 0; + return Abc_LitIsCompl(Lit) ^ sat_solver2_var_value( p->pSat, Abc_Lit2Var(Lit) ); +} +Abc_Cex_t * Ga2_ManDeriveCex( Ga2_Man_t * p, Vec_Int_t * vPis ) +{ + Abc_Cex_t * pCex; + Gia_Obj_t * pObj; + int i, f; + pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); + pCex->iPo = 0; + pCex->iFrame = p->pPars->iFrame; + Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) + { + if ( !Gia_ObjIsPi(p->pGia, pObj) ) + continue; + assert( Gia_ObjIsPi(p->pGia, pObj) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + if ( Ga2_ObjSatValue( p, pObj, f ) ) + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) ); + } + return pCex; +} +void Ga2_ManRefinePrint( Ga2_Man_t * p, Vec_Int_t * vVec ) +{ + Gia_Obj_t * pObj, * pFanin; + int i, k; + printf( "\n Unsat core: \n" ); + Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) + { + Vec_Int_t * vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + printf( "%12d : ", i ); + printf( "Obj =%6d ", Gia_ObjId(p->pGia, pObj) ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + printf( "ff " ); + else + printf( " " ); + if ( Ga2_ObjIsAbs0(p, pObj) ) + printf( "a " ); + else if ( Ga2_ObjIsLeaf0(p, pObj) ) + printf( "l " ); + else + printf( " " ); + printf( "Fanins: " ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + { + printf( "%6d ", Gia_ObjId(p->pGia, pFanin) ); + if ( Gia_ObjIsRo(p->pGia, pFanin) ) + printf( "ff " ); + else + printf( " " ); + if ( Ga2_ObjIsAbs0(p, pFanin) ) + printf( "a " ); + else if ( Ga2_ObjIsLeaf0(p, pFanin) ) + printf( "l " ); + else + printf( " " ); + } + printf( "\n" ); + } +} +void Ga2_ManRefinePrintPPis( Ga2_Man_t * p ) +{ + Vec_Int_t * vVec = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) + { + if ( !i ) continue; + if ( Ga2_ObjIsAbs(p, pObj) ) + continue; + assert( pObj->fPhase ); + assert( Ga2_ObjIsLeaf(p, pObj) ); + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); + Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) ); + } + printf( " Current PPIs (%d): ", Vec_IntSize(vVec) ); + Vec_IntSort( vVec, 1 ); + Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) + printf( "%d ", Gia_ObjId(p->pGia, pObj) ); + printf( "\n" ); + Vec_IntFree( vVec ); +} + + +void Ga2_GlaPrepareCexAndMap( Ga2_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMaps ) +{ + Abc_Cex_t * pCex; + Vec_Int_t * vMap; + Gia_Obj_t * pObj; + int f, i, k; +/* + Gia_ManForEachObj( p->pGia, pObj, i ) + if ( Ga2_ObjId(p, pObj) >= 0 ) + assert( Vec_IntEntry(p->vValues, Ga2_ObjId(p, pObj)) == i ); +*/ + // find PIs and PPIs + vMap = Vec_IntAlloc( 1000 ); + Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) + { + if ( !i ) continue; + if ( Ga2_ObjIsAbs(p, pObj) ) + continue; + assert( pObj->fPhase ); + assert( Ga2_ObjIsLeaf(p, pObj) ); + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); + Vec_IntPush( vMap, Gia_ObjId(p->pGia, pObj) ); + } + // derive counter-example + pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 ); + pCex->iFrame = p->pPars->iFrame; + for ( f = 0; f <= p->pPars->iFrame; f++ ) + Gia_ManForEachObjVec( vMap, p->pGia, pObj, k ) + if ( Ga2_ObjSatValue( p, pObj, f ) ) + Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k ); + *pvMaps = vMap; + *ppCex = pCex; +} +Vec_Int_t * Ga2_ManRefine( Ga2_Man_t * p ) +{ + Abc_Cex_t * pCex; + Vec_Int_t * vMap, * vVec; + Gia_Obj_t * pObj; + int i, k; + if ( p->pPars->fAddLayer ) + { + // use simplified refinement strategy, which adds logic near at PPI without finding important ones + vVec = Vec_IntAlloc( 100 ); + Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i ) + { + if ( !i ) continue; + if ( Ga2_ObjIsAbs(p, pObj) ) + continue; + assert( pObj->fPhase ); + assert( Ga2_ObjIsLeaf(p, pObj) ); + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) ); + if ( Gia_ObjIsPi(p->pGia, pObj) ) + continue; + Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) ); + } + p->nObjAdded += Vec_IntSize(vVec); + return vVec; + } + Ga2_GlaPrepareCexAndMap( p, &pCex, &vMap ); + // Rf2_ManRefine( p->pRf2, pCex, vMap, p->pPars->fPropFanout, 1 ); + vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 1, 1 ); +// printf( "Refinement %d\n", Vec_IntSize(vVec) ); + Abc_CexFree( pCex ); + if ( Vec_IntSize(vVec) == 0 ) + { + Vec_IntFree( vVec ); + Abc_CexFreeP( &p->pGia->pCexSeq ); + p->pGia->pCexSeq = Ga2_ManDeriveCex( p, vMap ); + Vec_IntFree( vMap ); + return NULL; + } + Vec_IntFree( vMap ); + // remove those already added + k = 0; + Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) + if ( !Ga2_ObjIsAbs(p, pObj) ) + Vec_IntWriteEntry( vVec, k++, Gia_ObjId(p->pGia, pObj) ); + Vec_IntShrink( vVec, k ); + + // these objects should be PPIs that are not abstracted yet + Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) + assert( pObj->fPhase );//&& Ga2_ObjIsLeaf(p, pObj) ); + p->nObjAdded += Vec_IntSize(vVec); + return vVec; +} + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ga2_GlaAbsCount( Ga2_Man_t * p, int fRo, int fAnd ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( fRo ) + Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) + Counter += Gia_ObjIsRo(p->pGia, pObj); + else if ( fAnd ) + Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i ) + Counter += Gia_ObjIsAnd(pObj); + else assert( 0 ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ga2_ManAbsPrintFrame( Ga2_Man_t * p, int nFrames, int nConfls, int nCexes, clock_t Time, int fFinal ) +{ + if ( Abc_FrameIsBatchMode() && !(((fFinal && nCexes) || p->pPars->fVeryVerbose)) ) + return; + Abc_Print( 1, "%4d :", nFrames ); + Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Vec_IntSize(p->vAbs) / p->nMarked) ); + Abc_Print( 1, "%6d", Vec_IntSize(p->vAbs) ); + Abc_Print( 1, "%5d", Vec_IntSize(p->vValues)-Vec_IntSize(p->vAbs)-1 ); + Abc_Print( 1, "%5d", Ga2_GlaAbsCount(p, 1, 0) ); + Abc_Print( 1, "%6d", Ga2_GlaAbsCount(p, 0, 1) ); + Abc_Print( 1, "%8d", nConfls ); + if ( nCexes == 0 ) + Abc_Print( 1, "%5c", '-' ); + else + Abc_Print( 1, "%5d", nCexes ); + Abc_PrintInt( sat_solver2_nvars(p->pSat) ); + Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); + Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); + Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); + Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) ); + Abc_Print( 1, "%s", ((fFinal && nCexes) || p->pPars->fVeryVerbose) ? "\n" : "\r" ); + fflush( stdout ); +} + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Ga2_GlaGetFileName( Ga2_Man_t * p, int fAbs ) +{ + static char * pFileNameDef = "glabs.aig"; + if ( p->pPars->pFileVabs ) + return p->pPars->pFileVabs; + if ( p->pGia->pSpec ) + { + if ( fAbs ) + return Extra_FileNameGenericAppend( p->pGia->pSpec, "_abs.aig"); + else + return Extra_FileNameGenericAppend( p->pGia->pSpec, "_gla.aig"); + } + return pFileNameDef; +} + +void Ga2_GlaDumpAbsracted( Ga2_Man_t * p, int fVerbose ) +{ + char * pFileName; + assert( p->pPars->fDumpMabs || p->pPars->fDumpVabs || p->pPars->fCallProver ); + if ( p->pPars->fDumpMabs ) + { + pFileName = Ga2_GlaGetFileName(p, 0); +// if ( fVerbose ) +// Abc_Print( 1, "Dumping miter with abstraction map into file \"%s\"...\n", pFileName ); + // dump abstraction map + Vec_IntFreeP( &p->pGia->vGateClasses ); + p->pGia->vGateClasses = Ga2_ManAbsTranslate( p ); + Gia_WriteAiger( p->pGia, pFileName, 0, 0 ); + } + if ( p->pPars->fDumpVabs || p->pPars->fCallProver ) + { + Vec_Int_t * vGateClasses; + Gia_Man_t * pAbs; + pFileName = Ga2_GlaGetFileName(p, 1); +// if ( fVerbose ) +// Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); + // dump absracted model + vGateClasses = Ga2_ManAbsTranslate( p ); + pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses ); + Gia_ManCleanValue( p->pGia ); + Gia_WriteAiger( pAbs, pFileName, 0, 0 ); + Gia_ManStop( pAbs ); + Vec_IntFreeP( &vGateClasses ); + } +} + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_Ga2SendAbsracted( Ga2_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); + Gia_Man_t * pAbs; + Vec_Int_t * vGateClasses; + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Sending abstracted model...\n" ); + // create abstraction (value of p->pGia is not used here) + vGateClasses = Ga2_ManAbsTranslate( p ); + pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses ); + Vec_IntFreeP( &vGateClasses ); + Gia_ManCleanValue( p->pGia ); + // send it out + Gia_ManToBridgeAbsNetlist( stdout, pAbs ); + Gia_ManStop( pAbs ); +} +void Gia_Ga2SendCancel( Ga2_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeBadAbs( FILE * pFile ); + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Cancelling previously sent model...\n" ); + Gia_ManToBridgeBadAbs( stdout ); +} + +/**Function************************************************************* + + Synopsis [Performs gate-level abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManPerformGla( Gia_Man_t * pAig, Abs_Par_t * pPars ) +{ + int fUseSecondCore = 1; + Ga2_Man_t * p; + Vec_Int_t * vCore, * vPPis; + clock_t clk2, clk = clock(); + int Status = l_Undef, RetValue = -1, iFrameTryToProve = -1, fOneIsSent = 0; + int i, c, f, Lit; + // check trivial case + assert( Gia_ManPoNum(pAig) == 1 ); + ABC_FREE( pAig->pCexSeq ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) + { + if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) + { + Abc_Print( 1, "Sequential miter is trivially UNSAT.\n" ); + return 1; + } + pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); + Abc_Print( 1, "Sequential miter is trivially SAT.\n" ); + return 0; + } + // create gate classes if not given + if ( pAig->vGateClasses == NULL ) + { + pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) ); + Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 ); + Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 ); + } + // start the manager + p = Ga2_ManStart( pAig, pPars ); + p->timeInit = clock() - clk; + // perform initial abstraction + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" ); + Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %% RatioMax = %d %%\n", + pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin, pPars->nRatioMax ); + Abc_Print( 1, "LrnStart = %d LrnDelta = %d LrnRatio = %d %% Skip = %d SimpleCNF = %d Dump = %d\n", + pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce, pPars->fUseSkip, pPars->fUseSimple, pPars->fDumpVabs|pPars->fDumpMabs|pPars->fCallProver ); + if ( pPars->fDumpVabs || pPars->fDumpMabs ) + Abc_Print( 1, "%s will be dumped into file \"%s\".\n", + pPars->fDumpVabs ? "Abstracted model" : "Miter with abstraction map", + Ga2_GlaGetFileName(p, pPars->fDumpVabs) ); + Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" ); + } + // iterate unrolling + for ( i = f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; i++ ) + { + int nAbsOld; + // remember the timeframe + p->pPars->iFrame = -1; + // create new SAT solver + Ga2_ManRestart( p ); + // remember abstraction size after the last restart + nAbsOld = Vec_IntSize(p->vAbs); + // unroll the circuit + for ( f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; f++ ) + { + // remember current limits + int nConflsBeg = sat_solver2_nconflicts(p->pSat); + int nAbs = Vec_IntSize(p->vAbs); + int nValues = Vec_IntSize(p->vValues); + int nVarsOld; + // remember the timeframe + p->pPars->iFrame = f; + // extend and clear storage + if ( f == Vec_PtrSize(p->vId2Lit) ) + Vec_PtrPush( p->vId2Lit, Vec_IntAlloc(0) ); + Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 ); + // add static clauses to this timeframe + Ga2_ManAddAbsClauses( p, f ); + // skip checking if skipcheck is enabled (&gla -s) + if ( p->pPars->fUseSkip && f <= p->pPars->iFrameProved ) + continue; + // skip checking if we need to skip several starting frames (&gla -S ) + if ( p->pPars->nFramesStart && f <= p->pPars->nFramesStart ) + continue; + // get the output literal +// Lit = Ga2_ManUnroll_rec( p, Gia_ManPo(pAig,0), f ); + Lit = Ga2_ObjFindLit( p, Gia_ObjFanin0(Gia_ManPo(pAig,0)), f ); + assert( Lit >= 0 ); + Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ); + if ( Lit == 0 ) + continue; + assert( Lit > 1 ); + // check for counter-examples + if ( p->nSatVars > sat_solver2_nvars(p->pSat) ) + sat_solver2_setnvars( p->pSat, p->nSatVars ); + nVarsOld = p->nSatVars; + for ( c = 0; ; c++ ) + { + // consider the special case when the target literal is implied false + // by implications which happened as a result of previous refinements + // note that incremental UNSAT core cannot be computed because there is no learned clauses + // in this case, we will assume that UNSAT core cannot reduce the problem + if ( var_is_assigned(p->pSat, Abc_Lit2Var(Lit)) ) + { + Prf_ManStopP( &p->pSat->pPrf2 ); + break; + } + // perform SAT solving + clk2 = clock(); + Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( Status == l_True ) // perform refinement + { + p->nCexes++; + p->timeSat += clock() - clk2; + + // cancel old one if it was sent + if ( Abc_FrameIsBridgeMode() && fOneIsSent ) + { + Gia_Ga2SendCancel( p, pPars->fVerbose ); + fOneIsSent = 0; + } + if ( iFrameTryToProve >= 0 ) + { + Gia_Ga2ProveCancel( pPars->fVerbose ); + iFrameTryToProve = -1; + } + + // perform refinement + clk2 = clock(); + vPPis = Ga2_ManRefine( p ); + p->timeCex += clock() - clk2; + if ( vPPis == NULL ) + { + if ( pPars->fVerbose ) + Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 ); + goto finish; + } + + if ( c == 0 ) + { +// Ga2_ManRefinePrintPPis( p ); + // create bookmark to be used for rollback + assert( nVarsOld == p->pSat->size ); + sat_solver2_bookmark( p->pSat ); + // start incremental proof manager + assert( p->pSat->pPrf2 == NULL ); + p->pSat->pPrf2 = Prf_ManAlloc(); + if ( p->pSat->pPrf2 ) + { + p->nProofIds = 0; + Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); + Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) ); + } + } + else + { + // resize the proof logger + if ( p->pSat->pPrf2 ) + Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) ); + } + + Ga2_ManAddToAbs( p, vPPis ); + Vec_IntFree( vPPis ); + if ( pPars->fVerbose ) + Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c+1, clock() - clk, 0 ); + continue; + } + p->timeUnsat += clock() - clk2; + if ( Status == l_Undef ) // ran out of resources + goto finish; + if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit ) // timeout + goto finish; + if ( c == 0 ) + { + if ( f > p->pPars->iFrameProved ) + p->pPars->nFramesNoChange++; + break; + } + if ( f > p->pPars->iFrameProved ) + p->pPars->nFramesNoChange = 0; + + // derive the core + assert( p->pSat->pPrf2 != NULL ); + vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); + Prf_ManStopP( &p->pSat->pPrf2 ); + // update the SAT solver + sat_solver2_rollback( p->pSat ); + // reduce abstraction + Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld ); + + // purify UNSAT core + if ( fUseSecondCore ) + { +// int nOldCore = Vec_IntSize(vCore); + // reverse the order of objects in the core +// Vec_IntSort( vCore, 0 ); +// Vec_IntPrint( vCore ); + // create bookmark to be used for rollback + assert( nVarsOld == p->pSat->size ); + sat_solver2_bookmark( p->pSat ); + // start incremental proof manager + assert( p->pSat->pPrf2 == NULL ); + p->pSat->pPrf2 = Prf_ManAlloc(); + if ( p->pSat->pPrf2 ) + { + p->nProofIds = 0; + Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); + Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vCore) ); + + Ga2_ManAddToAbs( p, vCore ); + Vec_IntFree( vCore ); + } + // run SAT solver + clk2 = clock(); + Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( Status == l_Undef ) + goto finish; + assert( Status == l_False ); + p->timeUnsat += clock() - clk2; + + // derive the core + assert( p->pSat->pPrf2 != NULL ); + vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); + Prf_ManStopP( &p->pSat->pPrf2 ); + // update the SAT solver + sat_solver2_rollback( p->pSat ); + // reduce abstraction + Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld ); +// printf( "\n%4d -> %4d\n", nOldCore, Vec_IntSize(vCore) ); + } + + Ga2_ManAddToAbs( p, vCore ); +// Ga2_ManRefinePrint( p, vCore ); + Vec_IntFree( vCore ); + break; + } + // remember the last proved frame + if ( p->pPars->iFrameProved < f ) + p->pPars->iFrameProved = f; + // print statistics + if ( pPars->fVerbose ) + Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 ); + // check if abstraction was proved + if ( Gia_Ga2ProveCheck( pPars->fVerbose ) ) + { + RetValue = 1; + goto finish; + } + if ( c > 0 ) + { + if ( p->pPars->fVeryVerbose ) + Abc_Print( 1, "\n" ); + // recompute the abstraction + Vec_IntFreeP( &pAig->vGateClasses ); + pAig->vGateClasses = Ga2_ManAbsTranslate( p ); + // check if the number of objects is below limit + if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 ) + { + Status = l_Undef; + goto finish; + } + } + // check the number of stable frames + if ( p->pPars->nFramesNoChange == p->pPars->nFramesNoChangeLim ) + { + // dump the model into file + if ( p->pPars->fDumpVabs || p->pPars->fDumpMabs || p->pPars->fCallProver ) + { + char Command[1000]; + Abc_FrameSetStatus( -1 ); + Abc_FrameSetCex( NULL ); + Abc_FrameSetNFrames( f+1 ); + sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") ); + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); + Ga2_GlaDumpAbsracted( p, pPars->fVerbose ); + } + // call the prover + if ( p->pPars->fCallProver ) + { + // cancel old one if it is proving + if ( iFrameTryToProve >= 0 ) + Gia_Ga2ProveCancel( pPars->fVerbose ); + // prove new one + Gia_Ga2ProveAbsracted( Ga2_GlaGetFileName(p, 1), pPars->fVerbose ); + iFrameTryToProve = f; + } + // speak to the bridge + if ( Abc_FrameIsBridgeMode() ) + { + // cancel old one if it was sent + if ( fOneIsSent ) + Gia_Ga2SendCancel( p, pPars->fVerbose ); + // send new one + Gia_Ga2SendAbsracted( p, pPars->fVerbose ); + fOneIsSent = 1; + } + } + // if abstraction grew more than a certain percentage, force a restart + if ( pPars->nRatioMax == 0 ) + continue; + if ( c > 0 && (f > 20 || Vec_IntSize(p->vAbs) > 100) && Vec_IntSize(p->vAbs) - nAbsOld >= nAbsOld * pPars->nRatioMax / 100 ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Forcing restart because abstraction grew from %d to %d (more than %d %%).\n", + nAbsOld, Vec_IntSize(p->vAbs), pPars->nRatioMax ); + break; + } + } + } +finish: + Prf_ManStopP( &p->pSat->pPrf2 ); + // cancel old one if it is proving + if ( iFrameTryToProve >= 0 ) + Gia_Ga2ProveCancel( pPars->fVerbose ); + // analize the results + if ( RetValue == 1 ) + Abc_Print( 1, "GLA completed %d frames and proved abstraction derived in frame %d. ", p->pPars->iFrameProved+1, iFrameTryToProve ); + else if ( pAig->pCexSeq == NULL ) + { +// if ( pAig->vGateClasses != NULL ) +// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); + Vec_IntFreeP( &pAig->vGateClasses ); + pAig->vGateClasses = Ga2_ManAbsTranslate( p ); + if ( Status == l_Undef ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "\n" ); + if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) + Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); + else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) + Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); + else if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 ) + Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, p->pPars->iFrameProved+1 ); + else + Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", p->pPars->iFrameProved+1 ); + } + else + { + p->pPars->iFrame = p->pPars->iFrameProved; + Abc_Print( 1, "GLA completed %d frames and produced a %d-stable abstraction. ", p->pPars->iFrameProved+1, p->pPars->nFramesNoChange ); + } + } + else + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "\n" ); + if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) ) + Abc_Print( 1, " Gia_ManPerformGlaOld(): CEX verification has failed!\n" ); + Abc_Print( 1, "True counter-example detected in frame %d. ", f ); + p->pPars->iFrame = f - 1; + Vec_IntFreeP( &pAig->vGateClasses ); + RetValue = 0; + } + Abc_PrintTime( 1, "Time", clock() - clk ); + if ( p->pPars->fVerbose ) + { + p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit; + ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk ); + ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); + ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); + ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); + ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); + ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); + Ga2_ManReportMemory( p ); + } +// Ga2_ManDumpStats( p->pGia, p->pPars, p->pSat, p->pPars->iFrameProved, 0 ); + Ga2_ManStop( p ); + fflush( stdout ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absGlaOld.c b/src/proof/abs/absGlaOld.c new file mode 100644 index 00000000..5ee69739 --- /dev/null +++ b/src/proof/abs/absGlaOld.c @@ -0,0 +1,1957 @@ +/**CFile**************************************************************** + + FileName [absGla.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Gate-level abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absGla.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sat/cnf/cnf.h" +#include "sat/bsat/satSolver2.h" +#include "base/main/main.h" +#include "abs.h" +#include "absRef.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Rfn_Obj_t_ Rfn_Obj_t; // refinement object +struct Rfn_Obj_t_ +{ + unsigned Value : 1; // value + unsigned fVisit : 1; // visited + unsigned fPPi : 1; // PPI + unsigned Prio : 16; // priority + unsigned Sign : 12; // traversal signature +}; + +typedef struct Gla_Obj_t_ Gla_Obj_t; // abstraction object +struct Gla_Obj_t_ +{ + int iGiaObj; // corresponding GIA obj + unsigned fAbs : 1; // belongs to abstraction + unsigned fCompl0 : 1; // compl bit of the first fanin + unsigned fConst : 1; // object attribute + unsigned fPi : 1; // object attribute + unsigned fPo : 1; // object attribute + unsigned fRo : 1; // object attribute + unsigned fRi : 1; // object attribute + unsigned fAnd : 1; // object attribute + unsigned fMark : 1; // nearby object + unsigned nFanins : 23; // fanin count + int Fanins[4]; // fanins + Vec_Int_t vFrames; // variables in each timeframe +}; + +typedef struct Gla_Man_t_ Gla_Man_t; // manager +struct Gla_Man_t_ +{ + // user data + Gia_Man_t * pGia0; // starting AIG manager + Gia_Man_t * pGia; // working AIG manager + Abs_Par_t * pPars; // parameters + // internal data + Vec_Int_t * vAbs; // abstracted objects + Gla_Obj_t * pObjRoot; // the primary output + Gla_Obj_t * pObjs; // objects + unsigned * pObj2Obj; // mapping of GIA obj into GLA obj + int nObjs; // the number of objects + int nAbsOld; // previous abstraction +// int nAbsNew; // previous abstraction +// int nLrnOld; // the number of bytes +// int nLrnNew; // the number of bytes + // other data + int nCexes; // the number of counter-examples + int nObjAdded; // total number of objects added + int nSatVars; // the number of SAT variables + Cnf_Dat_t * pCnf; // CNF derived for the nodes + sat_solver2 * pSat; // incremental SAT solver + Vec_Int_t * vTemp; // temporary array + Vec_Int_t * vAddedNew; // temporary array + Vec_Int_t * vObjCounts; // object counters + Vec_Int_t * vCoreCounts; // counts how many times each object appears in the core + Vec_Int_t * vProofIds; // counts how many times each object appears in the core + int nProofIds; // proof ID counter + // refinement + Vec_Int_t * pvRefis; // vectors of each object + // refinement manager + Gia_Man_t * pGia2; + Rnm_Man_t * pRnm; + // statistics + clock_t timeInit; + clock_t timeSat; + clock_t timeUnsat; + clock_t timeCex; + clock_t timeOther; +}; + +// declarations +static Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis ); +static int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame ); +static int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame ); + +// object procedures +static inline int Gla_ObjId( Gla_Man_t * p, Gla_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } +static inline Gla_Obj_t * Gla_ManObj( Gla_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; } +static inline Gia_Obj_t * Gla_ManGiaObj( Gla_Man_t * p, Gla_Obj_t * pObj ) { return Gia_ManObj( p->pGia, pObj->iGiaObj ); } +static inline int Gla_ObjSatValue( Gla_Man_t * p, int iGia, int f ) { return Gla_ManCheckVar(p, p->pObj2Obj[iGia], f) ? sat_solver2_var_value( p->pSat, Gla_ManGetVar(p, p->pObj2Obj[iGia], f) ) : 0; } + +static inline Rfn_Obj_t * Gla_ObjRef( Gla_Man_t * p, Gia_Obj_t * pObj, int f ) { return (Rfn_Obj_t *)Vec_IntGetEntryP( &(p->pvRefis[Gia_ObjId(p->pGia, pObj)]), f ); } +static inline void Gla_ObjClearRef( Rfn_Obj_t * p ) { *((int *)p) = 0; } + + +// iterator through abstracted objects +#define Gla_ManForEachObj( p, pObj ) \ + for ( pObj = p->pObjs + 1; pObj < p->pObjs + p->nObjs; pObj++ ) +#define Gla_ManForEachObjAbs( p, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(p->vAbs) && ((pObj = Gla_ManObj(p, Vec_IntEntry(p->vAbs, i))),1); i++) +#define Gla_ManForEachObjAbsVec( vVec, p, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(vVec) && ((pObj = Gla_ManObj(p, Vec_IntEntry(vVec, i))),1); i++) + +// iterator through fanins of an abstracted object +#define Gla_ObjForEachFanin( p, pObj, pFanin, i ) \ + for ( i = 0; (i < (int)pObj->nFanins) && ((pFanin = Gla_ManObj(p, pObj->Fanins[i])),1); i++ ) + +// some lessons learned from debugging mismatches between GIA and mapped CNF +// - inputs/output of AND-node may be PPIs (have SAT vars), but the node is not included in the abstraction +// - some logic node can be a PPI of one LUT and an internal node of another LUT + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Prepares CEX and vMap for refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GlaPrepareCexAndMap( Gla_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMap ) +{ + Abc_Cex_t * pCex; + Vec_Int_t * vMap; + Gla_Obj_t * pObj, * pFanin; + Gia_Obj_t * pGiaObj; + int f, i, k; + // find PIs and PPIs + vMap = Vec_IntAlloc( 1000 ); + Gla_ManForEachObjAbs( p, pObj, i ) + { + assert( pObj->fConst || pObj->fRo || pObj->fAnd ); + Gla_ObjForEachFanin( p, pObj, pFanin, k ) + if ( !pFanin->fAbs ) + Vec_IntPush( vMap, pFanin->iGiaObj ); + } + Vec_IntUniqify( vMap ); + // derive counter-example + pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 ); + pCex->iFrame = p->pPars->iFrame; + for ( f = 0; f <= p->pPars->iFrame; f++ ) + Gia_ManForEachObjVec( vMap, p->pGia, pGiaObj, k ) + if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pGiaObj), f ) ) + Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k ); + *pvMap = vMap; + *ppCex = pCex; +} + +/**Function************************************************************* + + Synopsis [Derives counter-example using current assignments.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gla_ManDeriveCex( Gla_Man_t * p, Vec_Int_t * vPis ) +{ + Abc_Cex_t * pCex; + Gia_Obj_t * pObj; + int i, f; + pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); + pCex->iPo = 0; + pCex->iFrame = p->pPars->iFrame; + Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) + { + if ( !Gia_ObjIsPi(p->pGia, pObj) ) + continue; + assert( Gia_ObjIsPi(p->pGia, pObj) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) ); + } + return pCex; +} + +/**Function************************************************************* + + Synopsis [Collects GIA abstraction objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManCollectInternal_rec( Gia_Man_t * p, Gia_Obj_t * pGiaObj, Vec_Int_t * vRoAnds ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pGiaObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pGiaObj); + assert( Gia_ObjIsAnd(pGiaObj) ); + Gla_ManCollectInternal_rec( p, Gia_ObjFanin0(pGiaObj), vRoAnds ); + Gla_ManCollectInternal_rec( p, Gia_ObjFanin1(pGiaObj), vRoAnds ); + Vec_IntPush( vRoAnds, Gia_ObjId(p, pGiaObj) ); +} +void Gla_ManCollect( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vCos, Vec_Int_t * vRoAnds ) +{ + Gla_Obj_t * pObj, * pFanin; + Gia_Obj_t * pGiaObj; + int i, k; + + // collect COs + Vec_IntPush( vCos, Gia_ObjId(p->pGia, Gia_ManPo(p->pGia, 0)) ); + // collect fanins of abstracted objects + Gla_ManForEachObjAbs( p, pObj, i ) + { + assert( pObj->fConst || pObj->fRo || pObj->fAnd ); + if ( pObj->fRo ) + { + pGiaObj = Gia_ObjRoToRi( p->pGia, Gia_ManObj(p->pGia, pObj->iGiaObj) ); + Vec_IntPush( vCos, Gia_ObjId(p->pGia, pGiaObj) ); + } + Gla_ObjForEachFanin( p, pObj, pFanin, k ) + if ( !pFanin->fAbs ) + Vec_IntPush( (pFanin->fPi ? vPis : vPPis), pFanin->iGiaObj ); + } + Vec_IntUniqify( vPis ); + Vec_IntUniqify( vPPis ); + Vec_IntSort( vCos, 0 ); + // sorting PIs/PPIs/COs leads to refinements that are more "well-aligned"... + + // mark const/PIs/PPIs + Gia_ManIncrementTravId( p->pGia ); + Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); + Gia_ManForEachObjVec( vPis, p->pGia, pGiaObj, i ) + Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); + Gia_ManForEachObjVec( vPPis, p->pGia, pGiaObj, i ) + Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); + // mark and add ROs first + Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i ) + { + if ( i == 0 ) continue; + pGiaObj = Gia_ObjRiToRo( p->pGia, pGiaObj ); + Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj ); + Vec_IntPush( vRoAnds, Gia_ObjId(p->pGia, pGiaObj) ); + } + // collect nodes between PIs/PPIs/ROs and COs + Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i ) + Gla_ManCollectInternal_rec( p->pGia, Gia_ObjFanin0(pGiaObj), vRoAnds ); +} + +/**Function************************************************************* + + Synopsis [Drive implications of the given node towards primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManRefSetAndPropFanout_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign ) +{ + int i;//, Id = Gia_ObjId(p->pGia, pObj); + Rfn_Obj_t * pRef0, * pRef1, * pRef = Gla_ObjRef( p, pObj, f ); + Gia_Obj_t * pFanout; + int k; + if ( (int)pRef->Sign != Sign ) + return; + assert( pRef->fVisit == 0 ); + pRef->fVisit = 1; + if ( pRef->fPPi ) + { + assert( (int)pRef->Prio > 0 ); + for ( i = p->pPars->iFrame; i >= 0; i-- ) + if ( !Gla_ObjRef(p, pObj, i)->fVisit ) + Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign ); + Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); + return; + } + if ( (Gia_ObjIsCo(pObj) && f == p->pPars->iFrame) || Gia_ObjIsPo(p->pGia, pObj) ) + return; + if ( Gia_ObjIsRi(p->pGia, pObj) ) + { + pFanout = Gia_ObjRiToRo(p->pGia, pObj); + if ( !Gla_ObjRef(p, pFanout, f+1)->fVisit ) + Gia_ManRefSetAndPropFanout_rec( p, pFanout, f+1, vSelect, Sign ); + return; + } + assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); + Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k ) + { +// Rfn_Obj_t * pRefF = Gla_ObjRef(p, pFanout, f); + if ( Gla_ObjRef(p, pFanout, f)->fVisit ) + continue; + if ( Gia_ObjIsCo(pFanout) ) + { + Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign ); + continue; + } + assert( Gia_ObjIsAnd(pFanout) ); + pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pFanout), f ); + pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pFanout), f ); + if ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRef0->fVisit) || + ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRef1->fVisit) || + ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRef0->fVisit) && + ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRef1->fVisit) ) ) + Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign ); + } +} + +/**Function************************************************************* + + Synopsis [Selects assignments to be refined.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManRefSelect_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign ) +{ + int i;//, Id = Gia_ObjId(p->pGia, pObj); + Rfn_Obj_t * pRef = Gla_ObjRef( p, pObj, f ); +// assert( (int)pRef->Sign == Sign ); + if ( pRef->fVisit ) + return; + if ( p->pPars->fPropFanout ) + Gia_ManRefSetAndPropFanout_rec( p, pObj, f, vSelect, Sign ); + else + pRef->fVisit = 1; + if ( pRef->fPPi ) + { + assert( (int)pRef->Prio > 0 ); + if ( p->pPars->fPropFanout ) + { + for ( i = p->pPars->iFrame; i >= 0; i-- ) + if ( !Gla_ObjRef(p, pObj, i)->fVisit ) + Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign ); + } + else + { + Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); + Vec_IntAddToEntry( p->vObjCounts, f, 1 ); + } + return; + } + if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) + return; + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect, Sign ); + return; + } + if ( Gia_ObjIsAnd(pObj) ) + { + Rfn_Obj_t * pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); + Rfn_Obj_t * pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f ); + if ( pRef->Value == 1 ) + { + if ( pRef0->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); + if ( pRef1->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); + } + else // select one value + { + if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + { + if ( pRef0->Prio <= pRef1->Prio ) // choice + { + if ( pRef0->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); + } + else + { + if ( pRef1->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); + } + } + else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) + { + if ( pRef0->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign ); + } + else if ( (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + { + if ( pRef1->Prio > 0 ) + Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign ); + } + else assert( 0 ); + } + } + else assert( 0 ); +} + + +/**Function************************************************************* + + Synopsis [Performs refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManVerifyUsingTerSim( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vRoAnds, Vec_Int_t * vCos, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj; + int i, f; +// Gia_ManForEachObj( p->pGia, pObj, i ) +// assert( Gia_ObjTerSimGetC(pObj) ); + for ( f = 0; f <= p->pPars->iFrame; f++ ) + { + Gia_ObjTerSimSet0( Gia_ManConst0(p->pGia) ); + Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) + { + if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) + Gia_ObjTerSimSetX( pObj ); + Gia_ManForEachObjVec( vRes, p->pGia, pObj, i ) + if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + + Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjTerSimAnd( pObj ); + else if ( f == 0 ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimRo( p->pGia, pObj ); + } + Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) + Gia_ObjTerSimCo( pObj ); + } + pObj = Gia_ManPo( p->pGia, 0 ); + if ( !Gia_ObjTerSimGet1(pObj) ) + Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); + // clear + Gia_ObjTerSimSetC( Gia_ManConst0(p->pGia) ); + Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) + Gia_ObjTerSimSetC( pObj ); + Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) + Gia_ObjTerSimSetC( pObj ); + Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) + Gia_ObjTerSimSetC( pObj ); + Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) + Gia_ObjTerSimSetC( pObj ); +} + + +/**Function************************************************************* + + Synopsis [Performs refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gla_ManRefinement( Gla_Man_t * p ) +{ + Abc_Cex_t * pCex; + Vec_Int_t * vMap, * vVec; + Gia_Obj_t * pObj; + int i; + Gia_GlaPrepareCexAndMap( p, &pCex, &vMap ); + vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 0, 1 ); + Abc_CexFree( pCex ); + if ( Vec_IntSize(vVec) == 0 ) + { + Vec_IntFree( vVec ); + Abc_CexFreeP( &p->pGia->pCexSeq ); + p->pGia->pCexSeq = Gla_ManDeriveCex( p, vMap ); + Vec_IntFree( vMap ); + return NULL; + } + Vec_IntFree( vMap ); + // remap them into GLA objects + Gia_ManForEachObjVec( vVec, p->pGia, pObj, i ) + Vec_IntWriteEntry( vVec, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] ); + p->nObjAdded += Vec_IntSize(vVec); + return vVec; +} + +/**Function************************************************************* + + Synopsis [Performs refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gla_ManRefinement2( Gla_Man_t * p ) +{ + int fVerify = 1; + static int Sign = 0; + Vec_Int_t * vPis, * vPPis, * vCos, * vRoAnds, * vSelect = NULL; + Rfn_Obj_t * pRef, * pRef0, * pRef1; + Gia_Obj_t * pObj; + int i, f; + Sign++; + + // compute PIs and pseudo-PIs + vCos = Vec_IntAlloc( 1000 ); + vPis = Vec_IntAlloc( 1000 ); + vPPis = Vec_IntAlloc( 1000 ); + vRoAnds = Vec_IntAlloc( 1000 ); + Gla_ManCollect( p, vPis, vPPis, vCos, vRoAnds ); + +/* + // check how many pseudo PIs have variables + Gla_ManForEachObjAbsVec( vPis, p, pGla, i ) + { + Abc_Print( 1, " %5d : ", Gla_ObjId(p, pGla) ); + for ( f = 0; f <= p->pPars->iFrame; f++ ) + Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) ); + Abc_Print( 1, "\n" ); + } + + // check how many pseudo PIs have variables + Gla_ManForEachObjAbsVec( vPPis, p, pGla, i ) + { + Abc_Print( 1, "%5d : ", Gla_ObjId(p, pGla) ); + for ( f = 0; f <= p->pPars->iFrame; f++ ) + Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) ); + Abc_Print( 1, "\n" ); + } +*/ + // propagate values + for ( f = 0; f <= p->pPars->iFrame; f++ ) + { + // constant + pRef = Gla_ObjRef( p, Gia_ManConst0(p->pGia), f ); Gla_ObjClearRef( pRef ); + pRef->Value = 0; + pRef->Prio = 0; + pRef->Sign = Sign; + // primary input + Gia_ManForEachObjVec( vPis, p->pGia, pObj, i ) + { +// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) ); + pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); + pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ); + pRef->Prio = 0; + pRef->Sign = Sign; + assert( pRef->fVisit == 0 ); + } + // primary input + Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i ) + { +// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) ); + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); + pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); + pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ); + pRef->Prio = i+1; + pRef->fPPi = 1; + pRef->Sign = Sign; + assert( pRef->fVisit == 0 ); + } + // internal nodes + Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); + pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f == 0 ) + { + pRef->Value = 0; + pRef->Prio = 0; + pRef->Sign = Sign; + } + else + { + pRef0 = Gla_ObjRef( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); + pRef->Value = pRef0->Value; + pRef->Prio = pRef0->Prio; + pRef->Sign = Sign; + } + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); + pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f ); + pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj)) & (pRef1->Value ^ Gia_ObjFaninC1(pObj)); + + if ( p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] != ~0 && + Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) && + (int)pRef->Value != Gla_ObjSatValue(p, Gia_ObjId(p->pGia, pObj), f) ) + { + Abc_Print( 1, "Object has value mismatch " ); + Gia_ObjPrint( p->pGia, pObj ); + } + + if ( pRef->Value == 1 ) + pRef->Prio = Abc_MaxInt( pRef0->Prio, pRef1->Prio ); + else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + pRef->Prio = Abc_MinInt( pRef0->Prio, pRef1->Prio ); // choice + else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) + pRef->Prio = pRef0->Prio; + else + pRef->Prio = pRef1->Prio; + assert( pRef->fVisit == 0 ); + pRef->Sign = Sign; + } + // output nodes + Gia_ManForEachObjVec( vCos, p->pGia, pObj, i ) + { + pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef ); + pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f ); + pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj)); + pRef->Prio = pRef0->Prio; + assert( pRef->fVisit == 0 ); + pRef->Sign = Sign; + } + } + + // make sure the output value is 1 + pObj = Gia_ManPo( p->pGia, 0 ); + pRef = Gla_ObjRef( p, pObj, p->pPars->iFrame ); + if ( pRef->Value != 1 ) + Abc_Print( 1, "\nCounter-example verification has failed!!!\n" ); + + // check the CEX + if ( pRef->Prio == 0 ) + { + p->pGia->pCexSeq = Gla_ManDeriveCex( p, vPis ); + Vec_IntFree( vPis ); + Vec_IntFree( vPPis ); + Vec_IntFree( vRoAnds ); + Vec_IntFree( vCos ); + return NULL; + } + + // select objects + vSelect = Vec_IntAlloc( 100 ); + Vec_IntFill( p->vObjCounts, p->pPars->iFrame+1, 0 ); + Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), p->pPars->iFrame, vSelect, Sign ); + Vec_IntUniqify( vSelect ); + +/* + for ( f = 0; f < p->pPars->iFrame; f++ ) + printf( "%2d", Vec_IntEntry(p->vObjCounts, f) ); + printf( "\n" ); +*/ + if ( fVerify ) + Gla_ManVerifyUsingTerSim( p, vPis, vPPis, vRoAnds, vCos, vSelect ); + + // remap them into GLA objects + Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) + Vec_IntWriteEntry( vSelect, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] ); + + Vec_IntFree( vPis ); + Vec_IntFree( vPPis ); + Vec_IntFree( vRoAnds ); + Vec_IntFree( vCos ); + + p->nObjAdded += Vec_IntSize(vSelect); + return vSelect; +} + + +/**Function************************************************************* + + Synopsis [Adds clauses for the given obj in the given frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManCollectFanins( Gla_Man_t * p, Gla_Obj_t * pGla, int iObj, Vec_Int_t * vFanins ) +{ + int i, nClauses, iFirstClause, * pLit; + nClauses = p->pCnf->pObj2Count[pGla->iGiaObj]; + iFirstClause = p->pCnf->pObj2Clause[pGla->iGiaObj]; + Vec_IntClear( vFanins ); + for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) + for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ ) + if ( lit_var(*pLit) != iObj ) + Vec_IntPushUnique( vFanins, lit_var(*pLit) ); + assert( Vec_IntSize( vFanins ) <= 4 ); + Vec_IntSort( vFanins, 0 ); +} + + +/**Function************************************************************* + + Synopsis [Duplicates AIG while decoupling nodes duplicated in the mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupMapped_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Man_t * pNew ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupMapped_rec( p, Gia_ObjFanin0(pObj), pNew ); + Gia_ManDupMapped_rec( p, Gia_ObjFanin1(pObj), pNew ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Vec_IntPush( pNew->vLutConfigs, Gia_ObjId(p, pObj) ); +} +Gia_Man_t * Gia_ManDupMapped( Gia_Man_t * p, Vec_Int_t * vMapping ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pFanin; + int i, k, * pMapping, * pObj2Obj; + // start new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + // start mapping + Gia_ManFillValue( p ); + pObj2Obj = ABC_FALLOC( int, Gia_ManObjNum(p) ); + pObj2Obj[0] = 0; + // create reverse mapping and attach it to the node + pNew->vLutConfigs = Vec_IntAlloc( Gia_ManObjNum(p) * 4 / 3 ); + Vec_IntPush( pNew->vLutConfigs, 0 ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + { + int Offset = Vec_IntEntry(vMapping, Gia_ObjId(p, pObj)); + if ( Offset == 0 ) + continue; + pMapping = Vec_IntEntryP( vMapping, Offset ); + Gia_ManIncrementTravId( p ); + for ( k = 1; k <= 4; k++ ) + { + if ( pMapping[k] == -1 ) + continue; + pFanin = Gia_ManObj(p, pMapping[k]); + Gia_ObjSetTravIdCurrent( p, pFanin ); + pFanin->Value = pObj2Obj[pMapping[k]]; + assert( ~pFanin->Value ); + } + assert( !Gia_ObjIsTravIdCurrent(p, pObj) ); + assert( !~pObj->Value ); + Gia_ManDupMapped_rec( p, pObj, pNew ); + pObj2Obj[i] = pObj->Value; + assert( ~pObj->Value ); + } + else if ( Gia_ObjIsCi(pObj) ) + { + pObj2Obj[i] = Gia_ManAppendCi( pNew ); + Vec_IntPush( pNew->vLutConfigs, i ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + Gia_ObjFanin0(pObj)->Value = pObj2Obj[Gia_ObjFaninId0p(p, pObj)]; + assert( ~Gia_ObjFanin0(pObj)->Value ); + pObj2Obj[i] = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntPush( pNew->vLutConfigs, i ); + } + } + assert( Vec_IntSize(pNew->vLutConfigs) == Gia_ManObjNum(pNew) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + // map original AIG into the new AIG + Gia_ManForEachObj( p, pObj, i ) + pObj->Value = pObj2Obj[i]; + ABC_FREE( pObj2Obj ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gla_Man_t * Gla_ManStart( Gia_Man_t * pGia0, Abs_Par_t * pPars ) +{ + Gla_Man_t * p; + Aig_Man_t * pAig; + Gia_Obj_t * pObj; + Gla_Obj_t * pGla; + Vec_Int_t * vMappingNew; + int i, k, Offset, * pMapping, * pLits, * pObj2Count, * pObj2Clause; + + // start + p = ABC_CALLOC( Gla_Man_t, 1 ); + p->pGia0 = pGia0; + p->pPars = pPars; + p->vAbs = Vec_IntAlloc( 100 ); + p->vTemp = Vec_IntAlloc( 100 ); + p->vAddedNew = Vec_IntAlloc( 100 ); + p->vObjCounts = Vec_IntAlloc( 100 ); + + // internal data + pAig = Gia_ManToAigSimple( pGia0 ); + p->pCnf = Cnf_DeriveOther( pAig, 1 ); + Aig_ManStop( pAig ); + // create working GIA + p->pGia = Gia_ManDupMapped( pGia0, p->pCnf->vMapping ); + if ( pPars->fPropFanout ) + Gia_ManStaticFanoutStart( p->pGia ); + + // derive new gate map + assert( pGia0->vGateClasses != 0 ); + p->pGia->vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) ); + p->vCoreCounts = Vec_IntStart( Gia_ManObjNum(p->pGia) ); + p->vProofIds = Vec_IntAlloc(0); + // update p->pCnf->vMapping, p->pCnf->pObj2Count, p->pCnf->pObj2Clause + // (here are not updating p->pCnf->pVarNums because it is not needed) + vMappingNew = Vec_IntStart( Gia_ManObjNum(p->pGia) ); + pObj2Count = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) ); + pObj2Clause = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( pGia0, pObj, i ) + { + // skip internal nodes not used in the mapping + if ( !~pObj->Value ) + continue; + // replace positive literal by variable + assert( !Abc_LitIsCompl(pObj->Value) ); + pObj->Value = Abc_Lit2Var(pObj->Value); + assert( (int)pObj->Value < Gia_ManObjNum(p->pGia) ); + // update arrays + pObj2Count[pObj->Value] = p->pCnf->pObj2Count[i]; + pObj2Clause[pObj->Value] = p->pCnf->pObj2Clause[i]; + if ( Vec_IntEntry(pGia0->vGateClasses, i) ) + Vec_IntWriteEntry( p->pGia->vGateClasses, pObj->Value, 1 ); + // update mappings + Offset = Vec_IntEntry(p->pCnf->vMapping, i); + Vec_IntWriteEntry( vMappingNew, pObj->Value, Vec_IntSize(vMappingNew) ); + pMapping = Vec_IntEntryP(p->pCnf->vMapping, Offset); + Vec_IntPush( vMappingNew, pMapping[0] ); + for ( k = 1; k <= 4; k++ ) + { + if ( pMapping[k] == -1 ) + Vec_IntPush( vMappingNew, -1 ); + else + { + assert( ~Gia_ManObj(pGia0, pMapping[k])->Value ); + Vec_IntPush( vMappingNew, Gia_ManObj(pGia0, pMapping[k])->Value ); + } + } + } + // update mapping after the offset (currently not being done because it is not used) + Vec_IntFree( p->pCnf->vMapping ); p->pCnf->vMapping = vMappingNew; + ABC_FREE( p->pCnf->pObj2Count ); p->pCnf->pObj2Count = pObj2Count; + ABC_FREE( p->pCnf->pObj2Clause ); p->pCnf->pObj2Clause = pObj2Clause; + + + // count the number of variables + p->nObjs = 1; + Gia_ManForEachObj( p->pGia, pObj, i ) + if ( p->pCnf->pObj2Count[i] >= 0 ) + pObj->Value = p->nObjs++; + else + pObj->Value = ~0; + + // re-express CNF using new variable IDs + pLits = p->pCnf->pClauses[0]; + for ( i = 0; i < p->pCnf->nLiterals; i++ ) + { + // find the original AIG object + pObj = Gia_ManObj( pGia0, lit_var(pLits[i]) ); + assert( ~pObj->Value ); + // find the working AIG object + pObj = Gia_ManObj( p->pGia, pObj->Value ); + assert( ~pObj->Value ); + // express literal in terms of LUT variables + pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) ); + } + + // create objects + p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs ); + p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) ); +// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( p->pGia, pObj, i ) + { + p->pObj2Obj[i] = pObj->Value; + if ( !~pObj->Value ) + continue; + pGla = Gla_ManObj( p, pObj->Value ); + pGla->iGiaObj = i; + pGla->fCompl0 = Gia_ObjFaninC0(pObj); + pGla->fConst = Gia_ObjIsConst0(pObj); + pGla->fPi = Gia_ObjIsPi(p->pGia, pObj); + pGla->fPo = Gia_ObjIsPo(p->pGia, pObj); + pGla->fRi = Gia_ObjIsRi(p->pGia, pObj); + pGla->fRo = Gia_ObjIsRo(p->pGia, pObj); + pGla->fAnd = Gia_ObjIsAnd(pObj); + if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) + continue; + if ( Gia_ObjIsCo(pObj) ) + { + pGla->nFanins = 1; + pGla->Fanins[0] = Gia_ObjFanin0(pObj)->Value; + continue; + } + if ( Gia_ObjIsAnd(pObj) ) + { +// Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp ); +// pGla->nFanins = Vec_IntSize( p->vTemp ); +// memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) ); + Offset = Vec_IntEntry( p->pCnf->vMapping, i ); + pMapping = Vec_IntEntryP( p->pCnf->vMapping, Offset ); + pGla->nFanins = 0; + for ( k = 1; k <= 4; k++ ) + if ( pMapping[k] != -1 ) + pGla->Fanins[ pGla->nFanins++ ] = Gia_ManObj(p->pGia, pMapping[k])->Value; + continue; + } + assert( Gia_ObjIsRo(p->pGia, pObj) ); + pGla->nFanins = 1; + pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value; + pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) ); + } + p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value ); + // abstraction + assert( p->pGia->vGateClasses != NULL ); + Gla_ManForEachObj( p, pGla ) + { + if ( Vec_IntEntry( p->pGia->vGateClasses, pGla->iGiaObj ) == 0 ) + continue; + pGla->fAbs = 1; + Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); + } + // other + p->pSat = sat_solver2_new(); + if ( pPars->fUseFullProof ) + p->pSat->pPrf1 = Vec_SetAlloc( 20 ); +// p->pSat->fVerbose = p->pPars->fVerbose; +// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax ); + p->pSat->nLearntStart = p->pPars->nLearnedStart; + p->pSat->nLearntDelta = p->pPars->nLearnedDelta; + p->pSat->nLearntRatio = p->pPars->nLearnedPerce; + p->pSat->nLearntMax = p->pSat->nLearntStart; + p->nSatVars = 1; + // start the refinement manager +// p->pGia2 = Gia_ManDup( p->pGia ); + p->pRnm = Rnm_ManStart( p->pGia ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gla_Man_t * Gla_ManStart2( Gia_Man_t * pGia, Abs_Par_t * pPars ) +{ + Gla_Man_t * p; + Aig_Man_t * pAig; + Gia_Obj_t * pObj; + Gla_Obj_t * pGla; + int i, * pLits; + // start + p = ABC_CALLOC( Gla_Man_t, 1 ); + p->pGia = pGia; + p->pPars = pPars; + p->vAbs = Vec_IntAlloc( 100 ); + p->vTemp = Vec_IntAlloc( 100 ); + p->vAddedNew = Vec_IntAlloc( 100 ); + // internal data + pAig = Gia_ManToAigSimple( p->pGia ); + p->pCnf = Cnf_DeriveOther( pAig, 1 ); + Aig_ManStop( pAig ); + // count the number of variables + p->nObjs = 1; + Gia_ManForEachObj( p->pGia, pObj, i ) + if ( p->pCnf->pObj2Count[i] >= 0 ) + pObj->Value = p->nObjs++; + else + pObj->Value = ~0; + // re-express CNF using new variable IDs + pLits = p->pCnf->pClauses[0]; + for ( i = 0; i < p->pCnf->nLiterals; i++ ) + { + pObj = Gia_ManObj( p->pGia, lit_var(pLits[i]) ); + assert( ~pObj->Value ); + pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) ); + } + // create objects + p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs ); + p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) ); +// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( p->pGia, pObj, i ) + { + p->pObj2Obj[i] = pObj->Value; + if ( !~pObj->Value ) + continue; + pGla = Gla_ManObj( p, pObj->Value ); + pGla->iGiaObj = i; + pGla->fCompl0 = Gia_ObjFaninC0(pObj); + pGla->fConst = Gia_ObjIsConst0(pObj); + pGla->fPi = Gia_ObjIsPi(p->pGia, pObj); + pGla->fPo = Gia_ObjIsPo(p->pGia, pObj); + pGla->fRi = Gia_ObjIsRi(p->pGia, pObj); + pGla->fRo = Gia_ObjIsRo(p->pGia, pObj); + pGla->fAnd = Gia_ObjIsAnd(pObj); + if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) + continue; + if ( Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ) + { + Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp ); + pGla->nFanins = Vec_IntSize( p->vTemp ); + memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) ); + continue; + } + assert( Gia_ObjIsRo(p->pGia, pObj) ); + pGla->nFanins = 1; + pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value; + pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) ); + } + p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value ); + // abstraction + assert( pGia->vGateClasses != NULL ); + Gla_ManForEachObj( p, pGla ) + { + if ( Vec_IntEntry( pGia->vGateClasses, pGla->iGiaObj ) == 0 ) + continue; + pGla->fAbs = 1; + Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); + } + // other + p->pSat = sat_solver2_new(); + p->nSatVars = 1; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManStop( Gla_Man_t * p ) +{ + Gla_Obj_t * pGla; + int i; + + if ( p->pPars->fVerbose ) + Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n", + sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat), + sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); + + // stop the refinement manager +// Gia_ManStopP( &p->pGia2 ); + Rnm_ManStop( p->pRnm, 0 ); + + if ( p->pvRefis ) + for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ ) + ABC_FREE( p->pvRefis[i].pArray ); + Gla_ManForEachObj( p, pGla ) + ABC_FREE( pGla->vFrames.pArray ); + Cnf_DataFree( p->pCnf ); + if ( p->pGia0 != NULL ) + Gia_ManStop( p->pGia ); +// Gia_ManStaticFanoutStart( p->pGia0 ); + sat_solver2_delete( p->pSat ); + Vec_IntFreeP( &p->vObjCounts ); + Vec_IntFreeP( &p->vAddedNew ); + Vec_IntFreeP( &p->vCoreCounts ); + Vec_IntFreeP( &p->vProofIds ); + Vec_IntFreeP( &p->vTemp ); + Vec_IntFreeP( &p->vAbs ); + ABC_FREE( p->pvRefis ); + ABC_FREE( p->pObj2Obj ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_GlaAbsCount( Gla_Man_t * p, int fRo, int fAnd ) +{ + Gla_Obj_t * pObj; + int i, Counter = 0; + if ( fRo ) + Gla_ManForEachObjAbs( p, pObj, i ) + Counter += (pObj->fRo && pObj->fAbs); + else if ( fAnd ) + Gla_ManForEachObjAbs( p, pObj, i ) + Counter += (pObj->fAnd && pObj->fAbs); + else + Gla_ManForEachObjAbs( p, pObj, i ) + Counter += (pObj->fAbs); + return Counter; +} + + +/**Function************************************************************* + + Synopsis [Derives new abstraction map.] + + Description [Returns 1 if node contains abstracted leaf on the path.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gla_ManTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla, int nUsageCount ) +{ + int Value0, Value1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 1; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Gla_ManTranslate_rec( p, Gia_ObjFanin0(pObj), vGla, nUsageCount ); + Value1 = Gla_ManTranslate_rec( p, Gia_ObjFanin1(pObj), vGla, nUsageCount ); + if ( Value0 || Value1 ) + Vec_IntAddToEntry( vGla, Gia_ObjId(p, pObj), nUsageCount ); + return Value0 || Value1; +} +Vec_Int_t * Gla_ManTranslate( Gla_Man_t * p ) +{ + Vec_Int_t * vGla, * vGla2; + Gla_Obj_t * pObj, * pFanin; + Gia_Obj_t * pGiaObj; + int i, k, nUsageCount; + vGla = Vec_IntStart( Gia_ManObjNum(p->pGia) ); + Gla_ManForEachObjAbs( p, pObj, i ) + { + nUsageCount = Vec_IntEntry(p->vCoreCounts, pObj->iGiaObj); + assert( nUsageCount >= 0 ); + if ( nUsageCount == 0 ) + nUsageCount++; + pGiaObj = Gla_ManGiaObj( p, pObj ); + if ( Gia_ObjIsConst0(pGiaObj) || Gia_ObjIsRo(p->pGia, pGiaObj) ) + { + Vec_IntWriteEntry( vGla, pObj->iGiaObj, nUsageCount ); + continue; + } + assert( Gia_ObjIsAnd(pGiaObj) ); + Gia_ManIncrementTravId( p->pGia ); + Gla_ObjForEachFanin( p, pObj, pFanin, k ) + Gia_ObjSetTravIdCurrent( p->pGia, Gla_ManGiaObj(p, pFanin) ); + Gla_ManTranslate_rec( p->pGia, pGiaObj, vGla, nUsageCount ); + } + Vec_IntWriteEntry( vGla, 0, p->pPars->iFrame+1 ); + if ( p->pGia->vLutConfigs ) // use mapping from new to old + { + vGla2 = Vec_IntStart( Gia_ManObjNum(p->pGia0) ); + for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ ) + if ( Vec_IntEntry(vGla, i) ) + Vec_IntWriteEntry( vGla2, Vec_IntEntry(p->pGia->vLutConfigs, i), Vec_IntEntry(vGla, i) ); + Vec_IntFree( vGla ); + return vGla2; + } + return vGla; +} + + +/**Function************************************************************* + + Synopsis [Collect pseudo-PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis ) +{ + Vec_Int_t * vPPis; + Gla_Obj_t * pObj, * pFanin; + int i, k; + vPPis = Vec_IntAlloc( 1000 ); + if ( vPis ) + Vec_IntClear( vPis ); + Gla_ManForEachObjAbs( p, pObj, i ) + { + assert( pObj->fConst || pObj->fRo || pObj->fAnd ); + Gla_ObjForEachFanin( p, pObj, pFanin, k ) + if ( !pFanin->fPi && !pFanin->fAbs ) + Vec_IntPush( vPPis, pObj->Fanins[k] ); + else if ( vPis && pFanin->fPi && !pFanin->fAbs ) + Vec_IntPush( vPis, pObj->Fanins[k] ); + } + Vec_IntUniqify( vPPis ); + Vec_IntReverseOrder( vPPis ); + if ( vPis ) + Vec_IntUniqify( vPis ); + return vPPis; +} +int Gla_ManCountPPis( Gla_Man_t * p ) +{ + Vec_Int_t * vPPis = Gla_ManCollectPPis( p, NULL ); + int RetValue = Vec_IntSize( vPPis ); + Vec_IntFree( vPPis ); + return RetValue; +} +void Gla_ManExplorePPis( Gla_Man_t * p, Vec_Int_t * vPPis ) +{ + static int Round = 0; + Gla_Obj_t * pObj, * pFanin; + int i, j, k, Count; + if ( (Round++ % 5) == 0 ) + return; + j = 0; + Gla_ManForEachObjAbsVec( vPPis, p, pObj, i ) + { + assert( pObj->fAbs == 0 ); + Count = 0; + Gla_ObjForEachFanin( p, pObj, pFanin, k ) + Count += pFanin->fAbs; + if ( Count == 0 || ((Round & 1) && Count == 1) ) + continue; + Vec_IntWriteEntry( vPPis, j++, Gla_ObjId(p, pObj) ); + } +// printf( "\n%d -> %d\n", Vec_IntSize(vPPis), j ); + Vec_IntShrink( vPPis, j ); +} + + +/**Function************************************************************* + + Synopsis [Adds CNF for the given timeframe.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame ) +{ + Gla_Obj_t * pGla = Gla_ManObj( p, iObj ); + int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame ); + assert( !pGla->fPo && !pGla->fRi ); + return (iVar > 0); +} +int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame ) +{ + Gla_Obj_t * pGla = Gla_ManObj( p, iObj ); + int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame ); + assert( !pGla->fPo && !pGla->fRi ); + if ( iVar == 0 ) + { + Vec_IntSetEntry( &pGla->vFrames, iFrame, (iVar = p->nSatVars++) ); + // remember the change + Vec_IntPush( p->vAddedNew, iObj ); + Vec_IntPush( p->vAddedNew, iFrame ); + } + return iVar; +} +void Gla_ManAddClauses( Gla_Man_t * p, int iObj, int iFrame, Vec_Int_t * vLits ) +{ + Gla_Obj_t * pGlaObj = Gla_ManObj( p, iObj ); + int iVar, iVar1, iVar2; + if ( pGlaObj->fConst ) + { + iVar = Gla_ManGetVar( p, iObj, iFrame ); + sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj ); + } + else if ( pGlaObj->fRo ) + { + assert( pGlaObj->nFanins == 1 ); + if ( iFrame == 0 ) + { + iVar = Gla_ManGetVar( p, iObj, iFrame ); + sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj ); + } + else + { + iVar1 = Gla_ManGetVar( p, iObj, iFrame ); + iVar2 = Gla_ManGetVar( p, pGlaObj->Fanins[0], iFrame-1 ); + sat_solver2_add_buffer( p->pSat, iVar1, iVar2, pGlaObj->fCompl0, 0, iObj ); + } + } + else if ( pGlaObj->fAnd ) + { + int i, RetValue, nClauses, iFirstClause, * pLit; + nClauses = p->pCnf->pObj2Count[pGlaObj->iGiaObj]; + iFirstClause = p->pCnf->pObj2Clause[pGlaObj->iGiaObj]; + for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) + { + Vec_IntClear( vLits ); + for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ ) + { + iVar = Gla_ManGetVar( p, lit_var(*pLit), iFrame ); + Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); + } + RetValue = sat_solver2_addclause( p->pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits), iObj ); + } + } + else assert( 0 ); +} +void Gia_GlaAddToCounters( Gla_Man_t * p, Vec_Int_t * vCore ) +{ + Gla_Obj_t * pGla; + int i; + Gla_ManForEachObjAbsVec( vCore, p, pGla, i ) + Vec_IntAddToEntry( p->vCoreCounts, pGla->iGiaObj, 1 ); +} +void Gia_GlaAddToAbs( Gla_Man_t * p, Vec_Int_t * vAbsAdd, int fCheck ) +{ + Gla_Obj_t * pGla; + int i, k = 0; + Gla_ManForEachObjAbsVec( vAbsAdd, p, pGla, i ) + { + if ( fCheck ) + { + assert( pGla->fAbs == 0 ); + if ( p->pSat->pPrf2 ) + Vec_IntWriteEntry( p->vProofIds, Gla_ObjId(p, pGla), p->nProofIds++ ); + } + if ( pGla->fAbs ) + continue; + pGla->fAbs = 1; + Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) ); + // filter clauses to remove those contained in the abstraction + Vec_IntWriteEntry( vAbsAdd, k++, Gla_ObjId(p, pGla) ); + } + Vec_IntShrink( vAbsAdd, k ); +} +void Gia_GlaAddTimeFrame( Gla_Man_t * p, int f ) +{ + Gla_Obj_t * pObj; + int i; + Gla_ManForEachObjAbs( p, pObj, i ) + Gla_ManAddClauses( p, Gla_ObjId(p, pObj), f, p->vTemp ); + sat_solver2_simplify( p->pSat ); +} +void Gia_GlaAddOneSlice( Gla_Man_t * p, int fCur, Vec_Int_t * vCore ) +{ + int f, i, iGlaObj; + for ( f = fCur; f >= 0; f-- ) + Vec_IntForEachEntry( vCore, iGlaObj, i ) + Gla_ManAddClauses( p, iGlaObj, f, p->vTemp ); + sat_solver2_simplify( p->pSat ); +} +void Gla_ManRollBack( Gla_Man_t * p ) +{ + int i, iObj, iFrame; + Vec_IntForEachEntryDouble( p->vAddedNew, iObj, iFrame, i ) + { + assert( Vec_IntEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame ) > 0 ); + Vec_IntWriteEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame, 0 ); + } + Vec_IntForEachEntryStart( p->vAbs, iObj, i, p->nAbsOld ) + { + assert( Gla_ManObj( p, iObj )->fAbs == 1 ); + Gla_ManObj( p, iObj )->fAbs = 0; + } + Vec_IntShrink( p->vAbs, p->nAbsOld ); +} + + + + + +/**Function************************************************************* + + Synopsis [Finds the set of clauses involved in the UNSAT core.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gla_ManGetOutLit( Gla_Man_t * p, int f ) +{ + Gla_Obj_t * pFanin = Gla_ManObj( p, p->pObjRoot->Fanins[0] ); + int iSat = Vec_IntEntry( &pFanin->vFrames, f ); + assert( iSat > 0 ); + if ( f == 0 && pFanin->fRo && !p->pObjRoot->fCompl0 ) + return -1; + return Abc_Var2Lit( iSat, p->pObjRoot->fCompl0 ); +} +Vec_Int_t * Gla_ManUnsatCore( Gla_Man_t * p, int f, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls ) +{ + Vec_Int_t * vCore = NULL; + int nConfPrev = pSat->stats.conflicts; + int RetValue, iLit = Gla_ManGetOutLit( p, f ); + clock_t clk = clock(); + if ( piRetValue ) + *piRetValue = 1; + // consider special case when PO points to the flop + // this leads to immediate conflict in the first timeframe + if ( iLit == -1 ) + { + vCore = Vec_IntAlloc( 1 ); + Vec_IntPush( vCore, p->pObjRoot->Fanins[0] ); + return vCore; + } + // solve the problem + RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( pnConfls ) + *pnConfls = (int)pSat->stats.conflicts - nConfPrev; + if ( RetValue == l_Undef ) + { + if ( piRetValue ) + *piRetValue = -1; + return NULL; + } + if ( RetValue == l_True ) + { + if ( piRetValue ) + *piRetValue = 0; + return NULL; + } + if ( fVerbose ) + { +// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev ); +// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts ); +// Abc_PrintTime( 1, "Time", clock() - clk ); + } + assert( RetValue == l_False ); + // derive the UNSAT core + clk = clock(); + vCore = (Vec_Int_t *)Sat_ProofCore( pSat ); + if ( vCore ) + Vec_IntSort( vCore, 1 ); + if ( fVerbose ) + { +// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) ); +// Abc_PrintTime( 1, "Time", clock() - clk ); + } + return vCore; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gla_ManAbsPrintFrame( Gla_Man_t * p, int nCoreSize, int nFrames, int nConfls, int nCexes, clock_t Time ) +{ + if ( Abc_FrameIsBatchMode() && nCoreSize <= 0 ) + return; + Abc_Print( 1, "%4d :", nFrames-1 ); + Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Gia_GlaAbsCount(p, 0, 0) / (p->nObjs - Gia_ManPoNum(p->pGia) + Gia_ManCoNum(p->pGia) + 1)) ); + Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 0) ); + Abc_Print( 1, "%5d", Gla_ManCountPPis(p) ); + Abc_Print( 1, "%5d", Gia_GlaAbsCount(p, 1, 0) ); + Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 1) ); + Abc_Print( 1, "%8d", nConfls ); + if ( nCexes == 0 ) + Abc_Print( 1, "%5c", '-' ); + else + Abc_Print( 1, "%5d", nCexes ); +// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) ); + Abc_PrintInt( sat_solver2_nvars(p->pSat) ); + Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); + Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); +// Abc_Print( 1, " %6d", nCoreSize > 0 ? nCoreSize : 0 ); + Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); + Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) ); +// Abc_PrintInt( p->nAbsNew ); +// Abc_PrintInt( p->nLrnNew ); +// Abc_Print( 1, "%4.1f MB", 4.0 * p->nLrnNew * Abc_BitWordNum(p->nAbsNew) / (1<<20) ); + Abc_Print( 1, "%s", (nCoreSize > 0 && nCexes > 0) ? "\n" : "\r" ); + fflush( stdout ); +} +void Gla_ManReportMemory( Gla_Man_t * p ) +{ + Gla_Obj_t * pGla; + double memTot = 0; + double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t); + double memSat = sat_solver2_memory( p->pSat, 1 ); + double memPro = sat_solver2_memory_proof( p->pSat ); + double memMap = p->nObjs * sizeof(Gla_Obj_t) + Gia_ManObjNum(p->pGia) * sizeof(int); + double memRef = Rnm_ManMemoryUsage( p->pRnm ); + double memOth = sizeof(Gla_Man_t); + for ( pGla = p->pObjs; pGla < p->pObjs + p->nObjs; pGla++ ) + memMap += Vec_IntCap(&pGla->vFrames) * sizeof(int); + memOth += Vec_IntCap(p->vAddedNew) * sizeof(int); + memOth += Vec_IntCap(p->vTemp) * sizeof(int); + memOth += Vec_IntCap(p->vAbs) * sizeof(int); + memTot = memAig + memSat + memPro + memMap + memRef + memOth; + ABC_PRMP( "Memory: AIG ", memAig, memTot ); + ABC_PRMP( "Memory: SAT ", memSat, memTot ); + ABC_PRMP( "Memory: Proof ", memPro, memTot ); + ABC_PRMP( "Memory: Map ", memMap, memTot ); + ABC_PRMP( "Memory: Refine ", memRef, memTot ); + ABC_PRMP( "Memory: Other ", memOth, memTot ); + ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); +} + + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GlaSendAbsracted( Gla_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); + Gia_Man_t * pAbs; + Vec_Int_t * vGateClasses; + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Sending abstracted model...\n" ); + // create abstraction (value of p->pGia is not used here) + vGateClasses = Gla_ManTranslate( p ); + pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses ); + Vec_IntFreeP( &vGateClasses ); + // send it out + Gia_ManToBridgeAbsNetlist( stdout, pAbs ); + Gia_ManStop( pAbs ); +} +void Gia_GlaSendCancel( Gla_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeBadAbs( FILE * pFile ); + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Cancelling previously sent model...\n" ); + Gia_ManToBridgeBadAbs( stdout ); +} + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GlaDumpAbsracted( Gla_Man_t * p, int fVerbose ) +{ + char * pFileNameDef = "glabs.aig"; + char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef; + Gia_Man_t * pAbs; + Vec_Int_t * vGateClasses; + if ( fVerbose ) + Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); + // create abstraction + vGateClasses = Gla_ManTranslate( p ); + pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses ); + Vec_IntFreeP( &vGateClasses ); + // write into file + Gia_WriteAiger( pAbs, pFileName, 0, 0 ); + Gia_ManStop( pAbs ); +} + + +/**Function************************************************************* + + Synopsis [Performs gate-level abstraction] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManPerformGlaOld( Gia_Man_t * pAig, Abs_Par_t * pPars, int fStartVta ) +{ + extern int Gia_VtaPerformInt( Gia_Man_t * pAig, Abs_Par_t * pPars ); + extern void Ga2_ManDumpStats( Gia_Man_t * pGia, Abs_Par_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN ); + Gla_Man_t * p; + Vec_Int_t * vPPis, * vCore;//, * vCore2 = NULL; + Abc_Cex_t * pCex = NULL; + int f, i, iPrev, nConfls, Status, nVarsOld = 0, nCoreSize, fOneIsSent = 0, RetValue = -1; + clock_t clk2, clk = clock(); + // preconditions + assert( Gia_ManPoNum(pAig) == 1 ); + assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) + { + if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) + { + printf( "Sequential miter is trivially UNSAT.\n" ); + return 1; + } + ABC_FREE( pAig->pCexSeq ); + pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); + printf( "Sequential miter is trivially SAT.\n" ); + return 0; + } + + // compute intial abstraction + if ( pAig->vGateClasses == NULL ) + { + if ( fStartVta ) + { + int nFramesMaxOld = pPars->nFramesMax; + int nFramesStartOld = pPars->nFramesStart; + int nTimeOutOld = pPars->nTimeOut; + int nDumpOld = pPars->fDumpVabs; + pPars->nFramesMax = pPars->nFramesStart; + pPars->nFramesStart = Abc_MinInt( pPars->nFramesStart/2 + 1, 3 ); + pPars->nTimeOut = 20; + pPars->fDumpVabs = 0; + RetValue = Gia_VtaPerformInt( pAig, pPars ); + pPars->nFramesMax = nFramesMaxOld; + pPars->nFramesStart = nFramesStartOld; + pPars->nTimeOut = nTimeOutOld; + pPars->fDumpVabs = nDumpOld; + // create gate classes + Vec_IntFreeP( &pAig->vGateClasses ); + if ( pAig->vObjClasses ) + pAig->vGateClasses = Gia_VtaConvertToGla( pAig, pAig->vObjClasses ); + Vec_IntFreeP( &pAig->vObjClasses ); + // return if VTA solve the problem if could not start + if ( RetValue == 0 || pAig->vGateClasses == NULL ) + return RetValue; + } + else + { + pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) ); + Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 ); + Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 ); + } + } + // start the manager + p = Gla_ManStart( pAig, pPars ); + p->timeInit = clock() - clk; + // set runtime limit + if ( p->pPars->nTimeOut ) + sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() ); + // perform initial abstraction + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" ); + Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%.\n", + pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin ); + Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n", + pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce ); + Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" ); + } + for ( f = i = iPrev = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++, iPrev = i ) + { + int nConflsBeg = sat_solver2_nconflicts(p->pSat); + p->pPars->iFrame = f; + + // load timeframe + Gia_GlaAddTimeFrame( p, f ); + + // iterate as long as there are counter-examples + for ( i = 0; ; i++ ) + { + clk2 = clock(); + vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls ); +// assert( (vCore != NULL) == (Status == 1) ); + if ( Status == -1 || (p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit) ) // resource limit is reached + { + Prf_ManStopP( &p->pSat->pPrf2 ); +// if ( Gia_ManRegNum(p->pGia) > 1 ) // for comb cases, return the abstraction +// Vec_IntShrink( p->vAbs, p->nAbsOld ); + goto finish; + } + if ( Status == 1 ) + { + Prf_ManStopP( &p->pSat->pPrf2 ); + p->timeUnsat += clock() - clk2; + break; + } + p->timeSat += clock() - clk2; + assert( Status == 0 ); + p->nCexes++; + + // cancel old one if it was sent + if ( Abc_FrameIsBridgeMode() && fOneIsSent ) + { + Gia_GlaSendCancel( p, pPars->fVerbose ); + fOneIsSent = 0; + } + + // perform the refinement + clk2 = clock(); + if ( pPars->fAddLayer ) + { + vPPis = Gla_ManCollectPPis( p, NULL ); +// Gla_ManExplorePPis( p, vPPis ); + } + else + { + vPPis = Gla_ManRefinement( p ); + if ( vPPis == NULL ) + { + Prf_ManStopP( &p->pSat->pPrf2 ); + pCex = p->pGia->pCexSeq; p->pGia->pCexSeq = NULL; + break; + } + } + assert( pCex == NULL ); + + // start proof logging + if ( i == 0 ) + { + // create bookmark to be used for rollback + sat_solver2_bookmark( p->pSat ); + Vec_IntClear( p->vAddedNew ); + p->nAbsOld = Vec_IntSize( p->vAbs ); + nVarsOld = p->nSatVars; +// p->nLrnOld = sat_solver2_nlearnts( p->pSat ); +// p->nAbsNew = 0; +// p->nLrnNew = 0; + + // start incremental proof manager + assert( p->pSat->pPrf2 == NULL ); + if ( p->pSat->pPrf1 == NULL ) + p->pSat->pPrf2 = Prf_ManAlloc(); + if ( p->pSat->pPrf2 ) + { + p->nProofIds = 0; + Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 ); + Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) ); + } + } + else + { + // resize the proof logger + if ( p->pSat->pPrf2 ) + Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) ); + } + + Gia_GlaAddToAbs( p, vPPis, 1 ); + Gia_GlaAddOneSlice( p, f, vPPis ); + Vec_IntFree( vPPis ); + + // print the result (do not count it towards change) + if ( p->pPars->fVerbose ) + Gla_ManAbsPrintFrame( p, -1, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk ); + } + if ( pCex != NULL ) + break; + assert( Status == 1 ); + + // valid core is obtained + nCoreSize = 1; + if ( vCore ) + { + nCoreSize += Vec_IntSize( vCore ); + Gia_GlaAddToCounters( p, vCore ); + } + if ( i == 0 ) + { + p->pPars->nFramesNoChange++; + Vec_IntFreeP( &vCore ); + } + else + { + p->pPars->nFramesNoChange = 0; +// p->nAbsNew = Vec_IntSize( p->vAbs ) - p->nAbsOld; +// p->nLrnNew = Abc_AbsInt( sat_solver2_nlearnts( p->pSat ) - p->nLrnOld ); + // update the SAT solver + sat_solver2_rollback( p->pSat ); + // update storage + Gla_ManRollBack( p ); + p->nSatVars = nVarsOld; + // load this timeframe + Gia_GlaAddToAbs( p, vCore, 0 ); + Gia_GlaAddOneSlice( p, f, vCore ); + Vec_IntFree( vCore ); + // run SAT solver + clk2 = clock(); + vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls ); + p->timeUnsat += clock() - clk2; +// assert( (vCore != NULL) == (Status == 1) ); + Vec_IntFreeP( &vCore ); + if ( Status == -1 ) // resource limit is reached + break; + if ( Status == 0 ) + { + assert( 0 ); + // Vta_ManSatVerify( p ); + // make sure, there was no initial abstraction (otherwise, it was invalid) + assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart ); + // pCex = Vga_ManDeriveCex( p ); + break; + } + } + // print the result + if ( p->pPars->fVerbose ) + Gla_ManAbsPrintFrame( p, nCoreSize, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk ); + + if ( f > 2 && iPrev > 0 && i == 0 ) // change has happened + { + if ( Abc_FrameIsBridgeMode() ) + { + // cancel old one if it was sent + if ( fOneIsSent ) + Gia_GlaSendCancel( p, pPars->fVerbose ); + // send new one + Gia_GlaSendAbsracted( p, pPars->fVerbose ); + fOneIsSent = 1; + } + + // dump the model into file + if ( p->pPars->fDumpVabs ) + { + char Command[1000]; + Abc_FrameSetStatus( -1 ); + Abc_FrameSetCex( NULL ); + Abc_FrameSetNFrames( f+1 ); + sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") ); + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); + Gia_GlaDumpAbsracted( p, pPars->fVerbose ); + } + } + + // check if the number of objects is below limit + if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 ) + { + Status = -1; + break; + } + } +finish: + // analize the results + if ( pCex == NULL ) + { + if ( p->pPars->fVerbose && Status == -1 ) + printf( "\n" ); +// if ( pAig->vGateClasses != NULL ) +// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); + Vec_IntFreeP( &pAig->vGateClasses ); + pAig->vGateClasses = Gla_ManTranslate( p ); + if ( Status == -1 ) + { + if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) + Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange ); + else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) + Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange ); + else if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 ) + Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f ); + else + Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f ); + } + else + { + p->pPars->iFrame++; + Abc_Print( 1, "GLA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange ); + } + } + else + { + if ( p->pPars->fVerbose ) + printf( "\n" ); + ABC_FREE( pAig->pCexSeq ); + pAig->pCexSeq = pCex; + if ( !Gia_ManVerifyCex( pAig, pCex, 0 ) ) + Abc_Print( 1, " Gia_ManPerformGlaOld(): CEX verification has failed!\n" ); + Abc_Print( 1, "Counter-example detected in frame %d. ", f ); + p->pPars->iFrame = pCex->iFrame - 1; + Vec_IntFreeP( &pAig->vGateClasses ); + RetValue = 0; + } + Abc_PrintTime( 1, "Time", clock() - clk ); + if ( p->pPars->fVerbose ) + { + p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit; + ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk ); + ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); + ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); + ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); + ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); + ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); + Gla_ManReportMemory( p ); + } +// Ga2_ManDumpStats( pAig, p->pPars, p->pSat, p->pPars->iFrame, 1 ); + Gla_ManStop( p ); + fflush( stdout ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absIter.c b/src/proof/abs/absIter.c new file mode 100644 index 00000000..88cbe39d --- /dev/null +++ b/src/proof/abs/absIter.c @@ -0,0 +1,147 @@ +/**CFile**************************************************************** + + FileName [absIter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Iterative improvement of abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Gia_ObjIsInGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)); } +static inline void Gia_ObjAddToGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 1); } +static inline void Gia_ObjRemFromGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 0); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_IterTryImprove( Gia_Man_t * p, int nTimeOut, int iFrame0 ) +{ + Gia_Man_t * pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); + Aig_Man_t * pAig = Gia_ManToAigSimple( pAbs ); + int nStart = 0; + int nFrames = iFrame0 ? iFrame0 + 1 : 10000000; + int nNodeDelta = 2000; + int nBTLimit = 0; + int nBTLimitAll = 0; + int fVerbose = 0; + int RetValue, iFrame; + RetValue = Saig_BmcPerform( pAig, nStart, nFrames, nNodeDelta, nTimeOut, nBTLimit, nBTLimitAll, fVerbose, 0, &iFrame, 1 ); + assert( RetValue == 0 || RetValue == -1 ); + Aig_ManStop( pAig ); + Gia_ManStop( pAbs ); + return iFrame; +} +Gia_Man_t * Gia_ManShrinkGla( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose ) +{ + Gia_Obj_t * pObj; + int i, iFrame0, iFrame; + int nTotal = 0, nRemoved = 0; + Vec_Int_t * vGScopy; + clock_t clk, clkTotal = clock(); + assert( Gia_ManPoNum(p) == 1 ); + assert( p->vGateClasses != NULL ); + vGScopy = Vec_IntDup( p->vGateClasses ); + if ( nFrameMax == 0 ) + iFrame0 = Gia_IterTryImprove( p, 0, 0 ); + else + iFrame0 = nFrameMax - 1; + while ( 1 ) + { + int fChanges = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( pObj->fMark0 ) + continue; + if ( !Gia_ObjIsInGla(p, pObj) ) + continue; + if ( pObj == Gia_ObjFanin0( Gia_ManPo(p, 0) ) ) + continue; + if ( Gia_ObjIsAnd(pObj) ) + { + if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(pObj)) && Gia_ObjIsInGla(p, Gia_ObjFanin1(pObj)) ) + continue; + } + if ( Gia_ObjIsRo(p, pObj) ) + { + if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj))) ) + continue; + } + clk = clock(); + printf( "%5d : ", nTotal ); + printf( "Obj =%7d ", i ); + Gia_ObjRemFromGla( p, pObj ); + iFrame = Gia_IterTryImprove( p, nTimeOut, iFrame0 ); + if ( nFrameMax ) + assert( iFrame <= nFrameMax ); + else + assert( iFrame <= iFrame0 ); + printf( "Frame =%6d ", iFrame ); + if ( iFrame < iFrame0 ) + { + pObj->fMark0 = 1; + Gia_ObjAddToGla( p, pObj ); + printf( " " ); + } + else + { + fChanges = 1; + nRemoved++; + printf( "Removing " ); + Vec_IntWriteEntry( vGScopy, Gia_ObjId(p, pObj), 0 ); + } + Abc_PrintTime( 1, "Time", clock() - clk ); + nTotal++; + // update the classes + Vec_IntFreeP( &p->vGateClasses ); + p->vGateClasses = Vec_IntDup(vGScopy); + } + if ( !fChanges ) + break; + } + Gia_ManCleanMark0(p); + Vec_IntFree( vGScopy ); + printf( "Tried = %d. ", nTotal ); + printf( "Removed = %d. (%.2f %%) ", nRemoved, 100.0 * nRemoved / Vec_IntCountPositive(p->vGateClasses) ); + Abc_PrintTime( 1, "Time", clock() - clkTotal ); + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absOldCex.c b/src/proof/abs/absOldCex.c new file mode 100644 index 00000000..fec6d152 --- /dev/null +++ b/src/proof/abs/absOldCex.c @@ -0,0 +1,872 @@ +/**CFile**************************************************************** + + FileName [saigAbsCba.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [CEX-based abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigAbsCba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// local manager +typedef struct Saig_ManCba_t_ Saig_ManCba_t; +struct Saig_ManCba_t_ +{ + // user data + Aig_Man_t * pAig; // user's AIG + Abc_Cex_t * pCex; // user's CEX + int nInputs; // the number of first inputs to skip + int fVerbose; // verbose flag + // unrolling + Aig_Man_t * pFrames; // unrolled timeframes + Vec_Int_t * vMapPiF2A; // mapping of frame PIs into real PIs + // additional information + Vec_Vec_t * vReg2Frame; // register to frame mapping + Vec_Vec_t * vReg2Value; // register to value mapping +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Selects the best flops from the given array.] + + Description [Selects the best 'nFfsToSelect' flops among the array + 'vAbsFfsToAdd' of flops that should be added to the abstraction. + To this end, this procedure simulates the original AIG (pAig) using + the given CEX (pAbsCex), which was detected for the abstraction.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect ) +{ + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + Vec_Int_t * vMapEntries, * vFlopCosts, * vFlopAddCosts, * vFfsToAddBest; + int i, k, f, Entry, iBit, * pPerm; + assert( Aig_ManRegNum(pAig) == Vec_IntSize(vFlopClasses) ); + assert( Vec_IntSize(vAbsFfsToAdd) > nFfsToSelect ); + // map previously abstracted flops into their original numbers + vMapEntries = Vec_IntAlloc( Vec_IntSize(vFlopClasses) ); + Vec_IntForEachEntry( vFlopClasses, Entry, i ) + if ( Entry == 0 ) + Vec_IntPush( vMapEntries, i ); + // simulate one frame at a time + assert( Saig_ManPiNum(pAig) + Vec_IntSize(vMapEntries) == pAbsCex->nPis ); + vFlopCosts = Vec_IntStart( Vec_IntSize(vMapEntries) ); + // initialize the flops + Aig_ManCleanMarkB(pAig); + Aig_ManConst1(pAig)->fMarkB = 1; + Saig_ManForEachLo( pAig, pObj, i ) + pObj->fMarkB = 0; + for ( f = 0; f < pAbsCex->iFrame; f++ ) + { + // override the flop values according to the cex + iBit = pAbsCex->nRegs + f * pAbsCex->nPis + Saig_ManPiNum(pAig); + Vec_IntForEachEntry( vMapEntries, Entry, k ) + Saig_ManLo(pAig, Entry)->fMarkB = Abc_InfoHasBit(pAbsCex->pData, iBit + k); + // simulate + Aig_ManForEachNode( pAig, pObj, k ) + pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & + (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj)); + Aig_ManForEachCo( pAig, pObj, k ) + pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); + // transfer + Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMarkB = pObjRi->fMarkB; + // compare + iBit = pAbsCex->nRegs + (f + 1) * pAbsCex->nPis + Saig_ManPiNum(pAig); + Vec_IntForEachEntry( vMapEntries, Entry, k ) + if ( Saig_ManLi(pAig, Entry)->fMarkB != (unsigned)Abc_InfoHasBit(pAbsCex->pData, iBit + k) ) + Vec_IntAddToEntry( vFlopCosts, k, 1 ); + } +// Vec_IntForEachEntry( vFlopCosts, Entry, i ) +// printf( "%d ", Entry ); +// printf( "\n" ); + // remap the cost + vFlopAddCosts = Vec_IntAlloc( Vec_IntSize(vAbsFfsToAdd) ); + Vec_IntForEachEntry( vAbsFfsToAdd, Entry, i ) + Vec_IntPush( vFlopAddCosts, -Vec_IntEntry(vFlopCosts, Entry) ); + // sort the flops + pPerm = Abc_MergeSortCost( Vec_IntArray(vFlopAddCosts), Vec_IntSize(vFlopAddCosts) ); + // shrink the array + vFfsToAddBest = Vec_IntAlloc( nFfsToSelect ); + for ( i = 0; i < nFfsToSelect; i++ ) + { +// printf( "%d ", Vec_IntEntry(vFlopAddCosts, pPerm[i]) ); + Vec_IntPush( vFfsToAddBest, Vec_IntEntry(vAbsFfsToAdd, pPerm[i]) ); + } +// printf( "\n" ); + // cleanup + ABC_FREE( pPerm ); + Vec_IntFree( vMapEntries ); + Vec_IntFree( vFlopCosts ); + Vec_IntFree( vFlopAddCosts ); + Aig_ManCleanMarkB(pAig); + // return the computed flops + return vFfsToAddBest; +} + + +/**Function************************************************************* + + Synopsis [Duplicate with literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupWithCubes( Aig_Man_t * pAig, Vec_Vec_t * vReg2Value ) +{ + Vec_Int_t * vLevel; + Aig_Man_t * pAigNew; + Aig_Obj_t * pObj, * pMiter; + int i, k, Lit; + assert( pAig->nConstrs == 0 ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) + Vec_VecSizeSize(vReg2Value) ); + pAigNew->pName = Abc_UtilStrsav( pAig->pName ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachCi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreateCi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create POs for cubes + Vec_VecForEachLevelInt( vReg2Value, vLevel, i ) + { + pMiter = Aig_ManConst1( pAigNew ); + Vec_IntForEachEntry( vLevel, Lit, k ) + { + pObj = Saig_ManLi( pAig, Abc_Lit2Var(Lit) ); + pMiter = Aig_And( pAigNew, pMiter, Aig_NotCond(Aig_ObjChild0Copy(pObj), Abc_LitIsCompl(Lit)) ); + } + Aig_ObjCreateCo( pAigNew, pMiter ); + } + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) ); + // finalize + Aig_ManCleanup( pAigNew ); + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) ); + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Maps array of frame PI IDs into array of additional PI IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManCbaReason2Inputs( Saig_ManCba_t * p, Vec_Int_t * vReasons ) +{ + Vec_Int_t * vOriginal, * vVisited; + int i, Entry; + vOriginal = Vec_IntAlloc( Saig_ManPiNum(p->pAig) ); + vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) ); + Vec_IntForEachEntry( vReasons, Entry, i ) + { + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); + assert( iInput >= p->nInputs && iInput < Aig_ManCiNum(p->pAig) ); + if ( Vec_IntEntry(vVisited, iInput) == 0 ) + Vec_IntPush( vOriginal, iInput - p->nInputs ); + Vec_IntAddToEntry( vVisited, iInput, 1 ); + } + Vec_IntFree( vVisited ); + return vOriginal; +} + +/**Function************************************************************* + + Synopsis [Creates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_ManCbaReason2Cex( Saig_ManCba_t * p, Vec_Int_t * vReasons ) +{ + Abc_Cex_t * pCare; + int i, Entry, iInput, iFrame; + pCare = Abc_CexDup( p->pCex, p->pCex->nRegs ); + memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); + Vec_IntForEachEntry( vReasons, Entry, i ) + { + assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pFrames) ); + iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); + iFrame = Vec_IntEntry( p->vMapPiF2A, 2*Entry+1 ); + Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput ); + } +/* + for ( iFrame = 0; iFrame <= pCare->iFrame; iFrame++ ) + { + int Count = 0; + for ( i = 0; i < pCare->nPis; i++ ) + Count += Abc_InfoHasBit(pCare->pData, pCare->nRegs + pCare->nPis * iFrame + i); + printf( "%d ", Count ); + } +printf( "\n" ); +*/ + return pCare; +} + +/**Function************************************************************* + + Synopsis [Returns reasons for the property to fail.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManCbaFindReason_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vPrios, Vec_Int_t * vReasons ) +{ + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Aig_ObjIsConst1(pObj) ) + return; + if ( Aig_ObjIsCi(pObj) ) + { + Vec_IntPush( vReasons, Aig_ObjCioId(pObj) ); + return; + } + assert( Aig_ObjIsNode(pObj) ); + if ( pObj->fPhase ) + { + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + } + else + { + int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; + int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; + assert( !fPhase0 || !fPhase1 ); + if ( !fPhase0 && fPhase1 ) + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + else if ( fPhase0 && !fPhase1 ) + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + else + { + int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); + int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); + if ( iPrio0 <= iPrio1 ) + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + else + Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + } + } +} + +/**Function************************************************************* + + Synopsis [Returns reasons for the property to fail.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManCbaFindReason( Saig_ManCba_t * p ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vPrios, * vReasons; + int i; + + // set PI values according to CEX + vPrios = Vec_IntStartFull( Aig_ManObjNumMax(p->pFrames) ); + Aig_ManConst1(p->pFrames)->fPhase = 1; + Aig_ManForEachCi( p->pFrames, pObj, i ) + { + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i ); + int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 ); + pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), i ); + } + + // traverse and set the priority + Aig_ManForEachNode( p->pFrames, pObj, i ) + { + int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; + int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; + int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); + int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); + pObj->fPhase = fPhase0 && fPhase1; + if ( fPhase0 && fPhase1 ) // both are one + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MaxInt(iPrio0, iPrio1) ); + else if ( !fPhase0 && fPhase1 ) + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio0 ); + else if ( fPhase0 && !fPhase1 ) + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio1 ); + else // both are zero + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MinInt(iPrio0, iPrio1) ); + } + // check the property output + pObj = Aig_ManCo( p->pFrames, 0 ); + pObj->fPhase = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; + assert( !pObj->fPhase ); + + // select the reason + vReasons = Vec_IntAlloc( 100 ); + Aig_ManIncrementTravId( p->pFrames ); + Saig_ManCbaFindReason_rec( p->pFrames, Aig_ObjFanin0(pObj), vPrios, vReasons ); + Vec_IntFree( vPrios ); +// assert( !Aig_ObjIsTravIdCurrent(p->pFrames, Aig_ManConst1(p->pFrames)) ); + return vReasons; +} + + +/**Function************************************************************* + + Synopsis [Collect nodes in the unrolled timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManCbaUnrollCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots ) +{ + if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) + return; + Aig_ObjSetTravIdCurrent(pAig, pObj); + if ( Aig_ObjIsCo(pObj) ) + Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); + else if ( Aig_ObjIsNode(pObj) ) + { + Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); + Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots ); + } + if ( vRoots && Saig_ObjIsLo( pAig, pObj ) ) + Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) ); + Vec_IntPush( vObjs, Aig_ObjId(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derive unrolled timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManCbaUnrollWithCex( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, Vec_Int_t ** pvMapPiF2A, Vec_Vec_t ** pvReg2Frame ) +{ + Aig_Man_t * pFrames; // unrolled timeframes + Vec_Vec_t * vFrameCos; // the list of COs per frame + Vec_Vec_t * vFrameObjs; // the list of objects per frame + Vec_Int_t * vRoots, * vObjs; + Aig_Obj_t * pObj; + int i, f; + // sanity checks + assert( Saig_ManPiNum(pAig) == pCex->nPis ); +// assert( Saig_ManRegNum(pAig) == pCex->nRegs ); + assert( pCex->iPo >= 0 && pCex->iPo < Saig_ManPoNum(pAig) ); + + // map PIs of the unrolled frames into PIs of the original design + *pvMapPiF2A = Vec_IntAlloc( 1000 ); + + // collect COs and Objs visited in each frame + vFrameCos = Vec_VecStart( pCex->iFrame+1 ); + vFrameObjs = Vec_VecStart( pCex->iFrame+1 ); + // initialized the topmost frame + pObj = Aig_ManCo( pAig, pCex->iPo ); + Vec_VecPushInt( vFrameCos, pCex->iFrame, Aig_ObjId(pObj) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + { + // collect nodes starting from the roots + Aig_ManIncrementTravId( pAig ); + vRoots = Vec_VecEntryInt( vFrameCos, f ); + Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) + Saig_ManCbaUnrollCollect_rec( pAig, pObj, + Vec_VecEntryInt(vFrameObjs, f), + (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) ); + } + + // derive unrolled timeframes + pFrames = Aig_ManStart( 10000 ); + pFrames->pName = Abc_UtilStrsav( pAig->pName ); + pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec ); + // initialize the flops + if ( Saig_ManRegNum(pAig) == pCex->nRegs ) + { + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, i) ); + } + else // this is the case when synthesis was applied, assume all-0 init state + { + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), 1 ); + } + // iterate through the frames + for ( f = 0; f <= pCex->iFrame; f++ ) + { + // construct + vObjs = Vec_VecEntryInt( vFrameObjs, f ); + Aig_ManForEachObjVec( vObjs, pAig, pObj, i ) + { + if ( Aig_ObjIsNode(pObj) ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + else if ( Aig_ObjIsCo(pObj) ) + pObj->pData = Aig_ObjChild0Copy(pObj); + else if ( Aig_ObjIsConst1(pObj) ) + pObj->pData = Aig_ManConst1(pFrames); + else if ( Saig_ObjIsPi(pAig, pObj) ) + { + if ( Aig_ObjCioId(pObj) < nInputs ) + { + int iBit = pCex->nRegs + f * pCex->nPis + Aig_ObjCioId(pObj); + pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, iBit) ); + } + else + { + pObj->pData = Aig_ObjCreateCi( pFrames ); + Vec_IntPush( *pvMapPiF2A, Aig_ObjCioId(pObj) ); + Vec_IntPush( *pvMapPiF2A, f ); + } + } + } + if ( f == pCex->iFrame ) + break; + // transfer + vRoots = Vec_VecEntryInt( vFrameCos, f ); + Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) + { + Saig_ObjLiToLo( pAig, pObj )->pData = pObj->pData; + if ( *pvReg2Frame ) + { + Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjId(pObj) ); // record LO + Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjToLit((Aig_Obj_t *)pObj->pData) ); // record its literal + } + } + } + // create output + pObj = Aig_ManCo( pAig, pCex->iPo ); + Aig_ObjCreateCo( pFrames, Aig_Not((Aig_Obj_t *)pObj->pData) ); + Aig_ManSetRegNum( pFrames, 0 ); + // cleanup + Vec_VecFree( vFrameCos ); + Vec_VecFree( vFrameObjs ); + // finallize + Aig_ManCleanup( pFrames ); + // return + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Creates refinement manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Saig_ManCba_t * Saig_ManCbaStart( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ) +{ + Saig_ManCba_t * p; + p = ABC_CALLOC( Saig_ManCba_t, 1 ); + p->pAig = pAig; + p->pCex = pCex; + p->nInputs = nInputs; + p->fVerbose = fVerbose; + return p; +} + +/**Function************************************************************* + + Synopsis [Destroys refinement manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManCbaStop( Saig_ManCba_t * p ) +{ + Vec_VecFreeP( &p->vReg2Frame ); + Vec_VecFreeP( &p->vReg2Value ); + Aig_ManStopP( &p->pFrames ); + Vec_IntFreeP( &p->vMapPiF2A ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Destroys refinement manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManCbaShrink( Saig_ManCba_t * p ) +{ + Aig_Man_t * pManNew; + Aig_Obj_t * pObjLi, * pObjFrame; + Vec_Int_t * vLevel, * vLevel2; + int f, k, ObjId, Lit; + // assuming that important objects are labeled in Saig_ManCbaFindReason() + Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, f ) + { + Vec_IntForEachEntryDouble( vLevel, ObjId, Lit, k ) + { + pObjFrame = Aig_ManObj( p->pFrames, Abc_Lit2Var(Lit) ); + if ( pObjFrame == NULL || (!Aig_ObjIsConst1(pObjFrame) && !Aig_ObjIsTravIdCurrent(p->pFrames, pObjFrame)) ) + continue; + pObjLi = Aig_ManObj( p->pAig, ObjId ); + assert( Saig_ObjIsLi(p->pAig, pObjLi) ); + Vec_VecPushInt( p->vReg2Value, f, Abc_Var2Lit( Aig_ObjCioId(pObjLi) - Saig_ManPoNum(p->pAig), Abc_LitIsCompl(Lit) ^ !pObjFrame->fPhase ) ); + } + } + // print statistics + Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, k ) + { + vLevel2 = Vec_VecEntryInt( p->vReg2Value, k ); + printf( "Level = %4d StateBits = %4d (%6.2f %%) CareBits = %4d (%6.2f %%)\n", k, + Vec_IntSize(vLevel)/2, 100.0 * (Vec_IntSize(vLevel)/2) / Aig_ManRegNum(p->pAig), + Vec_IntSize(vLevel2), 100.0 * Vec_IntSize(vLevel2) / Aig_ManRegNum(p->pAig) ); + } + // try reducing the frames + pManNew = Saig_ManDupWithCubes( p->pAig, p->vReg2Value ); +// Ioa_WriteAiger( pManNew, "aigcube.aig", 0, 0 ); + Aig_ManStop( pManNew ); +} + +static inline void Saig_ObjCexMinSet0( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 0; } +static inline void Saig_ObjCexMinSet1( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; pObj->fMarkB = 1; } +static inline void Saig_ObjCexMinSetX( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 1; } + +static inline int Saig_ObjCexMinGet0( Aig_Obj_t * pObj ) { return pObj->fMarkA && !pObj->fMarkB; } +static inline int Saig_ObjCexMinGet1( Aig_Obj_t * pObj ) { return !pObj->fMarkA && pObj->fMarkB; } +static inline int Saig_ObjCexMinGetX( Aig_Obj_t * pObj ) { return pObj->fMarkA && pObj->fMarkB; } + +static inline int Saig_ObjCexMinGet0Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); } +static inline int Saig_ObjCexMinGet1Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); } + +static inline int Saig_ObjCexMinGet0Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); } +static inline int Saig_ObjCexMinGet1Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); } + +static inline void Saig_ObjCexMinSim( Aig_Obj_t * pObj ) +{ + if ( Aig_ObjIsAnd(pObj) ) + { + if ( Saig_ObjCexMinGet0Fanin0(pObj) || Saig_ObjCexMinGet0Fanin1(pObj) ) + Saig_ObjCexMinSet0( pObj ); + else if ( Saig_ObjCexMinGet1Fanin0(pObj) && Saig_ObjCexMinGet1Fanin1(pObj) ) + Saig_ObjCexMinSet1( pObj ); + else + Saig_ObjCexMinSetX( pObj ); + } + else if ( Aig_ObjIsCo(pObj) ) + { + if ( Saig_ObjCexMinGet0Fanin0(pObj) ) + Saig_ObjCexMinSet0( pObj ); + else if ( Saig_ObjCexMinGet1Fanin0(pObj) ) + Saig_ObjCexMinSet1( pObj ); + else + Saig_ObjCexMinSetX( pObj ); + } + else assert( 0 ); +} + +static inline void Saig_ObjCexMinPrint( Aig_Obj_t * pObj ) +{ + if ( Saig_ObjCexMinGet0(pObj) ) + printf( "0" ); + else if ( Saig_ObjCexMinGet1(pObj) ) + printf( "1" ); + else if ( Saig_ObjCexMinGetX(pObj) ) + printf( "X" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManCexVerifyUsingTernary( Aig_Man_t * pAig, Abc_Cex_t * pCex, Abc_Cex_t * pCare ) +{ + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + int i, f, iBit = 0; + assert( pCex->iFrame == pCare->iFrame ); + assert( pCex->nBits == pCare->nBits ); + assert( pCex->iPo < Saig_ManPoNum(pAig) ); + Saig_ObjCexMinSet1( Aig_ManConst1(pAig) ); + // set flops to the init state + Saig_ManForEachLo( pAig, pObj, i ) + { + assert( !Abc_InfoHasBit(pCex->pData, iBit) ); + assert( !Abc_InfoHasBit(pCare->pData, iBit) ); +// if ( Abc_InfoHasBit(pCare->pData, iBit++) ) + Saig_ObjCexMinSet0( pObj ); +// else +// Saig_ObjCexMinSetX( pObj ); + } + iBit = pCex->nRegs; + for ( f = 0; f <= pCex->iFrame; f++ ) + { + // init inputs + Saig_ManForEachPi( pAig, pObj, i ) + { + if ( Abc_InfoHasBit(pCare->pData, iBit++) ) + { + if ( Abc_InfoHasBit(pCex->pData, iBit-1) ) + Saig_ObjCexMinSet1( pObj ); + else + Saig_ObjCexMinSet0( pObj ); + } + else + Saig_ObjCexMinSetX( pObj ); + } + // simulate internal nodes + Aig_ManForEachNode( pAig, pObj, i ) + Saig_ObjCexMinSim( pObj ); + // simulate COs + Aig_ManForEachCo( pAig, pObj, i ) + Saig_ObjCexMinSim( pObj ); +/* + Aig_ManForEachObj( pAig, pObj, i ) + { + Aig_ObjPrint(pAig, pObj); + printf( " Value = " ); + Saig_ObjCexMinPrint( pObj ); + printf( "\n" ); + } +*/ + // transfer + Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, i ) + pObjRo->fMarkA = pObjRi->fMarkA, + pObjRo->fMarkB = pObjRi->fMarkB; + } + assert( iBit == pCex->nBits ); + return Saig_ObjCexMinGet1( Aig_ManCo( pAig, pCex->iPo ) ); +} + +/**Function************************************************************* + + Synopsis [SAT-based refinement of the counter-example.] + + Description [The first parameter (nInputs) indicates how many first + primary inputs to skip without considering as care candidates.] + + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ) +{ + Saig_ManCba_t * p; + Vec_Int_t * vReasons; + Abc_Cex_t * pCare; + clock_t clk = clock(); + + clk = clock(); + p = Saig_ManCbaStart( pAig, pCex, nInputs, fVerbose ); + +// p->vReg2Frame = Vec_VecStart( pCex->iFrame ); +// p->vReg2Value = Vec_VecStart( pCex->iFrame ); + p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, nInputs, &p->vMapPiF2A, &p->vReg2Frame ); + vReasons = Saig_ManCbaFindReason( p ); + if ( p->vReg2Frame ) + Saig_ManCbaShrink( p ); + + +//if ( fVerbose ) +//Aig_ManPrintStats( p->pFrames ); + + if ( fVerbose ) + { + Vec_Int_t * vRes = Saig_ManCbaReason2Inputs( p, vReasons ); + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); + Vec_IntFree( vRes ); +ABC_PRT( "Time", clock() - clk ); + } + + pCare = Saig_ManCbaReason2Cex( p, vReasons ); + Vec_IntFree( vReasons ); + Saig_ManCbaStop( p ); + +if ( fVerbose ) +{ +printf( "Real " ); +Abc_CexPrintStats( pCex ); +} +if ( fVerbose ) +{ +printf( "Care " ); +Abc_CexPrintStats( pCare ); +} +/* + // verify the reduced counter-example using ternary simulation + if ( !Saig_ManCexVerifyUsingTernary( pAig, pCex, pCare ) ) + printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification has failed!!!\n" ); + else if ( fVerbose ) + printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification is successful.\n" ); +*/ + Aig_ManCleanMarkAB( pAig ); + return pCare; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManCbaFilterInputs( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) +{ + Saig_ManCba_t * p; + Vec_Int_t * vRes, * vReasons; + clock_t clk; + if ( Saig_ManPiNum(pAig) != pCex->nPis ) + { + printf( "Saig_ManCbaFilterInputs(): The PI count of AIG (%d) does not match that of cex (%d).\n", + Aig_ManCiNum(pAig), pCex->nPis ); + return NULL; + } + +clk = clock(); + p = Saig_ManCbaStart( pAig, pCex, iFirstFlopPi, fVerbose ); + p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, iFirstFlopPi, &p->vMapPiF2A, &p->vReg2Frame ); + vReasons = Saig_ManCbaFindReason( p ); + vRes = Saig_ManCbaReason2Inputs( p, vReasons ); + if ( fVerbose ) + { + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + } + + Vec_IntFree( vReasons ); + Saig_ManCbaStop( p ); + return vRes; +} + + + + +/**Function************************************************************* + + Synopsis [Checks the abstracted model for a counter-example.] + + Description [Returns the array of abstracted flops that should be added + to the abstraction.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManCbaPerform( Aig_Man_t * pAbs, int nInputs, Saig_ParBmc_t * pPars ) +{ + Vec_Int_t * vAbsFfsToAdd; + int RetValue; + clock_t clk = clock(); +// assert( pAbs->nRegs > 0 ); + // perform BMC + RetValue = Saig_ManBmcScalable( pAbs, pPars ); + if ( RetValue == -1 ) // time out - nothing to add + { + printf( "Resource limit is reached during BMC.\n" ); + assert( pAbs->pSeqModel == NULL ); + return Vec_IntAlloc( 0 ); + } + if ( pAbs->pSeqModel == NULL ) + { + printf( "BMC did not detect a CEX with the given depth.\n" ); + return Vec_IntAlloc( 0 ); + } + if ( pPars->fVerbose ) + Abc_CexPrintStats( pAbs->pSeqModel ); + // CEX is detected - refine the flops + vAbsFfsToAdd = Saig_ManCbaFilterInputs( pAbs, nInputs, pAbs->pSeqModel, pPars->fVerbose ); + if ( Vec_IntSize(vAbsFfsToAdd) == 0 ) + { + Vec_IntFree( vAbsFfsToAdd ); + return NULL; + } + if ( pPars->fVerbose ) + { + printf( "Adding %d registers to the abstraction (total = %d). ", + Vec_IntSize(vAbsFfsToAdd), Aig_ManRegNum(pAbs)+Vec_IntSize(vAbsFfsToAdd) ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } + return vAbsFfsToAdd; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absOldRef.c b/src/proof/abs/absOldRef.c new file mode 100644 index 00000000..dee28cad --- /dev/null +++ b/src/proof/abs/absOldRef.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [saigAbsStart.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Counter-example-based abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigAbsStart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" +#include "proof/ssw/ssw.h" +#include "proof/fra/fra.h" +#include "proof/bbr/bbr.h" +#include "proof/pdr/pdr.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derive a new counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs ) +{ + Abc_Cex_t * pCex; + Aig_Obj_t * pObj; + int i, f; + if ( !Saig_ManVerifyCex( pAbs, pCexAbs ) ) + printf( "Saig_ManCexRemap(): The initial counter-example is invalid.\n" ); +// else +// printf( "Saig_ManCexRemap(): The initial counter-example is correct.\n" ); + // start the counter-example + pCex = Abc_CexAlloc( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); + pCex->iFrame = pCexAbs->iFrame; + pCex->iPo = pCexAbs->iPo; + // copy the bit data + for ( f = 0; f <= pCexAbs->iFrame; f++ ) + { + Saig_ManForEachPi( pAbs, pObj, i ) + { + if ( i == Saig_ManPiNum(p) ) + break; + if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) ) + Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + i ); + } + } + // verify the counter example + if ( !Saig_ManVerifyCex( p, pCex ) ) + { + printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" ); + Abc_CexFree( pCex ); + pCex = NULL; + } + else + { + Abc_Print( 1, "Counter-example verification is successful.\n" ); + Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame ); + } + return pCex; +} + +/**Function************************************************************* + + Synopsis [Find the first PI corresponding to the flop.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManCexFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) +{ + Aig_Obj_t * pObj; + int i; + assert( pAbs->vCiNumsOrig != NULL ); + Aig_ManForEachCi( p, pObj, i ) + { + if ( Vec_IntEntry(pAbs->vCiNumsOrig, i) >= Saig_ManPiNum(p) ) + return i; + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using one step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int fVerbose, int * pnUseStart, int * piRetValue, int * pnFrames ) +{ + Vec_Int_t * vFlopsNew; + int i, Entry, RetValue; + *piRetValue = -1; + if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 ) + { +/* + Fra_Sec_t SecPar, * pSecPar = &SecPar; + Fra_SecSetDefaultParams( pSecPar ); + pSecPar->fVerbose = fVerbose; + RetValue = Fra_FraigSec( pAbs, pSecPar, NULL ); +*/ + Abc_Cex_t * pCex = NULL; + Aig_Man_t * pAbsOrpos = Saig_ManDupOrpos( pAbs ); + Pdr_Par_t Pars, * pPars = &Pars; + Pdr_ManSetDefaultParams( pPars ); + pPars->nTimeOut = 10; + pPars->fVerbose = fVerbose; + if ( pPars->fVerbose ) + printf( "Running property directed reachability...\n" ); + RetValue = Pdr_ManSolve( pAbsOrpos, pPars, &pCex ); + if ( pCex ) + pCex->iPo = Saig_ManFindFailedPoCex( pAbs, pCex ); + Aig_ManStop( pAbsOrpos ); + pAbs->pSeqModel = pCex; + if ( RetValue ) + *piRetValue = 1; + + } + else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) ) + { + Saig_ParBbr_t Pars, * pPars = &Pars; + Bbr_ManSetDefaultParams( pPars ); + pPars->TimeLimit = 0; + pPars->nBddMax = 1000000; + pPars->nIterMax = nFrames; + pPars->fPartition = 1; + pPars->fReorder = 1; + pPars->fReorderImage = 1; + pPars->fVerbose = fVerbose; + pPars->fSilent = 0; + RetValue = Aig_ManVerifyUsingBdds( pAbs, pPars ); + if ( RetValue ) + *piRetValue = 1; + } + else + { + Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 0, nConfMaxOne, 0, fVerbose, 0, pnFrames, 0 ); + } + if ( pAbs->pSeqModel == NULL ) + return NULL; + if ( pnUseStart ) + *pnUseStart = pAbs->pSeqModel->iFrame; +// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, 1, fVerbose ); + vFlopsNew = Saig_ManExtendCounterExampleTest3( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); + if ( vFlopsNew == NULL ) + return NULL; + if ( Vec_IntSize(vFlopsNew) == 0 ) + { + printf( "Discovered a true counter-example!\n" ); + p->pSeqModel = Saig_ManCexRemap( p, pAbs, pAbs->pSeqModel ); + Vec_IntFree( vFlopsNew ); + *piRetValue = 0; + return NULL; + } + // vFlopsNew contains PI numbers that should be kept in pAbs + if ( fVerbose ) + printf( "Adding %d registers to the abstraction (total = %d).\n\n", Vec_IntSize(vFlopsNew), Aig_ManRegNum(pAbs)+Vec_IntSize(vFlopsNew) ); + // add to the abstraction + Vec_IntForEachEntry( vFlopsNew, Entry, i ) + { + Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); + assert( Entry >= Saig_ManPiNum(p) ); + assert( Entry < Aig_ManCiNum(p) ); + Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); + } + Vec_IntFree( vFlopsNew ); + + Vec_IntSort( vFlops, 0 ); + Vec_IntForEachEntryStart( vFlops, Entry, i, 1 ) + assert( Vec_IntEntry(vFlops, i-1) != Entry ); + + return Saig_ManDupAbstraction( p, vFlops ); +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using one step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vFlopClasses, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ) +{ + Aig_Man_t * pAbs; + Vec_Int_t * vFlopsNew; + int i, Entry; + clock_t clk = clock(); + pAbs = Saig_ManDupAbstraction( p, vFlops ); + if ( fSensePath ) + vFlopsNew = Saig_ManExtendCounterExampleTest2( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); + else +// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fTryFour, fVerbose ); + vFlopsNew = Saig_ManExtendCounterExampleTest3( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); + if ( vFlopsNew == NULL ) + { + Aig_ManStop( pAbs ); + return 0; + } + if ( Vec_IntSize(vFlopsNew) == 0 ) + { + printf( "Refinement did not happen. Discovered a true counter-example.\n" ); + printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManCiNum(pAbs), Aig_ManCiNum(p) ); + p->pSeqModel = Saig_ManCexRemap( p, pAbs, pCex ); + Vec_IntFree( vFlopsNew ); + Aig_ManStop( pAbs ); + return 0; + } + if ( fVerbose ) + { + printf( "Adding %d registers to the abstraction (total = %d). ", Vec_IntSize(vFlopsNew), Aig_ManRegNum(p)+Vec_IntSize(vFlopsNew) ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } + // vFlopsNew contains PI numbers that should be kept in pAbs + // select the most useful flops among those to be added + if ( nFfToAddMax > 0 && Vec_IntSize(vFlopsNew) > nFfToAddMax ) + { + Vec_Int_t * vFlopsNewBest; + // shift the indices + Vec_IntForEachEntry( vFlopsNew, Entry, i ) + Vec_IntAddToEntry( vFlopsNew, i, -Saig_ManPiNum(p) ); + // create new flops + vFlopsNewBest = Saig_ManCbaFilterFlops( p, pCex, vFlopClasses, vFlopsNew, nFfToAddMax ); + assert( Vec_IntSize(vFlopsNewBest) == nFfToAddMax ); + printf( "Filtering flops based on cost (%d -> %d).\n", Vec_IntSize(vFlopsNew), Vec_IntSize(vFlopsNewBest) ); + // update + Vec_IntFree( vFlopsNew ); + vFlopsNew = vFlopsNewBest; + // shift the indices + Vec_IntForEachEntry( vFlopsNew, Entry, i ) + Vec_IntAddToEntry( vFlopsNew, i, Saig_ManPiNum(p) ); + } + // add to the abstraction + Vec_IntForEachEntry( vFlopsNew, Entry, i ) + { + Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); + assert( Entry >= Saig_ManPiNum(p) ); + assert( Entry < Aig_ManCiNum(p) ); + Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); + } + Vec_IntFree( vFlopsNew ); + Aig_ManStop( pAbs ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Transform flop map into flop list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses ) +{ + Vec_Int_t * vFlops; + int i, Entry; + vFlops = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vFlopClasses, Entry, i ) + if ( Entry ) + Vec_IntPush( vFlops, i ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Transform flop list into flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops ) +{ + Vec_Int_t * vFlopClasses; + int i, Entry; + vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) ); + Vec_IntForEachEntry( vFlops, Entry, i ) + Vec_IntWriteEntry( vFlopClasses, Entry, 1 ); + return vFlopClasses; +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using the latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose ) +{ + Aig_Man_t * pNew; + Vec_Int_t * vFlops; + if ( pGia->vFlopClasses == NULL ) + { + printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" ); + return -1; + } + pNew = Gia_ManToAig( pGia, 0 ); + vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); + if ( !Saig_ManCexRefineStep( pNew, vFlops, pGia->vFlopClasses, pCex, nFfToAddMax, fTryFour, fSensePath, fVerbose ) ) + { + pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return 0; + } + Vec_IntFree( pGia->vFlopClasses ); + pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return -1; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absOldSat.c b/src/proof/abs/absOldSat.c new file mode 100644 index 00000000..14f59667 --- /dev/null +++ b/src/proof/abs/absOldSat.c @@ -0,0 +1,986 @@ +/**CFile**************************************************************** + + FileName [saigRefSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [SAT based refinement of a counter-example.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigRefSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// local manager +typedef struct Saig_RefMan_t_ Saig_RefMan_t; +struct Saig_RefMan_t_ +{ + // user data + Aig_Man_t * pAig; // user's AIG + Abc_Cex_t * pCex; // user's CEX + int nInputs; // the number of first inputs to skip + int fVerbose; // verbose flag + // unrolling + Aig_Man_t * pFrames; // unrolled timeframes + Vec_Int_t * vMapPiF2A; // mapping of frame PIs into real PIs +}; + +// performs ternary simulation +extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Maps array of frame PI IDs into array of original PI IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_RefManReason2Inputs( Saig_RefMan_t * p, Vec_Int_t * vReasons ) +{ + Vec_Int_t * vOriginal, * vVisited; + int i, Entry; + vOriginal = Vec_IntAlloc( Saig_ManPiNum(p->pAig) ); + vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) ); + Vec_IntForEachEntry( vReasons, Entry, i ) + { + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); + assert( iInput >= 0 && iInput < Aig_ManCiNum(p->pAig) ); + if ( Vec_IntEntry(vVisited, iInput) == 0 ) + Vec_IntPush( vOriginal, iInput ); + Vec_IntAddToEntry( vVisited, iInput, 1 ); + } + Vec_IntFree( vVisited ); + return vOriginal; +} + +/**Function************************************************************* + + Synopsis [Creates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_RefManReason2Cex( Saig_RefMan_t * p, Vec_Int_t * vReasons ) +{ + Abc_Cex_t * pCare; + int i, Entry, iInput, iFrame; + pCare = Abc_CexDup( p->pCex, p->pCex->nRegs ); + memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); + Vec_IntForEachEntry( vReasons, Entry, i ) + { + assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pFrames) ); + iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry ); + iFrame = Vec_IntEntry( p->vMapPiF2A, 2*Entry+1 ); + Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput ); + } + return pCare; +} + +/**Function************************************************************* + + Synopsis [Returns reasons for the property to fail.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_RefManFindReason_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vPrios, Vec_Int_t * vReasons ) +{ + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Aig_ObjIsCi(pObj) ) + { + Vec_IntPush( vReasons, Aig_ObjCioId(pObj) ); + return; + } + assert( Aig_ObjIsNode(pObj) ); + if ( pObj->fPhase ) + { + Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + } + else + { + int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; + int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; + assert( !fPhase0 || !fPhase1 ); + if ( !fPhase0 && fPhase1 ) + Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + else if ( fPhase0 && !fPhase1 ) + Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + else + { + int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); + int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); + if ( iPrio0 <= iPrio1 ) + Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons ); + else + Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons ); + } + } +} + +/**Function************************************************************* + + Synopsis [Returns reasons for the property to fail.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_RefManFindReason( Saig_RefMan_t * p ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vPrios, * vPi2Prio, * vReasons; + int i, CountPrios; + + vPi2Prio = Vec_IntStartFull( Saig_ManPiNum(p->pAig) ); + vPrios = Vec_IntStartFull( Aig_ManObjNumMax(p->pFrames) ); + + // set PI values according to CEX + CountPrios = 0; + Aig_ManConst1(p->pFrames)->fPhase = 1; + Aig_ManForEachCi( p->pFrames, pObj, i ) + { + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i ); + int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 ); + pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); + // assign priority + if ( Vec_IntEntry(vPi2Prio, iInput) == ~0 ) + Vec_IntWriteEntry( vPi2Prio, iInput, CountPrios++ ); +// Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Vec_IntEntry(vPi2Prio, iInput) ); + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), i ); + } +// printf( "Priority numbers = %d.\n", CountPrios ); + Vec_IntFree( vPi2Prio ); + + // traverse and set the priority + Aig_ManForEachNode( p->pFrames, pObj, i ) + { + int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase; + int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase; + int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) ); + int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) ); + pObj->fPhase = fPhase0 && fPhase1; + if ( fPhase0 && fPhase1 ) // both are one + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MaxInt(iPrio0, iPrio1) ); + else if ( !fPhase0 && fPhase1 ) + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio0 ); + else if ( fPhase0 && !fPhase1 ) + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio1 ); + else // both are zero + Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MinInt(iPrio0, iPrio1) ); + } + // check the property output + pObj = Aig_ManCo( p->pFrames, 0 ); + assert( (int)Aig_ObjFanin0(pObj)->fPhase == Aig_ObjFaninC0(pObj) ); + + // select the reason + vReasons = Vec_IntAlloc( 100 ); + Aig_ManIncrementTravId( p->pFrames ); + if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) ) + Saig_RefManFindReason_rec( p->pFrames, Aig_ObjFanin0(pObj), vPrios, vReasons ); + Vec_IntFree( vPrios ); + return vReasons; +} + + +/**Function************************************************************* + + Synopsis [Collect nodes in the unrolled timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManUnrollCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots ) +{ + if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) + return; + Aig_ObjSetTravIdCurrent(pAig, pObj); + if ( Aig_ObjIsCo(pObj) ) + Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); + else if ( Aig_ObjIsNode(pObj) ) + { + Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots ); + Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots ); + } + if ( vRoots && Saig_ObjIsLo( pAig, pObj ) ) + Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) ); + Vec_IntPush( vObjs, Aig_ObjId(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derive unrolled timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollWithCex( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, Vec_Int_t ** pvMapPiF2A ) +{ + Aig_Man_t * pFrames; // unrolled timeframes + Vec_Vec_t * vFrameCos; // the list of COs per frame + Vec_Vec_t * vFrameObjs; // the list of objects per frame + Vec_Int_t * vRoots, * vObjs; + Aig_Obj_t * pObj; + int i, f; + // sanity checks + assert( Saig_ManPiNum(pAig) == pCex->nPis ); + assert( Saig_ManRegNum(pAig) == pCex->nRegs ); + assert( pCex->iPo >= 0 && pCex->iPo < Saig_ManPoNum(pAig) ); + + // map PIs of the unrolled frames into PIs of the original design + *pvMapPiF2A = Vec_IntAlloc( 1000 ); + + // collect COs and Objs visited in each frame + vFrameCos = Vec_VecStart( pCex->iFrame+1 ); + vFrameObjs = Vec_VecStart( pCex->iFrame+1 ); + // initialized the topmost frame + pObj = Aig_ManCo( pAig, pCex->iPo ); + Vec_VecPushInt( vFrameCos, pCex->iFrame, Aig_ObjId(pObj) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + { + // collect nodes starting from the roots + Aig_ManIncrementTravId( pAig ); + vRoots = Vec_VecEntryInt( vFrameCos, f ); + Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) + Saig_ManUnrollCollect_rec( pAig, pObj, + Vec_VecEntryInt(vFrameObjs, f), + (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) ); + } + + // derive unrolled timeframes + pFrames = Aig_ManStart( 10000 ); + pFrames->pName = Abc_UtilStrsav( pAig->pName ); + pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec ); + // initialize the flops + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, i) ); + // iterate through the frames + for ( f = 0; f <= pCex->iFrame; f++ ) + { + // construct + vObjs = Vec_VecEntryInt( vFrameObjs, f ); + Aig_ManForEachObjVec( vObjs, pAig, pObj, i ) + { + if ( Aig_ObjIsNode(pObj) ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + else if ( Aig_ObjIsCo(pObj) ) + pObj->pData = Aig_ObjChild0Copy(pObj); + else if ( Aig_ObjIsConst1(pObj) ) + pObj->pData = Aig_ManConst1(pFrames); + else if ( Saig_ObjIsPi(pAig, pObj) ) + { + if ( Aig_ObjCioId(pObj) < nInputs ) + { + int iBit = pCex->nRegs + f * pCex->nPis + Aig_ObjCioId(pObj); + pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, iBit) ); + } + else + { + pObj->pData = Aig_ObjCreateCi( pFrames ); + Vec_IntPush( *pvMapPiF2A, Aig_ObjCioId(pObj) ); + Vec_IntPush( *pvMapPiF2A, f ); + } + } + } + if ( f == pCex->iFrame ) + break; + // transfer + vRoots = Vec_VecEntryInt( vFrameCos, f ); + Aig_ManForEachObjVec( vRoots, pAig, pObj, i ) + Saig_ObjLiToLo( pAig, pObj )->pData = pObj->pData; + } + // create output + pObj = Aig_ManCo( pAig, pCex->iPo ); + Aig_ObjCreateCo( pFrames, Aig_Not((Aig_Obj_t *)pObj->pData) ); + Aig_ManSetRegNum( pFrames, 0 ); + // cleanup + Vec_VecFree( vFrameCos ); + Vec_VecFree( vFrameObjs ); + // finallize + Aig_ManCleanup( pFrames ); + // return + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Creates refinement manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Saig_RefMan_t * Saig_RefManStart( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose ) +{ + Saig_RefMan_t * p; + p = ABC_CALLOC( Saig_RefMan_t, 1 ); + p->pAig = pAig; + p->pCex = pCex; + p->nInputs = nInputs; + p->fVerbose = fVerbose; + p->pFrames = Saig_ManUnrollWithCex( pAig, pCex, nInputs, &p->vMapPiF2A ); + return p; +} + +/**Function************************************************************* + + Synopsis [Destroys refinement manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_RefManStop( Saig_RefMan_t * p ) +{ + Aig_ManStopP( &p->pFrames ); + Vec_IntFreeP( &p->vMapPiF2A ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Sets phase bits in the timeframe AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_RefManSetPhases( Saig_RefMan_t * p, Abc_Cex_t * pCare, int fValue1 ) +{ + Aig_Obj_t * pObj; + int i, iFrame, iInput; + Aig_ManConst1( p->pFrames )->fPhase = 1; + Aig_ManForEachCi( p->pFrames, pObj, i ) + { + iInput = Vec_IntEntry( p->vMapPiF2A, 2*i ); + iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 ); + pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); + // update value if it is a don't-care + if ( pCare && !Abc_InfoHasBit( pCare->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ) ) + pObj->fPhase = fValue1; + } + Aig_ManForEachNode( p->pFrames, pObj, i ) + pObj->fPhase = ( Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fPhase ^ Aig_ObjFaninC1(pObj) ); + Aig_ManForEachCo( p->pFrames, pObj, i ) + pObj->fPhase = ( Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj) ); + pObj = Aig_ManCo( p->pFrames, 0 ); + return pObj->fPhase; +} + +/**Function************************************************************* + + Synopsis [Tries to remove literals from abstraction.] + + Description [The literals are sorted more desirable first.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Saig_RefManOrderLiterals( Saig_RefMan_t * p, Vec_Int_t * vVar2PiId, Vec_Int_t * vAssumps ) +{ + Vec_Vec_t * vLits; + Vec_Int_t * vVar2New; + int i, Entry, iInput, iFrame; + // collect literals + vLits = Vec_VecAlloc( 100 ); + vVar2New = Vec_IntStartFull( Saig_ManPiNum(p->pAig) ); + Vec_IntForEachEntry( vAssumps, Entry, i ) + { + int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) ); + assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) ); + iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum ); + iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 ); +// Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput ); + if ( Vec_IntEntry( vVar2New, iInput ) == ~0 ) + Vec_IntWriteEntry( vVar2New, iInput, Vec_VecSize(vLits) ); + Vec_VecPushInt( vLits, Vec_IntEntry( vVar2New, iInput ), Entry ); + } + Vec_IntFree( vVar2New ); + return vLits; +} + + +/**Function************************************************************* + + Synopsis [Generate the care set using SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_RefManCreateCex( Saig_RefMan_t * p, Vec_Int_t * vVar2PiId, Vec_Int_t * vAssumps ) +{ + Abc_Cex_t * pCare; + int i, Entry, iInput, iFrame; + // create counter-example + pCare = Abc_CexDup( p->pCex, p->pCex->nRegs ); + memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); + Vec_IntForEachEntry( vAssumps, Entry, i ) + { + int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) ); + assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) ); + iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum ); + iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 ); + Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput ); + } + return pCare; +} + +/**Function************************************************************* + + Synopsis [Generate the care set using SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_RefManRunSat( Saig_RefMan_t * p, int fNewOrder ) +{ + int nConfLimit = 1000000; + Abc_Cex_t * pCare; + Cnf_Dat_t * pCnf; + sat_solver * pSat; + Aig_Obj_t * pObj; + Vec_Vec_t * vLits = NULL; + Vec_Int_t * vAssumps, * vVar2PiId; + int i, k, Entry, RetValue;//, f = 0, Counter = 0; + int nCoreLits, * pCoreLits; + clock_t clk = clock(); + // create CNF + assert( Aig_ManRegNum(p->pFrames) == 0 ); +// pCnf = Cnf_Derive( p->pFrames, 0 ); // too slow + pCnf = Cnf_DeriveSimple( p->pFrames, 0 ); + RetValue = Saig_RefManSetPhases( p, NULL, 0 ); + if ( RetValue ) + { + printf( "Constructed frames are incorrect.\n" ); + Cnf_DataFree( pCnf ); + return NULL; + } + Cnf_DataTranformPolarity( pCnf, 0 ); + // create SAT solver + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( pSat == NULL ) + { + Cnf_DataFree( pCnf ); + return NULL; + } +//Abc_PrintTime( 1, "Preparing", clock() - clk ); + // look for a true counter-example + if ( p->nInputs > 0 ) + { + RetValue = sat_solver_solve( pSat, NULL, NULL, + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_False ) + { + printf( "The problem is trivially UNSAT. The CEX is real.\n" ); + // create counter-example + pCare = Abc_CexDup( p->pCex, p->pCex->nRegs ); + memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) ); + return pCare; + } + // the problem is SAT - it is expected + } + // create assumptions + vVar2PiId = Vec_IntStartFull( pCnf->nVars ); + vAssumps = Vec_IntAlloc( Aig_ManCiNum(p->pFrames) ); + Aig_ManForEachCi( p->pFrames, pObj, i ) + { +// RetValue = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); +// Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !RetValue ) ); + Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 1 ) ); + Vec_IntWriteEntry( vVar2PiId, pCnf->pVarNums[Aig_ObjId(pObj)], i ); + } + + // reverse the order of assumptions +// if ( fNewOrder ) +// Vec_IntReverseOrder( vAssumps ); + + if ( fNewOrder ) + { + // create literals + vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps ); + // sort literals + Vec_VecSort( vLits, 1 ); + // save literals + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + Vec_IntPush( vAssumps, Entry ); + + for ( i = 0; i < Vec_VecSize(vLits); i++ ) + printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) ); + printf( "\n" ); + + if ( p->fVerbose ) + printf( "Total PIs = %d. Essential PIs = %d.\n", + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_VecSize(vLits) ); + } + + // solve +clk = clock(); + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); +//Abc_PrintTime( 1, "Solving", clock() - clk ); + if ( RetValue != l_False ) + { + if ( RetValue == l_True ) + printf( "Internal Error!!! The resulting problem is SAT.\n" ); + else + printf( "Internal Error!!! SAT solver timed out.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vAssumps ); + Vec_IntFree( vVar2PiId ); + return NULL; + } + assert( RetValue == l_False ); // UNSAT + + // get relevant SAT literals + nCoreLits = sat_solver_final( pSat, &pCoreLits ); + assert( nCoreLits > 0 ); + if ( p->fVerbose ) + printf( "AnalizeFinal selected %d assumptions (out of %d). Conflicts = %d.\n", + nCoreLits, Vec_IntSize(vAssumps), (int)pSat->stats.conflicts ); + + // save literals + Vec_IntClear( vAssumps ); + for ( i = 0; i < nCoreLits; i++ ) + Vec_IntPush( vAssumps, pCoreLits[i] ); + + + // create literals + vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps ); + // sort literals +// Vec_VecSort( vLits, 0 ); + // save literals + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + Vec_IntPush( vAssumps, Entry ); + +// for ( i = 0; i < Vec_VecSize(vLits); i++ ) +// printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) ); +// printf( "\n" ); + + if ( p->fVerbose ) + printf( "Total PIs = %d. Essential PIs = %d.\n", + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_VecSize(vLits) ); +/* + // try assumptions in different order + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n", + Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts ); + + // create different sets of assumptions + Counter = Vec_VecSize(vLits); + for ( f = 0; f < Vec_VecSize(vLits); f++ ) + { + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + if ( i != f ) + Vec_IntPush( vAssumps, Entry ); + + // try the new assumptions + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n", + Vec_IntSize(vAssumps), RetValue == l_False ? "UNSAT" : "SAT", (int)pSat->stats.conflicts ); + if ( RetValue != l_False ) + continue; + + // UNSAT - remove literals + Vec_IntClear( Vec_VecEntryInt(vLits, f) ); + Counter--; + } + + for ( i = 0; i < Vec_VecSize(vLits); i++ ) + printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) ); + printf( "\n" ); + + if ( p->fVerbose ) + printf( "Total PIs = %d. Essential PIs = %d.\n", + Saig_ManPiNum(p->pAig) - p->nInputs, Counter ); + + // save literals + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + Vec_IntPush( vAssumps, Entry ); +*/ + // create counter-example + pCare = Saig_RefManCreateCex( p, vVar2PiId, vAssumps ); + + // cleanup + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vAssumps ); + Vec_IntFree( vVar2PiId ); + Vec_VecFreeP( &vLits ); + + // verify counter-example + RetValue = Saig_RefManSetPhases( p, pCare, 0 ); + if ( RetValue ) + printf( "Reduced CEX verification has failed.\n" ); + RetValue = Saig_RefManSetPhases( p, pCare, 1 ); + if ( RetValue ) + printf( "Reduced CEX verification has failed.\n" ); + return pCare; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_RefManRefineWithSat( Saig_RefMan_t * p, Vec_Int_t * vAigPis ) +{ + int nConfLimit = 1000000; + Cnf_Dat_t * pCnf; + sat_solver * pSat; + Aig_Obj_t * pObj; + Vec_Vec_t * vLits; + Vec_Int_t * vReasons, * vAssumps, * vVisited, * vVar2PiId; + int i, k, f, Entry, RetValue, Counter; + + // create CNF and SAT solver + pCnf = Cnf_DeriveSimple( p->pFrames, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( pSat == NULL ) + { + Cnf_DataFree( pCnf ); + return NULL; + } + + // mark used AIG inputs + vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) ); + Vec_IntForEachEntry( vAigPis, Entry, i ) + { + assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pAig) ); + Vec_IntWriteEntry( vVisited, Entry, 1 ); + } + + // create assumptions + vVar2PiId = Vec_IntStartFull( pCnf->nVars ); + vAssumps = Vec_IntAlloc( Aig_ManCiNum(p->pFrames) ); + Aig_ManForEachCi( p->pFrames, pObj, i ) + { + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i ); + int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 ); + if ( Vec_IntEntry(vVisited, iInput) == 0 ) + continue; + RetValue = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ); + Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !RetValue ) ); +// Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 1 ) ); + Vec_IntWriteEntry( vVar2PiId, pCnf->pVarNums[Aig_ObjId(pObj)], i ); + } + Vec_IntFree( vVisited ); + + // try assumptions in different order + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n", + Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts ); + +/* + // AnalizeFinal does not work because it implications propagate directly + // and SAT solver does not kick in (the number of conflicts in 0). + + // count the number of lits in the unsat core + { + int nCoreLits, * pCoreLits; + nCoreLits = sat_solver_final( pSat, &pCoreLits ); + assert( nCoreLits > 0 ); + + // count the number of flops + vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) ); + for ( i = 0; i < nCoreLits; i++ ) + { + int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(pCoreLits[i]) ); + int iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum ); + int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 ); + Vec_IntWriteEntry( vVisited, iInput, 1 ); + } + // count the number of entries + Counter = 0; + Vec_IntForEachEntry( vVisited, Entry, i ) + Counter += Entry; + Vec_IntFree( vVisited ); + +// if ( p->fVerbose ) + printf( "AnalizeFinal: Assumptions %d (out of %d). Essential PIs = %d. Conflicts = %d.\n", + nCoreLits, Vec_IntSize(vAssumps), Counter, (int)pSat->stats.conflicts ); + } +*/ + + // derive literals + vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps ); + for ( i = 0; i < Vec_VecSize(vLits); i++ ) + printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) ); + printf( "\n" ); + + // create different sets of assumptions + Counter = Vec_VecSize(vLits); + for ( f = 0; f < Vec_VecSize(vLits); f++ ) + { + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + if ( i != f ) + Vec_IntPush( vAssumps, Entry ); + + // try the new assumptions + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n", + Vec_IntSize(vAssumps), RetValue == l_False ? "UNSAT" : "SAT", (int)pSat->stats.conflicts ); + if ( RetValue != l_False ) + continue; + + // UNSAT - remove literals + Vec_IntClear( Vec_VecEntryInt(vLits, f) ); + Counter--; + } + + for ( i = 0; i < Vec_VecSize(vLits); i++ ) + printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) ); + printf( "\n" ); + + // create assumptions + Vec_IntClear( vAssumps ); + Vec_VecForEachEntryInt( vLits, Entry, i, k ) + Vec_IntPush( vAssumps, Entry ); + + // try assumptions in different order + RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps), + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n", + Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts ); + +// if ( p->fVerbose ) +// printf( "Total PIs = %d. Essential PIs = %d.\n", +// Saig_ManPiNum(p->pAig) - p->nInputs, Counter ); + + + // transform assumptions into reasons + vReasons = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vAssumps, Entry, i ) + { + int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) ); + assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) ); + Vec_IntPush( vReasons, iPiNum ); + } + + // cleanup + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vAssumps ); + Vec_IntFree( vVar2PiId ); + Vec_VecFreeP( &vLits ); + + return vReasons; +} + +/**Function************************************************************* + + Synopsis [SAT-based refinement of the counter-example.] + + Description [The first parameter (nInputs) indicates how many first + primary inputs to skip without considering as care candidates.] + + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_ManFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fNewOrder, int fVerbose ) +{ + Saig_RefMan_t * p; + Vec_Int_t * vReasons; + Abc_Cex_t * pCare; + clock_t clk = clock(); + + clk = clock(); + p = Saig_RefManStart( pAig, pCex, nInputs, fVerbose ); + vReasons = Saig_RefManFindReason( p ); + +if ( fVerbose ) +Aig_ManPrintStats( p->pFrames ); + +// if ( fVerbose ) + { + Vec_Int_t * vRes = Saig_RefManReason2Inputs( p, vReasons ); + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + + Vec_IntFree( vRes ); + +/* + //////////////////////////////////// + Vec_IntFree( vReasons ); + vReasons = Saig_RefManRefineWithSat( p, vRes ); + //////////////////////////////////// + + Vec_IntFree( vRes ); + vRes = Saig_RefManReason2Inputs( p, vReasons ); + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); + + Vec_IntFree( vRes ); +ABC_PRT( "Time", clock() - clk ); +*/ + } + + pCare = Saig_RefManReason2Cex( p, vReasons ); + Vec_IntFree( vReasons ); + Saig_RefManStop( p ); + +if ( fVerbose ) +Abc_CexPrintStats( pCex ); +if ( fVerbose ) +Abc_CexPrintStats( pCare ); + + return pCare; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExampleTest3( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) +{ + Saig_RefMan_t * p; + Vec_Int_t * vRes, * vReasons; + clock_t clk; + if ( Saig_ManPiNum(pAig) != pCex->nPis ) + { + printf( "Saig_ManExtendCounterExampleTest3(): The PI count of AIG (%d) does not match that of cex (%d).\n", + Aig_ManCiNum(pAig), pCex->nPis ); + return NULL; + } + +clk = clock(); + + p = Saig_RefManStart( pAig, pCex, iFirstFlopPi, fVerbose ); + vReasons = Saig_RefManFindReason( p ); + vRes = Saig_RefManReason2Inputs( p, vReasons ); + +// if ( fVerbose ) + { + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + } + +/* + //////////////////////////////////// + Vec_IntFree( vReasons ); + vReasons = Saig_RefManRefineWithSat( p, vRes ); + //////////////////////////////////// + + // derive new result + Vec_IntFree( vRes ); + vRes = Saig_RefManReason2Inputs( p, vReasons ); +// if ( fVerbose ) + { + printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ", + Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons), + Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + } +*/ + + Vec_IntFree( vReasons ); + Saig_RefManStop( p ); + return vRes; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absOldSim.c b/src/proof/abs/absOldSim.c new file mode 100644 index 00000000..e5c1e938 --- /dev/null +++ b/src/proof/abs/absOldSim.c @@ -0,0 +1,477 @@ +/**CFile**************************************************************** + + FileName [saigSimExt2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Extending simulation trace to contain ternary values.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigSimExt2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SAIG_ZER 1 +#define SAIG_ONE 2 +#define SAIG_UND 3 + +static inline int Saig_ManSimInfoNot( int Value ) +{ + if ( Value == SAIG_ZER ) + return SAIG_ONE; + if ( Value == SAIG_ONE ) + return SAIG_ZER; + return SAIG_UND; +} + +static inline int Saig_ManSimInfoAnd( int Value0, int Value1 ) +{ + if ( Value0 == SAIG_ZER || Value1 == SAIG_ZER ) + return SAIG_ZER; + if ( Value0 == SAIG_ONE && Value1 == SAIG_ONE ) + return SAIG_ONE; + return SAIG_UND; +} + +static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); +} + +static inline void Saig_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + assert( Value >= SAIG_ZER && Value <= SAIG_UND ); + Value ^= Saig_ManSimInfoGet( vSimInfo, pObj, iFrame ); + pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); +} + + + +#define SAIG_ZER_NEW 0 // 0 not visited +#define SAIG_ONE_NEW 1 // 1 not visited +#define SAIG_ZER_OLD 2 // 0 visited +#define SAIG_ONE_OLD 3 // 1 visited + +static inline int Saig_ManSimInfo2IsOld( int Value ) +{ + return Value == SAIG_ZER_OLD || Value == SAIG_ONE_OLD; +} + +static inline int Saig_ManSimInfo2SetOld( int Value ) +{ + if ( Value == SAIG_ZER_NEW ) + return SAIG_ZER_OLD; + if ( Value == SAIG_ONE_NEW ) + return SAIG_ONE_OLD; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2Not( int Value ) +{ + if ( Value == SAIG_ZER_NEW ) + return SAIG_ONE_NEW; + if ( Value == SAIG_ONE_NEW ) + return SAIG_ZER_NEW; + if ( Value == SAIG_ZER_OLD ) + return SAIG_ONE_OLD; + if ( Value == SAIG_ONE_OLD ) + return SAIG_ZER_OLD; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2And( int Value0, int Value1 ) +{ + if ( Value0 == SAIG_ZER_NEW || Value1 == SAIG_ZER_NEW ) + return SAIG_ZER_NEW; + if ( Value0 == SAIG_ONE_NEW && Value1 == SAIG_ONE_NEW ) + return SAIG_ONE_NEW; + assert( 0 ); + return 0; +} + +static inline int Saig_ManSimInfo2Get( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); +} + +static inline void Saig_ManSimInfo2Set( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + Value ^= Saig_ManSimInfo2Get( vSimInfo, pObj, iFrame ); + pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); +} + +// performs ternary simulation +//extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs ternary simulation for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + int Value0, Value1, Value; + Value0 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin0(pObj), iFrame ); + if ( Aig_ObjFaninC0(pObj) ) + Value0 = Saig_ManSimInfoNot( Value0 ); + if ( Aig_ObjIsCo(pObj) ) + { + Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); + return Value0; + } + assert( Aig_ObjIsNode(pObj) ); + Value1 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin1(pObj), iFrame ); + if ( Aig_ObjFaninC1(pObj) ) + Value1 = Saig_ManSimInfoNot( Value1 ); + Value = Saig_ManSimInfoAnd( Value0, Value1 ); + Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); + return Value; +} + +/**Function************************************************************* + + Synopsis [Performs ternary simulation for one design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ) +{ + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f, Entry, iBit = 0; + Saig_ManForEachLo( p, pObj, i ) + Saig_ManSimInfoSet( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER ); + for ( f = 0; f <= pCex->iFrame; f++ ) + { + Saig_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE ); + Saig_ManForEachPi( p, pObj, i ) + Saig_ManSimInfoSet( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER ); + if ( vRes ) + Vec_IntForEachEntry( vRes, Entry, i ) + Saig_ManSimInfoSet( vSimInfo, Aig_ManCi(p, Entry), f, SAIG_UND ); + Aig_ManForEachNode( p, pObj, i ) + Saig_ManExtendOneEval( vSimInfo, pObj, f ); + Aig_ManForEachCo( p, pObj, i ) + Saig_ManExtendOneEval( vSimInfo, pObj, f ); + if ( f == pCex->iFrame ) + break; + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + Saig_ManSimInfoSet( vSimInfo, pObjLo, f+1, Saig_ManSimInfoGet(vSimInfo, pObjLi, f) ); + } + // make sure the output of the property failed + pObj = Aig_ManCo( p, pCex->iPo ); + return Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame ); +} + +/**Function************************************************************* + + Synopsis [Performs ternary simulation for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManExtendOneEval2( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + int Value0, Value1, Value; + Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pObj), iFrame ); + if ( Aig_ObjFaninC0(pObj) ) + Value0 = Saig_ManSimInfo2Not( Value0 ); + if ( Aig_ObjIsCo(pObj) ) + { + Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value0 ); + return Value0; + } + assert( Aig_ObjIsNode(pObj) ); + Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pObj), iFrame ); + if ( Aig_ObjFaninC1(pObj) ) + Value1 = Saig_ManSimInfo2Not( Value1 ); + Value = Saig_ManSimInfo2And( Value0, Value1 ); + Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value ); + return Value; +} + +/**Function************************************************************* + + Synopsis [Performs sensitization analysis for one design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManSimDataInit2( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo ) +{ + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f, iBit = 0; + Saig_ManForEachLo( p, pObj, i ) + Saig_ManSimInfo2Set( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); + for ( f = 0; f <= pCex->iFrame; f++ ) + { + Saig_ManSimInfo2Set( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE_NEW ); + Saig_ManForEachPi( p, pObj, i ) + Saig_ManSimInfo2Set( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW ); + Aig_ManForEachNode( p, pObj, i ) + Saig_ManExtendOneEval2( vSimInfo, pObj, f ); + Aig_ManForEachCo( p, pObj, i ) + Saig_ManExtendOneEval2( vSimInfo, pObj, f ); + if ( f == pCex->iFrame ) + break; + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + Saig_ManSimInfo2Set( vSimInfo, pObjLo, f+1, Saig_ManSimInfo2Get(vSimInfo, pObjLi, f) ); + } + // make sure the output of the property failed + pObj = Aig_ManCo( p, pCex->iPo ); + return Saig_ManSimInfo2Get( vSimInfo, pObj, pCex->iFrame ); +} + +/**Function************************************************************* + + Synopsis [Drive implications of the given node towards primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) +{ + Aig_Obj_t * pFanout; + int k, iFanout = -1, Value0, Value1; + int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); + assert( !Saig_ManSimInfo2IsOld( Value ) ); + Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) ); + if ( (Aig_ObjIsCo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) ) + return; + if ( Saig_ObjIsLi( p, pObj ) ) + { + assert( f < fMax ); + pFanout = Saig_ObjLiToLo(p, pObj); + Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 ); + if ( !Saig_ManSimInfo2IsOld( Value ) ) + Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo ); + return; + } + assert( Aig_ObjIsCi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) ); + Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k ) + { + Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + continue; + if ( Aig_ObjIsCo(pFanout) ) + { + Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); + continue; + } + assert( Aig_ObjIsNode(pFanout) ); + Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f ); + Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f ); + if ( Aig_ObjFaninC0(pFanout) ) + Value0 = Saig_ManSimInfo2Not( Value0 ); + if ( Aig_ObjFaninC1(pFanout) ) + Value1 = Saig_ManSimInfo2Not( Value1 ); + if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD || + (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) ) + Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); + } +} + +/**Function************************************************************* + + Synopsis [Performs recursive sensetization analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManExplorePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) +{ + int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + return; + Saig_ManSetAndDriveImplications_rec( p, pObj, f, fMax, vSimInfo ); + assert( !Aig_ObjIsConst1(pObj) ); + if ( Saig_ObjIsLo(p, pObj) && f == 0 ) + return; + if ( Saig_ObjIsPi(p, pObj) ) + { + // propagate implications of this assignment + int i, iPiNum = Aig_ObjCioId(pObj); + for ( i = fMax; i >= 0; i-- ) + if ( i != f ) + Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, iPiNum), i, fMax, vSimInfo ); + return; + } + if ( Saig_ObjIsLo( p, pObj ) ) + { + assert( f > 0 ); + Saig_ManExplorePaths_rec( p, Saig_ObjLoToLi(p, pObj), f-1, fMax, vSimInfo ); + return; + } + if ( Aig_ObjIsCo(pObj) ) + { + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); + return; + } + assert( Aig_ObjIsNode(pObj) ); + if ( Value == SAIG_ZER_OLD ) + { +// if ( (Aig_ObjId(pObj) & 1) == 0 ) + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); +// else +// Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); + } + else + { + Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo ); + Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo ); + } +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManProcessCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vRes, * vResInv; + int i, f, Value; +// assert( Aig_ManRegNum(p) > 0 ); + assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) ); + // start simulation data + Value = Saig_ManSimDataInit2( p, pCex, vSimInfo ); + assert( Value == SAIG_ONE_NEW ); + // derive implications of constants and primary inputs + Saig_ManForEachLo( p, pObj, i ) + Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + { + Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo ); + for ( i = 0; i < iFirstFlopPi; i++ ) + Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo ); + } + // recursively compute justification + Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo ); + // select the result + vRes = Vec_IntAlloc( 1000 ); + vResInv = Vec_IntAlloc( 1000 ); + for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + { + Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f ); + if ( Saig_ManSimInfo2IsOld( Value ) ) + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + // resimulate to make sure it is valid + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); + assert( Value == SAIG_ONE ); + Vec_IntFree( vResInv ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) +{ + Vec_Int_t * vRes; + Vec_Ptr_t * vSimInfo; + clock_t clk; + if ( Saig_ManPiNum(p) != pCex->nPis ) + { + printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n", + Aig_ManCiNum(p), pCex->nPis ); + return NULL; + } + Aig_ManFanoutStart( p ); + vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) ); + Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) ); + +clk = clock(); + vRes = Saig_ManProcessCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + if ( fVerbose ) + { + printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) ); +ABC_PRT( "Time", clock() - clk ); + } + Vec_PtrFree( vSimInfo ); + Aig_ManFanoutStop( p ); + return vRes; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absOut.c b/src/proof/abs/absOut.c new file mode 100644 index 00000000..c230acb4 --- /dev/null +++ b/src/proof/abs/absOut.c @@ -0,0 +1,458 @@ +/**CFile**************************************************************** + + FileName [absOut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Abstraction refinement outside of abstraction engines.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absOut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derive a new counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManCexRemap( Gia_Man_t * p, Abc_Cex_t * pCexAbs, Vec_Int_t * vPis ) +{ + Abc_Cex_t * pCex; + int i, f, iPiNum; + assert( pCexAbs->iPo == 0 ); + // start the counter-example + pCex = Abc_CexAlloc( Gia_ManRegNum(p), Gia_ManPiNum(p), pCexAbs->iFrame+1 ); + pCex->iFrame = pCexAbs->iFrame; + pCex->iPo = pCexAbs->iPo; + // copy the bit data + for ( f = 0; f <= pCexAbs->iFrame; f++ ) + for ( i = 0; i < Vec_IntSize(vPis); i++ ) + { + if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) ) + { + iPiNum = Gia_ObjCioId( Gia_ManObj(p, Vec_IntEntry(vPis, i)) ); + Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + iPiNum ); + } + } + // verify the counter example + if ( !Gia_ManVerifyCex( p, pCex, 0 ) ) + { + Abc_Print( 1, "Gia_ManCexRemap(): Counter-example is invalid.\n" ); + Abc_CexFree( pCex ); + pCex = NULL; + } + else + { + Abc_Print( 1, "Counter-example verification is successful.\n" ); + Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame ); + } + return pCex; +} + +/**Function************************************************************* + + Synopsis [Refines gate-level abstraction using the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManGlaRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int fMinCut, int fVerbose ) +{ + extern void Nwk_ManDeriveMinCut( Gia_Man_t * p, int fVerbose ); + int fAddOneLayer = 1; + Abc_Cex_t * pCexNew = NULL; + Gia_Man_t * pAbs; + Aig_Man_t * pAig; + Abc_Cex_t * pCare; + Vec_Int_t * vPis, * vPPis; + int f, i, iObjId; + clock_t clk = clock(); + int nOnes = 0, Counter = 0; + if ( p->vGateClasses == NULL ) + { + Abc_Print( 1, "Gia_ManGlaRefine(): Abstraction gate map is missing.\n" ); + return -1; + } + // derive abstraction + pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); + Gia_ManStop( pAbs ); + pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); + if ( Gia_ManPiNum(pAbs) != pCex->nPis ) + { + Abc_Print( 1, "Gia_ManGlaRefine(): The PI counts in GLA and in CEX do not match.\n" ); + Gia_ManStop( pAbs ); + return -1; + } + if ( !Gia_ManVerifyCex( pAbs, pCex, 0 ) ) + { + Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is invalid.\n" ); +// Gia_ManStop( pAbs ); +// return -1; + } +// else +// Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is correct.\n" ); + // get inputs + Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, NULL, NULL ); + assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); + // add missing logic + if ( fAddOneLayer ) + { + Gia_Obj_t * pObj; + // check if this is a real counter-example + Gia_ObjTerSimSet0( Gia_ManConst0(pAbs) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + { + Gia_ManForEachPi( pAbs, pObj, i ) + { + if ( i >= Vec_IntSize(vPis) ) // PPIs + Gia_ObjTerSimSetX( pObj ); + else if ( Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachRo( pAbs, pObj, i ) + { + if ( f == 0 ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimRo( pAbs, pObj ); + } + Gia_ManForEachAnd( pAbs, pObj, i ) + Gia_ObjTerSimAnd( pObj ); + Gia_ManForEachCo( pAbs, pObj, i ) + Gia_ObjTerSimCo( pObj ); + } + pObj = Gia_ManPo( pAbs, 0 ); + if ( Gia_ObjTerSimGet1(pObj) ) + { + pCexNew = Gia_ManCexRemap( p, pCex, vPis ); + Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); + } +// else +// Abc_Print( 1, "CEX is not real.\n" ); + Gia_ManForEachObj( pAbs, pObj, i ) + Gia_ObjTerSimSetC( pObj ); + if ( pCexNew == NULL ) + { + // grow one layer + Vec_IntForEachEntry( vPPis, iObjId, i ) + { + assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); + Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); + } + if ( fVerbose ) + { + Abc_Print( 1, "Additional objects = %d. ", Vec_IntSize(vPPis) ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } + } + } + else + { + // minimize the CEX + pAig = Gia_ManToAigSimple( pAbs ); + pCare = Saig_ManCbaFindCexCareBits( pAig, pCex, Vec_IntSize(vPis), fVerbose ); + Aig_ManStop( pAig ); + if ( pCare == NULL ) + Abc_Print( 1, "Counter-example minimization has failed.\n" ); + // add new objects to the map + iObjId = -1; + for ( f = 0; f <= pCare->iFrame; f++ ) + for ( i = 0; i < pCare->nPis; i++ ) + if ( Abc_InfoHasBit( pCare->pData, pCare->nRegs + f * pCare->nPis + i ) ) + { + nOnes++; + assert( i >= Vec_IntSize(vPis) ); + iObjId = Vec_IntEntry( vPPis, i - Vec_IntSize(vPis) ); + assert( iObjId > 0 && iObjId < Gia_ManObjNum(p) ); + if ( Vec_IntEntry( p->vGateClasses, iObjId ) > 0 ) + continue; + assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); + Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); + // Abc_Print( 1, "Adding object %d.\n", iObjId ); + // Gia_ObjPrint( p, Gia_ManObj(p, iObjId) ); + Counter++; + } + Abc_CexFree( pCare ); + if ( fVerbose ) + { + Abc_Print( 1, "Essential bits = %d. Additional objects = %d. ", nOnes, Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } + // consider the case of SAT + if ( iObjId == -1 ) + { + pCexNew = Gia_ManCexRemap( p, pCex, vPis ); + Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); + } + } + Vec_IntFree( vPis ); + Vec_IntFree( vPPis ); + Gia_ManStop( pAbs ); + if ( pCexNew ) + { + ABC_FREE( p->pCexSeq ); + p->pCexSeq = pCexNew; + return 0; + } + // extract abstraction to include min-cut + if ( fMinCut ) + Nwk_ManDeriveMinCut( p, fVerbose ); + return -1; +} + + + + + +/**Function************************************************************* + + Synopsis [Resimulates the counter-example and returns flop values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManGetStateAndCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) +{ + Vec_Int_t * vInit = Vec_IntAlloc( Gia_ManRegNum(pAig) ); + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + assert( iFrame >= 0 && iFrame <= p->iFrame ); + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); + for ( i = 0, iBit = p->nRegs; i <= p->iFrame; i++ ) + { + if ( i == iFrame ) + { + Gia_ManForEachRo( pAig, pObjRo, k ) + Vec_IntPush( vInit, pObjRo->fMark0 ); + } + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + if ( i == p->iFrame ) + break; + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; + if ( RetValue != 1 ) + Vec_IntFreeP( &vInit ); + Gia_ManCleanMark0(pAig); + return vInit; +} + +/**Function************************************************************* + + Synopsis [Verify counter-example starting in the given timeframe.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + assert( iFrame >= 0 && iFrame <= p->iFrame ); + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); + for ( i = iFrame, iBit += p->nRegs + Gia_ManPiNum(pAig) * iFrame; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + if ( i == p->iFrame ) + break; + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; + Gia_ManCleanMark0(pAig); + if ( RetValue == 1 ) + printf( "Shortened CEX holds for the abstraction of the fast-forwarded model.\n" ); + else + printf( "Shortened CEX does not hold for the abstraction of the fast-forwarded model.\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManTransformFlops( Gia_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vInit ) +{ + Vec_Bit_t * vInitNew; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, iFlopId; + assert( Vec_IntSize(vInit) == Vec_IntSize(vFlops) ); + vInitNew = Vec_BitStart( Gia_ManRegNum(p) ); + Gia_ManForEachObjVec( vFlops, p, pObj, i ) + { + assert( Gia_ObjIsRo(p, pObj) ); + if ( Vec_IntEntry(vInit, i) == 0 ) + continue; + iFlopId = Gia_ObjCioId(pObj) - Gia_ManPiNum(p); + assert( iFlopId >= 0 && iFlopId < Gia_ManRegNum(p) ); + Vec_BitWriteEntry( vInitNew, iFlopId, 1 ); + } + pNew = Gia_ManDupFlip( p, Vec_BitArray(vInitNew) ); + Vec_BitFree( vInitNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManNewRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrameStart, int iFrameExtra, int fVerbose ) +{ + Gia_Man_t * pAbs, * pNew; + Vec_Int_t * vFlops, * vInit; + Vec_Int_t * vCopy; +// clock_t clk = clock(); + int RetValue; + ABC_FREE( p->pCexSeq ); + if ( p->vGateClasses == NULL ) + { + Abc_Print( 1, "Gia_ManNewRefine(): Abstraction gate map is missing.\n" ); + return -1; + } + vCopy = Vec_IntDup( p->vGateClasses ); + Abc_Print( 1, "Refining with %d-frame CEX, starting in frame %d, with %d extra frames.\n", pCex->iFrame, iFrameStart, iFrameExtra ); + // derive abstraction + pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); + Gia_ManStop( pAbs ); + pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); + if ( Gia_ManPiNum(pAbs) != pCex->nPis ) + { + Abc_Print( 1, "Gia_ManNewRefine(): The PI counts in GLA and in CEX do not match.\n" ); + Gia_ManStop( pAbs ); + Vec_IntFree( vCopy ); + return -1; + } + // get the state in frame iFrameStart + vInit = Gia_ManGetStateAndCheckCex( pAbs, pCex, iFrameStart ); + if ( vInit == NULL ) + { + Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is invalid.\n" ); + Gia_ManStop( pAbs ); + Vec_IntFree( vCopy ); + return -1; + } + if ( fVerbose ) + Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is correct.\n" ); + // get inputs + Gia_ManGlaCollect( p, p->vGateClasses, NULL, NULL, &vFlops, NULL ); +// assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); + Gia_ManStop( pAbs ); +//Vec_IntPrint( vFlops ); +//Vec_IntPrint( vInit ); + // transform the manager to have new init state + pNew = Gia_ManTransformFlops( p, vFlops, vInit ); + Vec_IntFree( vFlops ); + Vec_IntFree( vInit ); + // verify abstraction + { + Gia_Man_t * pAbs = Gia_ManDupAbsGates( pNew, p->vGateClasses ); + Gia_ManCheckCex( pAbs, pCex, iFrameStart ); + Gia_ManStop( pAbs ); + } + // transfer abstraction + assert( pNew->vGateClasses == NULL ); + pNew->vGateClasses = Vec_IntDup( p->vGateClasses ); + // perform abstraction for the new AIG + { + Abs_Par_t Pars, * pPars = &Pars; + Abs_ParSetDefaults( pPars ); + pPars->nFramesMax = pCex->iFrame - iFrameStart + 1 + iFrameExtra; + pPars->fVerbose = fVerbose; + RetValue = Gia_ManPerformGla( pNew, pPars ); + if ( RetValue == 0 ) // spurious SAT + { + Vec_IntFreeP( &pNew->vGateClasses ); + pNew->vGateClasses = Vec_IntDup( vCopy ); + } + } + // move the abstraction map + Vec_IntFreeP( &p->vGateClasses ); + p->vGateClasses = pNew->vGateClasses; + pNew->vGateClasses = NULL; + // cleanup + Gia_ManStop( pNew ); + Vec_IntFree( vCopy ); + return -1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absPth.c b/src/proof/abs/absPth.c new file mode 100644 index 00000000..73f76822 --- /dev/null +++ b/src/proof/abs/absPth.c @@ -0,0 +1,199 @@ +/**CFile**************************************************************** + + FileName [absPth.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Interface to pthreads.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absPth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/ioa/ioa.h" +#include "proof/pdr/pdr.h" + +// uncomment this line to enable pthreads +//#define ABC_USE_PTHREADS + +// to compile on Linux, modify Makefile as follows: +// add -pthread to OPTFLAGS +// add -lpthread to LIBS + +#ifdef ABC_USE_PTHREADS + +#ifdef WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#ifndef ABC_USE_PTHREADS + +void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ) {} +void Gia_Ga2ProveCancel( int fVerbose ) {} +int Gia_Ga2ProveCheck( int fVerbose ) { return 0; } + +#else // pthreads are used + +// information given to the thread +typedef struct Abs_ThData_t_ +{ + char * pFileName; + int fVerbose; + int RunId; +} Abs_ThData_t; + +// mutext to control access to shared variables +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; +static volatile int g_nRunIds = 0; // the number of the last prover instance +static volatile int g_fAbstractionProved = 0; // set to 1 when prover successed to prove + +// call back procedure for PDR +int Abs_CallBackToStop( int RunId ) { assert( RunId <= g_nRunIds ); return RunId < g_nRunIds; } + +// test procedure to replace PDR +int Pdr_ManSolve_test( Aig_Man_t * pAig, Pdr_Par_t * pPars, Abc_Cex_t ** ppCex ) +{ + char * p = ABC_ALLOC( char, 111 ); + while ( 1 ) + { + if ( pPars->pFuncStop && pPars->pFuncStop(pPars->RunId) ) + break; + } + ABC_FREE( p ); + return -1; +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Create one thread] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abs_ProverThread( void * pArg ) +{ + Abs_ThData_t * pThData = (Abs_ThData_t *)pArg; + Pdr_Par_t Pars, * pPars = &Pars; + Aig_Man_t * pAig, * pTemp; + int RetValue, status; + pAig = Ioa_ReadAiger( pThData->pFileName, 0 ); + if ( pAig == NULL ) + Abc_Print( 1, "\nCannot open file \"%s\".\n", pThData->pFileName ); + else + { + // synthesize abstraction + pAig = Aig_ManScl( pTemp = pAig, 1, 1, 0, -1, -1, 0, 0 ); + Aig_ManStop( pTemp ); + // call PDR + Pdr_ManSetDefaultParams( pPars ); + pPars->fSilent = 1; + pPars->RunId = pThData->RunId; + pPars->pFuncStop = Abs_CallBackToStop; + RetValue = Pdr_ManSolve( pAig, pPars, NULL ); +// RetValue = Pdr_ManSolve_test( pAig, pPars, NULL ); + // update the result + if ( RetValue == 1 ) + { + status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); + g_fAbstractionProved = 1; + status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); + } + // free memory + Aig_ManStop( pAig ); + // quit this thread + if ( pThData->fVerbose ) + { + if ( RetValue == 1 ) + Abc_Print( 1, "\nProved abstraction %d.\n", pThData->RunId ); + else if ( RetValue == 0 ) + Abc_Print( 1, "\nDisproved abstraction %d.\n", pThData->RunId ); + else if ( RetValue == -1 ) + Abc_Print( 1, "\nCancelled abstraction %d.\n", pThData->RunId ); + else assert( 0 ); + } + } + ABC_FREE( pThData->pFileName ); + ABC_FREE( pThData ); + // quit this thread + pthread_exit( NULL ); + assert(0); + return NULL; +} +void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ) +{ + Abs_ThData_t * pThData; + pthread_t ProverThread; + int status; + assert( pFileName != NULL ); + // disable verbosity + fVerbose = 0; + // reset the proof + status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); + g_fAbstractionProved = 0; + status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); + // collect thread data + pThData = ABC_CALLOC( Abs_ThData_t, 1 ); + pThData->pFileName = Abc_UtilStrsav( (void *)pFileName ); + pThData->fVerbose = fVerbose; + status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); + pThData->RunId = ++g_nRunIds; + status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); + // create thread + if ( fVerbose ) Abc_Print( 1, "\nTrying to prove abstraction %d.\n", pThData->RunId ); + status = pthread_create( &ProverThread, NULL, Abs_ProverThread, pThData ); + assert( status == 0 ); +} +void Gia_Ga2ProveCancel( int fVerbose ) +{ + int status; + status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); + g_nRunIds++; + status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); +} +int Gia_Ga2ProveCheck( int fVerbose ) +{ + int status; + if ( g_fAbstractionProved == 0 ) + return 0; + status = pthread_mutex_lock(&g_mutex); assert( status == 0 ); + g_fAbstractionProved = 0; + status = pthread_mutex_unlock(&g_mutex); assert( status == 0 ); + return 1; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absRef.c b/src/proof/abs/absRef.c new file mode 100644 index 00000000..3aea96ee --- /dev/null +++ b/src/proof/abs/absRef.c @@ -0,0 +1,1001 @@ +/**CFile**************************************************************** + + FileName [absRef.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Refinement manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sat/bsat/satSolver2.h" +#include "abs.h" +#include "absRef.h" + +ABC_NAMESPACE_IMPL_START + +/* + Description of the refinement manager + + This refinement manager should be + * started by calling Rnm_ManStart() + this procedure takes one argument, the user's seq miter as a GIA manager + - the manager should have only one property output + - this manager should not change while the refinement manager is alive + - it cannot be used by external applications for any purpose + - when the refinement manager stop, GIA manager is the same as at the beginning + - in the meantime, it will have some data-structures attached to its nodes... + * stopped by calling Rnm_ManStop() + * between starting and stopping, refinements are obtained by calling Rnm_ManRefine() + + Procedure Rnm_ManRefine() takes the following arguments: + * the refinement manager previously started by Rnm_ManStart() + * counter-example (CEX) obtained by abstracting some logic of GIA + * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager + - only PI, flop outputs, and internal AND nodes can be used in vMap + - the ordering of objects in vMap is not important + - however, the index of a non-PI object in vMap is used as its priority + (the smaller the index, the more likely this non-PI object apears in a refinement) + - only the logic between PO and the objects listed in vMap is traversed by the manager + (as a result, GIA can be arbitrarily large, but only objects used in the abstraction + and the pseudo-PI, that is, objects in the cut, will be visited by the manager) + * flag fPropFanout defines whether value propagation is done through the fanout + - it this flag is enabled, theoretically refinement should be better (the result smaller) + * flag fVerbose may print some statistics + + The refinement manager returns a minimal-size array of integer IDs of GIA objects + which should be added to the abstraction to possibly prevent the given counter-example + - only flop output and internal AND nodes from vMap may appear in the resulting array + - if the resulting array is empty, the CEX is a true CEX + (in other words, non-PI objects are not needed to set the PO value to 1) + + Verification of the selected refinement is performed by + - initializing all PI objects in vMap to value 0 or 1 they have in the CEX + - initializing all remaining objects in vMap to value X + - initializing objects used in the refiment to value 0 or 1 they have in the CEX + - simulating through as many timeframes as required by the CEX + - if the PO value in the last frame is 1, the refinement is correct + (however, the minimality of the refinement is not currently checked) + +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Rnm_Obj_t_ Rnm_Obj_t; // refinement object +struct Rnm_Obj_t_ +{ + unsigned Value : 1; // binary value + unsigned fVisit : 1; // visited object + unsigned fVisit0 : 1; // visited object + unsigned fPPi : 1; // PPI object + unsigned Prio : 24; // priority (0 - highest) +}; + +struct Rnm_Man_t_ +{ + // user data + Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package) + Abc_Cex_t * pCex; // counter-example + Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order) + int fPropFanout; // propagate fanouts + int fVerbose; // verbose flag + // traversing data + Vec_Int_t * vObjs; // internal objects used in value propagation + Vec_Str_t * vCounts; // fanin counters + Vec_Int_t * vFanins; // fanins + // SAT solver + sat_solver2 * pSat; // incremental SAT solver + Vec_Int_t * vSatVars; // SAT variables + Vec_Int_t * vSat2Ids; // mapping of SAT variables into object IDs + Vec_Int_t * vIsopMem; // memory for ISOP computation + // internal data + Rnm_Obj_t * pObjs; // refinement objects + int nObjs; // the number of used objects + int nObjsAlloc; // the number of allocated objects + int nObjsFrame; // the number of used objects in each frame + int nCalls; // total number of calls + int nRefines; // total refined objects + int nVisited; // visited during justification + // statistics + clock_t timeFwd; // forward propagation + clock_t timeBwd; // backward propagation + clock_t timeVer; // ternary simulation + clock_t timeTotal; // other time +}; + +// accessing the refinement object +static inline Rnm_Obj_t * Rnm_ManObj( Rnm_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + assert( Gia_ObjIsConst0(pObj) || pObj->Value ); + assert( (int)pObj->Value < p->nObjsFrame ); + assert( f >= 0 && f <= p->pCex->iFrame ); + return p->pObjs + f * p->nObjsFrame + pObj->Value; +} + +static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); } +static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); } +static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); } +static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); } +static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); } +static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; } + +static inline int Rnm_ObjCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_StrEntry( p->vCounts, Gia_ObjId(p->pGia, pObj) ); } +static inline void Rnm_ObjSetCount( Rnm_Man_t * p, Gia_Obj_t * pObj, int c ) { Vec_StrWriteEntry( p->vCounts, Gia_ObjId(p->pGia, pObj), (char)c ); } +static inline int Rnm_ObjAddToCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { int c = Rnm_ObjCount(p, pObj); if ( c < 16 ) Rnm_ObjSetCount(p, pObj, c+1); return c; } + +static inline int Rnm_ObjSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj) ); } +static inline void Rnm_ObjSetSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj, int c) { Vec_IntWriteEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj), c ); } +static inline int Rnm_ObjFindOrAddSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj) { if ( Rnm_ObjSatVar(p, pObj) == 0 ) { Rnm_ObjSetSatVar(p, pObj, Vec_IntSize(p->vSat2Ids)); Vec_IntPush(p->vSat2Ids, Gia_ObjId(p->pGia, pObj)); }; return 2*Rnm_ObjSatVar(p, pObj); } + +extern void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int * pLits, int iLitOut, int ProofId ); + +extern Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs UNSAT-core-based refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rnm_ManRefineCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisited, Vec_Int_t * vFlops ) +{ + Vec_Int_t * vLeaves; + Gia_Obj_t * pFanin; + int k; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + if ( Gia_ObjIsRo(p, pObj) ) + Vec_IntPush( vFlops, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + vLeaves = Ga2_ObjLeaves( p, pObj ); + Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) + Rnm_ManRefineCollect_rec( p, pFanin, vVisited, vFlops ); + Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); +} + +Vec_Int_t * Rnm_ManRefineUnsatCore( Rnm_Man_t * p, Vec_Int_t * vPPIs ) +{ + Vec_Int_t * vCnf0, * vCnf1; + Vec_Int_t * vLeaves, * vLits, * vPpi2Map; + Vec_Int_t * vVisited, * vFlops, * vCore, * vCoreFinal; + Gia_Obj_t * pObj, * pFanin; + int i, k, f, Status, Entry, pLits[5], iBit = p->pCex->nRegs; + // map PPIs into their positions in the map // CAN BE MADE FASTER + vPpi2Map = Vec_IntAlloc( Vec_IntSize(vPPIs) ); + Vec_IntForEachEntry( vPPIs, Entry, i ) + { + Entry = Vec_IntFind( p->vMap, Entry ); + assert( Entry >= 0 ); + Vec_IntPush( vPpi2Map, Entry ); + } + // collect nodes between selected PPIs and CIs + vFlops = Vec_IntAlloc( 100 ); + vVisited = Vec_IntAlloc( 100 ); + Gia_ManIncrementTravId( p->pGia ); + Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) +// if ( !Gia_ObjIsRo(p->pGia, pObj) ) // SKIP PPIs that are flops + Rnm_ManRefineCollect_rec( p->pGia, pObj, vVisited, vFlops ); + // create SAT variables and SAT solver + Vec_IntFill( p->vSat2Ids, 1, -1 ); + assert( p->pSat == NULL ); + p->pSat = sat_solver2_new(); + Vec_IntFill( p->vSatVars, Gia_ManObjNum(p->pGia), 0 ); // NO NEED TO CLEAN EACH TIME + // assign PPI variables + Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i ) + Rnm_ObjFindOrAddSatVar( p, pObj ); + // assign other variables + Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i ) + { + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + pLits[k] = Rnm_ObjFindOrAddSatVar( p, pFanin ); + vCnf0 = Ga2_ManCnfCompute( Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem ); + vCnf1 = Ga2_ManCnfCompute( ~Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem ); + Ga2_ManCnfAddStatic( p->pSat, vCnf0, vCnf1, pLits, Rnm_ObjFindOrAddSatVar(p, pObj), Rnm_ObjFindOrAddSatVar(p, pObj)/2 ); + Vec_IntFree( vCnf0 ); + Vec_IntFree( vCnf1 ); + } + +// printf( "\n" ); + + p->pSat->pPrf2 = Prf_ManAlloc(); + Prf_ManRestart( p->pSat->pPrf2, NULL, sat_solver2_nlearnts(p->pSat), Vec_IntSize(p->vSat2Ids) ); + + // iterate UNSAT core computation for each timeframe + vLits = Vec_IntAlloc( 100 ); + vCoreFinal = Vec_IntAlloc( 100 ); + for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) + { + // collect values of PPIs in this timeframe + Vec_IntClear( vLits ); + Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) + { + Entry = Abc_InfoHasBit( p->pCex->pData, iBit + Vec_IntEntry(vPpi2Map, i) ); + Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), !Entry ) ); + } + + // handle the first timeframe in a special vay + if ( f == 0 ) + Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i ) + if ( Vec_IntFind( vPPIs, Gia_ObjId(p->pGia, pObj) ) == -1 ) + Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), 1 ) ); +/* + // uniqify literals and detect special conflicts + Vec_IntUniqify( vLits ); + Vec_IntForEachEntryStart( vLits, Entry, i, 1 ) + if ( Vec_IntEntry(vLits, i-1) == Abc_LitNot(Entry) ) + break; + if ( i < Vec_IntSize(vLits) ) + printf( "triv_unsat " ); + else +*/ + + Status = sat_solver2_solve( p->pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( Status != l_False ) + continue; + vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat ); +// vCore = Vec_IntAlloc( 0 ); + // add to the UNSAT core + Vec_IntAppend( vCoreFinal, vCore ); + +// printf( "Frame %d : ", f ); +// Vec_IntPrint( vCore ); + Vec_IntFree( vCore ); + } + assert( iBit == p->pCex->nBits ); + Vec_IntUniqify( vCoreFinal ); + Vec_IntFree( vLits ); + Prf_ManStopP( &p->pSat->pPrf2 ); + sat_solver2_delete( p->pSat ); + p->pSat = NULL; + + // translate from entry into ID + Vec_IntForEachEntry( vCoreFinal, Entry, i ) + { + assert( Vec_IntEntry(p->vSat2Ids, Entry) >= 0 ); + assert( Vec_IntEntry(p->vSat2Ids, Entry) < Gia_ManObjNum(p->pGia) ); + Vec_IntWriteEntry( vCoreFinal, i, Vec_IntEntry(p->vSat2Ids, Entry) ); + } + // if there are flop outputs, add them + Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i ) + if ( Gia_ObjIsRo(p->pGia, pObj) ) + Vec_IntPush( vCoreFinal, Gia_ObjId(p->pGia, pObj) ); + Vec_IntUniqify( vCoreFinal ); + +// printf( "\n" ); +// Vec_IntPrint( vPPIs ); +// Vec_IntPrint( vCoreFinal ); + +// printf( "\n" ); + + // clean SAT variable numbers + Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i ) + { + Rnm_ObjSetSatVar( p, pObj, 0 ); + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + Rnm_ObjSetSatVar( p, pFanin, 0 ); + } + Vec_IntFree( vFlops ); + Vec_IntFree( vVisited ); + Vec_IntFree( vPpi2Map ); + return vCoreFinal; +} + + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia ) +{ + Rnm_Man_t * p; + assert( Gia_ManPoNum(pGia) == 1 ); + p = ABC_CALLOC( Rnm_Man_t, 1 ); + p->pGia = pGia; + p->vObjs = Vec_IntAlloc( 100 ); + p->vCounts = Vec_StrStart( Gia_ManObjNum(pGia) ); + p->vFanins = Vec_IntAlloc( 1000 ); + p->vSatVars = Vec_IntAlloc( 0 ); + p->vSat2Ids = Vec_IntAlloc( 1000 ); + p->vIsopMem = Vec_IntAlloc( 0 ); + p->nObjsAlloc = 10000; + p->pObjs = ABC_ALLOC( Rnm_Obj_t, p->nObjsAlloc ); + if ( p->pGia->vFanout == NULL ) + Gia_ManStaticFanoutStart( p->pGia ); + Gia_ManCleanValue(pGia); + Gia_ManCleanMark0(pGia); + Gia_ManCleanMark1(pGia); + return p; +} +void Rnm_ManStop( Rnm_Man_t * p, int fProfile ) +{ + if ( !p ) return; + // print runtime statistics + if ( fProfile && p->nCalls ) + { + double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc; + double MemOther = sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs); + clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer; + printf( "Abstraction refinement runtime statistics:\n" ); + ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal ); + ABC_PRTP( "Justification", p->timeBwd, p->timeTotal ); + ABC_PRTP( "Verification ", p->timeVer, p->timeTotal ); + ABC_PRTP( "Other ", timeOther, p->timeTotal ); + ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); + printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n", + p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) ); + } + + Gia_ManCleanMark0(p->pGia); + Gia_ManCleanMark1(p->pGia); + Gia_ManStaticFanoutStop(p->pGia); +// Gia_ManSetPhase(p->pGia); + Vec_IntFree( p->vIsopMem ); + Vec_IntFree( p->vSatVars ); + Vec_IntFree( p->vSat2Ids ); + Vec_StrFree( p->vCounts ); + Vec_IntFree( p->vFanins ); + Vec_IntFree( p->vObjs ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); +} +double Rnm_ManMemoryUsage( Rnm_Man_t * p ) +{ + return (double)(sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs)); +} + + +/**Function************************************************************* + + Synopsis [Collect internal objects to be used in value propagation.] + + Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rnm_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs, int nAddOn ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCo(pObj) ) + Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn ); + else if ( Gia_ObjIsAnd(pObj) ) + { + Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn ); + Rnm_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs, nAddOn ); + } + else if ( !Gia_ObjIsRo(p, pObj) ) + assert( 0 ); + pObj->Value = Vec_IntSize(vObjs) + nAddOn; + Vec_IntPush( vObjs, Gia_ObjId(p, pObj) ); +} +void Rnm_ManCollect( Rnm_Man_t * p ) +{ + Gia_Obj_t * pObj = NULL; + int i; + // mark const/PIs/PPIs + Gia_ManIncrementTravId( p->pGia ); + Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); + Gia_ManConst0(p->pGia)->Value = 0; + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + Gia_ObjSetTravIdCurrent( p->pGia, pObj ); + pObj->Value = 1 + i; + } + // collect objects + Vec_IntClear( p->vObjs ); + Rnm_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs, 1 + Vec_IntSize(p->vMap) ); + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + if ( Gia_ObjIsRo(p->pGia, pObj) ) + Rnm_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs, 1 + Vec_IntSize(p->vMap) ); + // the last object should be a CO + assert( Gia_ObjIsCo(pObj) ); + assert( (int)pObj->Value == Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) ); +} +void Rnm_ManCleanValues( Rnm_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + pObj->Value = 0; + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + pObj->Value = 0; +} + +/**Function************************************************************* + + Synopsis [Performs sensitization analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rnm_ManSensitize( Rnm_Man_t * p ) +{ + Rnm_Obj_t * pRnm, * pRnm0, * pRnm1; + Gia_Obj_t * pObj; + int f, i, iBit = p->pCex->nRegs; + // const0 is initialized automatically in all timeframes + for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) + { + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + pRnm = Rnm_ManObj( p, pObj, f ); + pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i ); + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + { + assert( pObj->Value > 0 ); + pRnm->Prio = pObj->Value; + pRnm->fPPi = 1; + } + } + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + { + assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ); + pRnm = Rnm_ManObj( p, pObj, f ); + assert( !pRnm->fPPi ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f == 0 ) + continue; + pRnm0 = Rnm_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); + pRnm->Value = pRnm0->Value; + pRnm->Prio = pRnm0->Prio; + continue; + } + if ( Gia_ObjIsCo(pObj) ) + { + pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); + pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)); + pRnm->Prio = pRnm0->Prio; + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); + pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f ); + pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj)); + if ( pRnm->Value == 1 ) + pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio ); + else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice + else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) + pRnm->Prio = pRnm0->Prio; + else + pRnm->Prio = pRnm1->Prio; + } + } + assert( iBit == p->pCex->nBits ); + pRnm = Rnm_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame ); + if ( pRnm->Value != 1 ) + printf( "Output value is incorrect.\n" ); + return pRnm->Prio; +} + + +/**Function************************************************************* + + Synopsis [Drive implications of the given node towards primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rnm_ManJustifyPropFanout_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect ) +{ + Rnm_Obj_t * pRnm0, * pRnm1, * pRnm = Rnm_ManObj( p, pObj, f ); + Gia_Obj_t * pFanout = NULL; + int i, k;//, Id = Gia_ObjId(p->pGia, pObj); + assert( pRnm->fVisit == 0 ); + pRnm->fVisit = 1; + if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ) + { + Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1; + p->nVisited++; + } + if ( pRnm->fPPi ) + { + assert( (int)pRnm->Prio > 0 ); + for ( i = p->pCex->iFrame; i >= 0; i-- ) + if ( !Rnm_ManObj(p, pObj, i)->fVisit ) + Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect ); + Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); + return; + } + if ( (Gia_ObjIsCo(pObj) && f == p->pCex->iFrame) || Gia_ObjIsPo(p->pGia, pObj) ) + return; + if ( Gia_ObjIsRi(p->pGia, pObj) ) + { + pFanout = Gia_ObjRiToRo(p->pGia, pObj); + if ( !Rnm_ManObj(p, pFanout, f+1)->fVisit ) + Rnm_ManJustifyPropFanout_rec( p, pFanout, f+1, vSelect ); + return; + } + assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) ); + Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k ) + { + Rnm_Obj_t * pRnmF; + if ( pFanout->Value == 0 ) + continue; + pRnmF = Rnm_ManObj(p, pFanout, f); + if ( pRnmF->fPPi || pRnmF->fVisit ) + continue; + if ( Gia_ObjIsCo(pFanout) ) + { + Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect ); + continue; + } + assert( Gia_ObjIsAnd(pFanout) ); + pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pFanout), f ); + pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pFanout), f ); + if ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRnm0->fVisit) || + ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRnm1->fVisit) || + ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRnm0->fVisit) && + ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRnm1->fVisit) ) ) + Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect ); + } +} +void Rnm_ManJustify_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect ) +{ + Rnm_Obj_t * pRnm = Rnm_ManObj( p, pObj, f ); + int i;//, Id = Gia_ObjId(p->pGia, pObj); + if ( pRnm->fVisit ) + return; + if ( p->fPropFanout ) + Rnm_ManJustifyPropFanout_rec( p, pObj, f, vSelect ); + else + { + pRnm->fVisit = 1; + if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ) + { + Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1; + p->nVisited++; + } + } + if ( pRnm->fPPi ) + { + assert( (int)pRnm->Prio > 0 ); + if ( p->fPropFanout ) + { + for ( i = p->pCex->iFrame; i >= 0; i-- ) + if ( !Rnm_ManObj(p, pObj, i)->fVisit ) + Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect ); + } + else + { + Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) ); +// for ( i = p->pCex->iFrame; i >= 0; i-- ) +// Rnm_ManObj(p, pObj, i)->fVisit = 1; + } + return; + } + if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) + return; + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect ); + return; + } + if ( Gia_ObjIsAnd(pObj) ) + { + Rnm_Obj_t * pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f ); + Rnm_Obj_t * pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f ); + if ( pRnm->Value == 1 ) + { + if ( pRnm0->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); + if ( pRnm1->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); + } + else // select one value + { + if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + { + if ( pRnm0->Prio <= pRnm1->Prio ) // choice + { + if ( pRnm0->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); + } + else + { + if ( pRnm1->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); + } + } + else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) + { + if ( pRnm0->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect ); + } + else if ( (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + { + if ( pRnm1->Prio > 0 ) + Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect ); + } + else assert( 0 ); + } + } + else assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [Performs refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rnm_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj; + int i, f, iBit = pCex->nRegs; + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis ) + { + Gia_ManForEachObjVec( vMap, p, pObj, i ) + { + pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i ); + if ( !Gia_ObjIsPi(p, pObj) ) + Gia_ObjTerSimSetX( pObj ); + else if ( pObj->Value ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap + { + if ( pObj->Value ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + Gia_ObjTerSimCo( pObj ); + else if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjTerSimAnd( pObj ); + else if ( f == 0 ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimRo( p, pObj ); + } + } + Gia_ManForEachObjVec( vMap, p, pObj, i ) + pObj->Value = 0; + pObj = Gia_ManPo( p, 0 ); + if ( !Gia_ObjTerSimGet1(pObj) ) + Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rnm_ManPrintSelected( Rnm_Man_t * p, Vec_Int_t * vSelected ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + { + if ( Vec_IntFind(vSelected, Gia_ObjId(p->pGia, pObj)) >= 0 ) + printf( "1" ), Counter++; + else + printf( "0" ); + } + else + printf( "-" ); + } + printf( " %3d\n", Counter ); +} + + + + + +/**Function************************************************************* + + Synopsis [Perform structural analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ga2_StructAnalize( Gia_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInter, Vec_Int_t * vSelect ) +{ + Vec_Int_t * vLeaves; + Gia_Obj_t * pObj, * pFanin; + int i, k; + // clean labels + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = pObj->fMark1 = 0; + // label frontier + Gia_ManForEachObjVec( vFront, p, pObj, i ) + pObj->fMark0 = 1, pObj->fMark1 = 0; + // label objects + Gia_ManForEachObjVec( vInter, p, pObj, i ) + pObj->fMark1 = 0, pObj->fMark1 = 1; + // label selected + Gia_ManForEachObjVec( vSelect, p, pObj, i ) + pObj->fMark1 = 1, pObj->fMark1 = 1; + // explore selected + printf( "\n" ); + Gia_ManForEachObjVec( vSelect, p, pObj, i ) + { + printf( "Selected %6d : ", Gia_ObjId(p, pObj) ); + printf( "\n" ); + vLeaves = Ga2_ObjLeaves( p, pObj ); + Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) + { + printf( " " ); + printf( "%6d ", Gia_ObjId(p, pFanin) ); + if ( pFanin->fMark0 && pFanin->fMark1 ) + printf( "select" ); + else if ( pFanin->fMark0 && !pFanin->fMark1 ) + printf( "front" ); + else if ( !pFanin->fMark0 && pFanin->fMark1 ) + printf( "internal" ); + else if ( !pFanin->fMark0 && !pFanin->fMark1 ) + printf( "new" ); + printf( "\n" ); + } + } +} + + +/**Function************************************************************* + + Synopsis [Finds essential objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Ga2_FilterSelected( Rnm_Man_t * p, Vec_Int_t * vSelect ) +{ + Vec_Int_t * vNew, * vLeaves; + Gia_Obj_t * pObj, * pFanin; + int i, k, RetValue;//, Counters[3] = {0}; +/* + // check that selected are not visited + Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) + assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 1 ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + if ( Vec_IntFind(vSelect, Gia_ObjId(p->pGia, pObj)) == -1 ) + assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 ); +*/ + + // verify +// Gia_ManForEachObj( p->pGia, pObj, i ) +// assert( Rnm_ObjCount(p, pObj) == 0 ); + + // increment fanin counters + Vec_IntClear( p->vFanins ); + Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) + { + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + if ( Rnm_ObjAddToCount(p, pFanin) == 0 ) + Vec_IntPush( p->vFanins, Gia_ObjId(p->pGia, pFanin) ); + } + + // find selected objects, which create potential constraints + // - flop objects + // - objects whose fanin belongs to the justified area + // - objects whose fanins overlap + // (these do not guantee reconvergence, but may potentially have it) + // (other objects cannot have reconvergence, even if they are added) + vNew = Vec_IntAlloc( 100 ); + Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i ) + { + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) ); + continue; + } + vLeaves = Ga2_ObjLeaves( p->pGia, pObj ); + Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) + { + if ( Gia_ObjIsConst0(pFanin) + || (pFanin->Value && Rnm_ManObj(p, pFanin, 0)->fVisit0 == 1) + || Rnm_ObjCount(p, pFanin) > 1 + ) + { + Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) ); + break; + } + } +// Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k ) +// { +// Counters[1] += (pFanin->Value && Rnm_ManObj( p, pFanin, 0 )->fVisit0 == 1); +// Counters[2] += (Rnm_ObjCount(p, pFanin) > 1); +// } + } + RetValue = Vec_IntUniqify( vNew ); + assert( RetValue == 0 ); + +// printf( "\n*** Select = %5d. New = %5d. Flops = %5d. Visited = %5d. Fanins = %5d.\n", +// Vec_IntSize(vSelect), Vec_IntSize(vNew), Counters[0], Counters[1], Counters[2] ); + + // clear fanin counters + Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i ) + Rnm_ObjSetCount( p, pObj, 0 ); + return vNew; +} + + +/**Function************************************************************* + + Synopsis [Computes the refinement for a given counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose ) +{ + int fVerify = 0; +// int fPostProcess = 1; + Vec_Int_t * vSelected = Vec_IntAlloc( 100 ); + Vec_Int_t * vNew; + clock_t clk, clk2 = clock(); + int RetValue; + p->nCalls++; +// Gia_ManCleanValue( p->pGia ); + // initialize + p->pCex = pCex; + p->vMap = vMap; + p->fPropFanout = fPropFanout; + p->fVerbose = fVerbose; + // collects used objects + Rnm_ManCollect( p ); + // initialize datastructure + p->nObjsFrame = 1 + Vec_IntSize(vMap) + Vec_IntSize(p->vObjs); + p->nObjs = p->nObjsFrame * (pCex->iFrame + 1); + if ( p->nObjs > p->nObjsAlloc ) + p->pObjs = ABC_REALLOC( Rnm_Obj_t, p->pObjs, (p->nObjsAlloc = p->nObjs + 10000) ); + memset( p->pObjs, 0, sizeof(Rnm_Obj_t) * p->nObjs ); + // propagate priorities + clk = clock(); + if ( Rnm_ManSensitize( p ) ) // the CEX is not a true CEX + { + p->timeFwd += clock() - clk; + // select refinement + clk = clock(); + p->nVisited = 0; + Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), pCex->iFrame, vSelected ); + RetValue = Vec_IntUniqify( vSelected ); +// assert( RetValue == 0 ); + p->timeBwd += clock() - clk; + } + + if ( fPostProcess ) + { + vNew = Ga2_FilterSelected( p, vSelected ); + if ( Vec_IntSize(vNew) > 0 ) + { + Vec_IntFree( vSelected ); + vSelected = vNew; + } + else + { + Vec_IntFree( vNew ); + // printf( "\nBig refinement.\n" ); + } + } + else + { +/* + vNew = Rnm_ManRefineUnsatCore( p, vSelected ); + if ( Vec_IntSize(vNew) > 0 ) + { + Vec_IntFree( vSelected ); + vSelected = vNew; +// Vec_IntFree( vNew ); + } + else + { + Vec_IntFree( vNew ); + // printf( "\nBig refinement.\n" ); + } +*/ + } + + // clean values + Rnm_ManCleanValues( p ); + + // verify (empty) refinement + if ( fVerify ) + { + clk = clock(); + Rnm_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected ); + p->timeVer += clock() - clk; + } + +// printf( "\nOriginal (%d): \n", Vec_IntSize(p->vMap) ); +// Rnm_ManPrintSelected( p, vSelected ); + +// Ga2_StructAnalize( p->pGia, vMap, p->vObjs, vSelected ); +// printf( "\nObjects = %5d. Visited = %5d.\n", Vec_IntSize(p->vObjs), p->nVisited ); + +// Vec_IntReverseOrder( vSelected ); + p->timeTotal += clock() - clk2; + p->nRefines += Vec_IntSize(vSelected); + return vSelected; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absRef.h b/src/proof/abs/absRef.h new file mode 100644 index 00000000..ca46c776 --- /dev/null +++ b/src/proof/abs/absRef.h @@ -0,0 +1,67 @@ +/**CFile**************************************************************** + + FileName [absRef.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Refinement manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absRef.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__proof_abs__AbsRef_h +#define ABC__proof_abs__AbsRef_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Rnm_Man_t_ Rnm_Man_t; // refinement manager + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== giaAbsRef.c ===========================================================*/ +extern Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia ); +extern void Rnm_ManStop( Rnm_Man_t * p, int fProfile ); +extern double Rnm_ManMemoryUsage( Rnm_Man_t * p ); +extern Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/proof/abs/absRef2.c b/src/proof/abs/absRef2.c new file mode 100644 index 00000000..7fb26e5a --- /dev/null +++ b/src/proof/abs/absRef2.c @@ -0,0 +1,916 @@ +/**CFile**************************************************************** + + FileName [absRef2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Refinement manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absRef2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" +#include "absRef2.h" + +ABC_NAMESPACE_IMPL_START + +/* + Description of the refinement manager + + This refinement manager should be + * started by calling Rf2_ManStart() + this procedure takes one argument, the user's seq miter as a GIA manager + - the manager should have only one property output + - this manager should not change while the refinement manager is alive + - it cannot be used by external applications for any purpose + - when the refinement manager stop, GIA manager is the same as at the beginning + - in the meantime, it will have some data-structures attached to its nodes... + * stopped by calling Rf2_ManStop() + * between starting and stopping, refinements are obtained by calling Rf2_ManRefine() + + Procedure Rf2_ManRefine() takes the following arguments: + * the refinement manager previously started by Rf2_ManStart() + * counter-example (CEX) obtained by abstracting some logic of GIA + * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager + - only PI, flop outputs, and internal AND nodes can be used in vMap + - the ordering of objects in vMap is not important + - however, the index of a non-PI object in vMap is used as its priority + (the smaller the index, the more likely this non-PI object apears in a refinement) + - only the logic between PO and the objects listed in vMap is traversed by the manager + (as a result, GIA can be arbitrarily large, but only objects used in the abstraction + and the pseudo-PI, that is, objects in the cut, will be visited by the manager) + * flag fPropFanout defines whether value propagation is done through the fanout + - it this flag is enabled, theoretically refinement should be better (the result smaller) + * flag fVerbose may print some statistics + + The refinement manager returns a minimal-size array of integer IDs of GIA objects + which should be added to the abstraction to possibly prevent the given counter-example + - only flop output and internal AND nodes from vMap may appear in the resulting array + - if the resulting array is empty, the CEX is a true CEX + (in other words, non-PI objects are not needed to set the PO value to 1) + + Verification of the selected refinement is performed by + - initializing all PI objects in vMap to value 0 or 1 they have in the CEX + - initializing all remaining objects in vMap to value X + - initializing objects used in the refiment to value 0 or 1 they have in the CEX + - simulating through as many timeframes as required by the CEX + - if the PO value in the last frame is 1, the refinement is correct + (however, the minimality of the refinement is not currently checked) + +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Rf2_Obj_t_ Rf2_Obj_t; // refinement object +struct Rf2_Obj_t_ +{ + unsigned Value : 1; // binary value + unsigned fVisit : 1; // visited object + unsigned fPPi : 1; // PPI object + unsigned Prio : 24; // priority (0 - highest) +}; + +struct Rf2_Man_t_ +{ + // user data + Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package) + Abc_Cex_t * pCex; // counter-example + Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order) + int fPropFanout; // propagate fanouts + int fVerbose; // verbose flag + // traversing data + Vec_Int_t * vObjs; // internal objects used in value propagation + Vec_Int_t * vFanins; // fanins of the PPI nodes + Vec_Int_t * pvVecs; // vectors of integers for each object + Vec_Vec_t * vGrp2Ppi; // for each node, the set of PPIs to include + int nMapWords; + // internal data + Rf2_Obj_t * pObjs; // refinement objects + int nObjs; // the number of used objects + int nObjsAlloc; // the number of allocated objects + int nObjsFrame; // the number of used objects in each frame + int nCalls; // total number of calls + int nRefines; // total refined objects + // statistics + clock_t timeFwd; // forward propagation + clock_t timeBwd; // backward propagation + clock_t timeVer; // ternary simulation + clock_t timeTotal; // other time +}; + +// accessing the refinement object +static inline Rf2_Obj_t * Rf2_ManObj( Rf2_Man_t * p, Gia_Obj_t * pObj, int f ) +{ + assert( Gia_ObjIsConst0(pObj) || pObj->Value ); + assert( (int)pObj->Value < p->nObjsFrame ); + assert( f >= 0 && f <= p->pCex->iFrame ); + return p->pObjs + f * p->nObjsFrame + pObj->Value; +} + +static inline Vec_Int_t * Rf2_ObjVec( Rf2_Man_t * p, Gia_Obj_t * pObj ) +{ + return p->pvVecs + Gia_ObjId(p->pGia, pObj); +} + + +static inline unsigned * Rf2_ObjA( Rf2_Man_t * p, Gia_Obj_t * pObj ) +{ + return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj)); +} +static inline unsigned * Rf2_ObjN( Rf2_Man_t * p, Gia_Obj_t * pObj ) +{ + return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj)) + p->nMapWords; +} +static inline void Rf2_ObjClear( Rf2_Man_t * p, Gia_Obj_t * pObj ) +{ + Vec_IntFill( Rf2_ObjVec(p, pObj), 2*p->nMapWords, 0 ); +} +static inline void Rf2_ObjStart( Rf2_Man_t * p, Gia_Obj_t * pObj, int i ) +{ + Vec_Int_t * vVec = Rf2_ObjVec(p, pObj); + int w; + Vec_IntClear( vVec ); + for ( w = 0; w < p->nMapWords; w++ ) + Vec_IntPush( vVec, 0 ); + for ( w = 0; w < p->nMapWords; w++ ) + Vec_IntPush( vVec, ~0 ); + Abc_InfoSetBit( Rf2_ObjA(p, pObj), i ); + Abc_InfoXorBit( Rf2_ObjN(p, pObj), i ); +} +static inline void Rf2_ObjCopy( Rf2_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) +{ + assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords ); + memcpy( Rf2_ObjA(p, pObj), Rf2_ObjA(p, pFanin), sizeof(unsigned) * 2 * p->nMapWords ); +} +static inline void Rf2_ObjDeriveAnd( Rf2_Man_t * p, Gia_Obj_t * pObj, int One ) +{ + unsigned * pInfo, * pInfo0, * pInfo1; + int i; + assert( Gia_ObjIsAnd(pObj) ); + assert( One == (int)pObj->fMark0 ); + assert( One == (int)(Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) ); + assert( One == (int)(Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) ); + assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords ); + + pInfo = Rf2_ObjA( p, pObj ); + pInfo0 = Rf2_ObjA( p, Gia_ObjFanin0(pObj) ); + pInfo1 = Rf2_ObjA( p, Gia_ObjFanin1(pObj) ); + for ( i = 0; i < p->nMapWords; i++ ) + pInfo[i] = One ? (pInfo0[i] & pInfo1[i]) : (pInfo0[i] | pInfo1[i]); + + pInfo = Rf2_ObjN( p, pObj ); + pInfo0 = Rf2_ObjN( p, Gia_ObjFanin0(pObj) ); + pInfo1 = Rf2_ObjN( p, Gia_ObjFanin1(pObj) ); + for ( i = 0; i < p->nMapWords; i++ ) + pInfo[i] = One ? (pInfo0[i] | pInfo1[i]) : (pInfo0[i] & pInfo1[i]); +} +static inline void Rf2_ObjPrint( Rf2_Man_t * p, Gia_Obj_t * pRoot ) +{ + Gia_Obj_t * pObj; + unsigned * pInfo; + int i; + pInfo = Rf2_ObjA( p, pRoot ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + if ( !Gia_ObjIsPi(p->pGia, pObj) ) + printf( "%d", Abc_InfoHasBit(pInfo, i) ); + printf( "\n" ); + pInfo = Rf2_ObjN( p, pRoot ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + if ( !Gia_ObjIsPi(p->pGia, pObj) ) + printf( "%d", !Abc_InfoHasBit(pInfo, i) ); + printf( "\n" ); + +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates a new manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia ) +{ + Rf2_Man_t * p; + assert( Gia_ManPoNum(pGia) == 1 ); + p = ABC_CALLOC( Rf2_Man_t, 1 ); + p->pGia = pGia; + p->vObjs = Vec_IntAlloc( 1000 ); + p->vFanins = Vec_IntAlloc( 1000 ); + p->pvVecs = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(pGia) ); + p->vGrp2Ppi = Vec_VecStart( 100 ); + Gia_ManCleanMark0(pGia); + Gia_ManCleanMark1(pGia); + return p; +} +void Rf2_ManStop( Rf2_Man_t * p, int fProfile ) +{ + if ( !p ) return; + // print runtime statistics + if ( fProfile && p->nCalls ) + { + double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc; + double MemOther = sizeof(Rf2_Man_t) + sizeof(Rf2_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs); + clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer; + printf( "Abstraction refinement runtime statistics:\n" ); + ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal ); + ABC_PRTP( "Justification", p->timeBwd, p->timeTotal ); + ABC_PRTP( "Verification ", p->timeVer, p->timeTotal ); + ABC_PRTP( "Other ", timeOther, p->timeTotal ); + ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); + printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n", + p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) ); + } + Vec_IntFree( p->vObjs ); + Vec_IntFree( p->vFanins ); + Vec_VecFree( p->vGrp2Ppi ); + ABC_FREE( p->pvVecs ); + ABC_FREE( p ); +} +double Rf2_ManMemoryUsage( Rf2_Man_t * p ) +{ + return (double)(sizeof(Rf2_Man_t) + sizeof(Vec_Int_t) * Gia_ManObjNum(p->pGia)); +} + + +/**Function************************************************************* + + Synopsis [Collect internal objects to be used in value propagation.] + + Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rf2_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCo(pObj) ) + Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs ); + else if ( Gia_ObjIsAnd(pObj) ) + { + Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs ); + Rf2_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs ); + } + else if ( !Gia_ObjIsRo(p, pObj) ) + assert( 0 ); + Vec_IntPush( vObjs, Gia_ObjId(p, pObj) ); +} +void Rf2_ManCollect( Rf2_Man_t * p ) +{ + Gia_Obj_t * pObj = NULL; + int i; + // mark const/PIs/PPIs + Gia_ManIncrementTravId( p->pGia ); + Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + Gia_ObjSetTravIdCurrent( p->pGia, pObj ); + } + // collect objects + Vec_IntClear( p->vObjs ); + Rf2_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs ); + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + if ( Gia_ObjIsRo(p->pGia, pObj) ) + Rf2_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs ); + // the last object should be a CO + assert( Gia_ObjIsCo(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Performs sensitization analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rf2_ManSensitize( Rf2_Man_t * p ) +{ + Rf2_Obj_t * pRnm, * pRnm0, * pRnm1; + Gia_Obj_t * pObj; + int f, i, iBit = p->pCex->nRegs; + // const0 is initialized automatically in all timeframes + for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) + { + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + pRnm = Rf2_ManObj( p, pObj, f ); + pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i ); + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + { + assert( pObj->Value > 0 ); + pRnm->Prio = pObj->Value; + pRnm->fPPi = 1; + } + } + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + { + assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ); + pRnm = Rf2_ManObj( p, pObj, f ); + assert( !pRnm->fPPi ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f == 0 ) + continue; + pRnm0 = Rf2_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 ); + pRnm->Value = pRnm0->Value; + pRnm->Prio = pRnm0->Prio; + continue; + } + if ( Gia_ObjIsCo(pObj) ) + { + pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f ); + pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)); + pRnm->Prio = pRnm0->Prio; + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f ); + pRnm1 = Rf2_ManObj( p, Gia_ObjFanin1(pObj), f ); + pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj)); + if ( pRnm->Value == 1 ) + pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio ); + else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 ) + pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice + else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 ) + pRnm->Prio = pRnm0->Prio; + else + pRnm->Prio = pRnm1->Prio; + } + } + assert( iBit == p->pCex->nBits ); + pRnm = Rf2_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame ); + if ( pRnm->Value != 1 ) + printf( "Output value is incorrect.\n" ); + return pRnm->Prio; +} + + + +/**Function************************************************************* + + Synopsis [Performs refinement.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rf2_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj; + int i, f, iBit = pCex->nRegs; + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis ) + { + Gia_ManForEachObjVec( vMap, p, pObj, i ) + { + pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i ); + if ( !Gia_ObjIsPi(p, pObj) ) + Gia_ObjTerSimSetX( pObj ); + else if ( pObj->Value ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap + { + if ( pObj->Value ) + Gia_ObjTerSimSet1( pObj ); + else + Gia_ObjTerSimSet0( pObj ); + } + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + { + if ( Gia_ObjIsCo(pObj) ) + Gia_ObjTerSimCo( pObj ); + else if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjTerSimAnd( pObj ); + else if ( f == 0 ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimRo( p, pObj ); + } + } + Gia_ManForEachObjVec( vMap, p, pObj, i ) + pObj->Value = 0; + pObj = Gia_ManPo( p, 0 ); + if ( !Gia_ObjTerSimGet1(pObj) ) + Abc_Print( 1, "\nRefinement verification has failed!!!\n" ); +} + +/**Function************************************************************* + + Synopsis [Computes the refinement for a given counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rf2_ManGatherFanins_rec( Rf2_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vFanins, int Depth, int RootId, int fFirst ) +{ + if ( Gia_ObjIsTravIdCurrent(p->pGia, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p->pGia, pObj); + if ( pObj->fPhase && !fFirst ) + { + Vec_Int_t * vVec = Rf2_ObjVec( p, pObj ); +// if ( Vec_IntEntry( vVec, 0 ) == 0 ) +// return; + if ( Vec_IntSize(vVec) == 0 ) + Vec_IntPush( vFanins, Gia_ObjId(p->pGia, pObj) ); + Vec_IntPushUnique( vVec, RootId ); + if ( Depth == 0 ) + return; + } + if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) ) + return; + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + assert( pObj->fPhase ); + pObj = Gia_ObjRoToRi(p->pGia, pObj); + Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - 1, RootId, 0 ); + } + else if ( Gia_ObjIsAnd(pObj) ) + { + Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 ); + Rf2_ManGatherFanins_rec( p, Gia_ObjFanin1(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 ); + } + else assert( 0 ); +} +void Rf2_ManGatherFanins( Rf2_Man_t * p, int Depth ) +{ + Vec_Int_t * vUsed; + Vec_Int_t * vVec; + Gia_Obj_t * pObj; + int i, k, Entry; + // mark PPIs + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + vVec = Rf2_ObjVec( p, pObj ); + assert( Vec_IntSize(vVec) == 0 ); + Vec_IntPush( vVec, 0 ); + } + // collect internal + Vec_IntClear( p->vFanins ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + if ( Gia_ObjIsPi(p->pGia, pObj) ) + continue; + Gia_ManIncrementTravId( p->pGia ); + Rf2_ManGatherFanins_rec( p, pObj, p->vFanins, Depth, i, 1 ); + } + + vUsed = Vec_IntStart( Vec_IntSize(p->vMap) ); + + // evaluate collected + printf( "\nMap (%d): ", Vec_IntSize(p->vMap) ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + vVec = Rf2_ObjVec( p, pObj ); + if ( Vec_IntSize(vVec) > 1 ) + printf( "%d=%d ", i, Vec_IntSize(vVec) - 1 ); + Vec_IntForEachEntryStart( vVec, Entry, k, 1 ) + Vec_IntAddToEntry( vUsed, Entry, 1 ); + Vec_IntClear( vVec ); + } + printf( "\n" ); + // evaluate internal + printf( "Int (%d): ", Vec_IntSize(p->vFanins) ); + Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i ) + { + vVec = Rf2_ObjVec( p, pObj ); + if ( Vec_IntSize(vVec) > 1 ) + printf( "%d=%d ", i, Vec_IntSize(vVec) ); + if ( Vec_IntSize(vVec) > 1 ) + Vec_IntForEachEntry( vVec, Entry, k ) + Vec_IntAddToEntry( vUsed, Entry, 1 ); + Vec_IntClear( vVec ); + } + printf( "\n" ); + // evaluate PPIs + Vec_IntForEachEntry( vUsed, Entry, k ) + printf( "%d ", Entry ); + printf( "\n" ); + + Vec_IntFree( vUsed ); +} + + +/**Function************************************************************* + + Synopsis [Sort, make dup- and containment-free, and filter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Rf2_ManCountPpis( Rf2_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Sort, make dup- and containment-free, and filter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Rf2_ManPrintVector( Vec_Int_t * p, int Num ) +{ + int i, k, Entry; + Vec_IntForEachEntry( p, Entry, i ) + { + for ( k = 0; k < Num; k++ ) + printf( "%c", '0' + ((Entry>>k) & 1) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Sort, make dup- and containment-free, and filter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Rf2_ManProcessVector( Vec_Int_t * p, int Limit ) +{ +// int Start = Vec_IntSize(p); + int Start = 0; + int i, j, k, Entry, Entry2; +// printf( "%d", Vec_IntSize(p) ); + if ( Start > 5 ) + { + printf( "Before: \n" ); + Rf2_ManPrintVector( p, 31 ); + } + + k = 0; + Vec_IntForEachEntry( p, Entry, i ) + if ( Gia_WordCountOnes((unsigned)Entry) <= Limit ) + Vec_IntWriteEntry( p, k++, Entry ); + Vec_IntShrink( p, k ); + Vec_IntSort( p, 0 ); + k = 0; + Vec_IntForEachEntry( p, Entry, i ) + { + Vec_IntForEachEntryStop( p, Entry2, j, i ) + if ( (Entry2 & Entry) == Entry2 ) // Entry2 is a subset of Entry + break; + if ( j == i ) // Entry is not contained in any Entry2 + Vec_IntWriteEntry( p, k++, Entry ); + } + Vec_IntShrink( p, k ); +// printf( "->%d ", Vec_IntSize(p) ); + if ( Start > 5 ) + { + printf( "After: \n" ); + Rf2_ManPrintVector( p, 31 ); + k = 0; + } +} + +/**Function************************************************************* + + Synopsis [Assigns a unique justifification ID for each PPI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rf2_ManAssignJustIds( Rf2_Man_t * p ) +{ + Gia_Obj_t * pObj; + int nPpis = Rf2_ManCountPpis( p ); + int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0); + int i, k = 0; + Vec_VecClear( p->vGrp2Ppi ); + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + Vec_VecPushInt( p->vGrp2Ppi, (k++ / nGroupSize), i ); + printf( "Considering %d PPIs combined into %d groups of size %d.\n", k, (k-1)/nGroupSize+1, nGroupSize ); + return (k-1)/nGroupSize+1; +} + +/**Function************************************************************* + + Synopsis [Sort, make dup- and containment-free, and filter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Rf2_ManPrintVectorSpecial( Rf2_Man_t * p, Vec_Int_t * vVec ) +{ + Gia_Obj_t * pObj; + int nPpis = Rf2_ManCountPpis( p ); + int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0); + int s, i, k, Entry, Counter; + + Vec_IntForEachEntry( vVec, Entry, s ) + { + k = 0; + Counter = 0; + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI + { + if ( (Entry >> (k++ / nGroupSize)) & 1 ) + printf( "1" ), Counter++; + else + printf( "0" ); + } + else + printf( "-" ); + } + printf( " %3d \n", Counter ); + } +} + +/**Function************************************************************* + + Synopsis [Performs justification propagation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Rf2_ManPropagate( Rf2_Man_t * p, int Limit ) +{ + Vec_Int_t * vVec, * vVec0, * vVec1; + Gia_Obj_t * pObj; + int f, i, k, j, Entry, Entry2, iBit = p->pCex->nRegs; + // init constant + pObj = Gia_ManConst0(p->pGia); + pObj->fMark0 = 0; + Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 ); + // iterate through the timeframes + for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) + { + // initialize frontier values and init justification sets + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i ); + Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 ); + } + // assign justification sets for PPis + Vec_VecForEachLevelInt( p->vGrp2Ppi, vVec, i ) + Vec_IntForEachEntry( vVec, Entry, k ) + { + assert( i < 31 ); + pObj = Gia_ManObj( p->pGia, Vec_IntEntry(p->vMap, Entry) ); + assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 1 ); + Vec_IntAddToEntry( Rf2_ObjVec(p, pObj), 0, (1 << i) ); + } + // propagate internal nodes + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + { + pObj->fMark0 = 0; + vVec = Rf2_ObjVec(p, pObj); + Vec_IntClear( vVec ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f == 0 ) + { + Vec_IntPush( vVec, 0 ); + continue; + } + pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0; + vVec0 = Rf2_ObjVec( p, Gia_ObjRoToRi(p->pGia, pObj) ); + Vec_IntAppend( vVec, vVec0 ); + continue; + } + if ( Gia_ObjIsCo(pObj) ) + { + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); + vVec0 = Rf2_ObjVec( p, Gia_ObjFanin0(pObj) ); + Vec_IntAppend( vVec, vVec0 ); + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + vVec0 = Rf2_ObjVec(p, Gia_ObjFanin0(pObj)); + vVec1 = Rf2_ObjVec(p, Gia_ObjFanin1(pObj)); + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + if ( pObj->fMark0 == 1 ) + { + Vec_IntForEachEntry( vVec0, Entry, k ) + Vec_IntForEachEntry( vVec1, Entry2, j ) + Vec_IntPush( vVec, Entry | Entry2 ); + Rf2_ManProcessVector( vVec, Limit ); + } + else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 ) + { + Vec_IntAppend( vVec, vVec0 ); + Vec_IntAppend( vVec, vVec1 ); + Rf2_ManProcessVector( vVec, Limit ); + } + else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 ) + Vec_IntAppend( vVec, vVec0 ); + else + Vec_IntAppend( vVec, vVec1 ); + } + } + assert( iBit == p->pCex->nBits ); + if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 ) + printf( "Output value is incorrect.\n" ); + return Rf2_ObjVec(p, Gia_ManPo(p->pGia, 0)); +} + +/**Function************************************************************* + + Synopsis [Performs justification propagation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rf2_ManBounds( Rf2_Man_t * p ) +{ + Gia_Obj_t * pObj; + int f, i, iBit = p->pCex->nRegs; + // init constant + pObj = Gia_ManConst0(p->pGia); + pObj->fMark0 = 0; + Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) ); + // iterate through the timeframes + for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis ) + { + // initialize frontier values and init justification sets + Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i ) + { + assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) ); + pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i ); + Rf2_ObjStart( p, pObj, i ); + } + // propagate internal nodes + Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i ) + { + pObj->fMark0 = 0; + Rf2_ObjClear( p, pObj ); + if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( f == 0 ) + { + Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + i ); + continue; + } + pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0; + Rf2_ObjCopy( p, pObj, Gia_ObjRoToRi(p->pGia, pObj) ); + continue; + } + if ( Gia_ObjIsCo(pObj) ) + { + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); + Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) ); + continue; + } + assert( Gia_ObjIsAnd(pObj) ); + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + if ( pObj->fMark0 == 1 ) + Rf2_ObjDeriveAnd( p, pObj, 1 ); + else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 ) + Rf2_ObjDeriveAnd( p, pObj, 0 ); + else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 ) + Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) ); + else + Rf2_ObjCopy( p, pObj, Gia_ObjFanin1(pObj) ); + } + } + assert( iBit == p->pCex->nBits ); + if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 ) + printf( "Output value is incorrect.\n" ); + + printf( "Bounds: \n" ); + Rf2_ObjPrint( p, Gia_ManPo(p->pGia, 0) ); +} + +/**Function************************************************************* + + Synopsis [Computes the refinement for a given counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose ) +{ + Vec_Int_t * vJusts; +// Vec_Int_t * vSelected = Vec_IntAlloc( 100 ); + Vec_Int_t * vSelected = NULL; + clock_t clk, clk2 = clock(); + int nGroups; + p->nCalls++; + // initialize + p->pCex = pCex; + p->vMap = vMap; + p->fPropFanout = fPropFanout; + p->fVerbose = fVerbose; + // collects used objects + Rf2_ManCollect( p ); + // collect reconvergence points +// Rf2_ManGatherFanins( p, 2 ); + // propagate justification IDs + nGroups = Rf2_ManAssignJustIds( p ); + vJusts = Rf2_ManPropagate( p, 32 ); + +// printf( "\n" ); +// Rf2_ManPrintVector( vJusts, nGroups ); + Rf2_ManPrintVectorSpecial( p, vJusts ); + if ( Vec_IntSize(vJusts) == 0 ) + { + printf( "Empty set of justifying subsets.\n" ); + return NULL; + } + +// p->nMapWords = Abc_BitWordNum( Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) + 1 ); // Map + Flops + Const +// Rf2_ManBounds( p ); + + // select the result +// Abc_PrintTime( 1, "Time", clock() - clk2 ); + + // verify (empty) refinement + clk = clock(); +// Rf2_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected ); +// Vec_IntUniqify( vSelected ); +// Vec_IntReverseOrder( vSelected ); + p->timeVer += clock() - clk; + p->timeTotal += clock() - clk2; +// p->nRefines += Vec_IntSize(vSelected); + return vSelected; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absRef2.h b/src/proof/abs/absRef2.h new file mode 100644 index 00000000..df7774c0 --- /dev/null +++ b/src/proof/abs/absRef2.h @@ -0,0 +1,67 @@ +/**CFile**************************************************************** + + FileName [absRef2.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Refinement manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absRef2.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__proof_abs__AbsRef2_h +#define ABC__proof_abs__AbsRef2_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Rf2_Man_t_ Rf2_Man_t; // refinement manager + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== giaAbsRef.c ===========================================================*/ +extern Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia ); +extern void Rf2_ManStop( Rf2_Man_t * p, int fProfile ); +extern double Rf2_ManMemoryUsage( Rf2_Man_t * p ); +extern Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/proof/abs/absUtil.c b/src/proof/abs/absUtil.c new file mode 100644 index 00000000..60429496 --- /dev/null +++ b/src/proof/abs/absUtil.c @@ -0,0 +1,257 @@ +/**CFile**************************************************************** + + FileName [absUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Interface to pthreads.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abs_ParSetDefaults( Abs_Par_t * p ) +{ + memset( p, 0, sizeof(Abs_Par_t) ); + p->nFramesMax = 0; // maximum frames + p->nFramesStart = 0; // starting frame + p->nFramesPast = 4; // overlap frames + p->nConfLimit = 0; // conflict limit + p->nLearnedMax = 1000; // max number of learned clauses + p->nLearnedStart = 1000; // max number of learned clauses + p->nLearnedDelta = 200; // max number of learned clauses + p->nLearnedPerce = 70; // max number of learned clauses + p->nTimeOut = 0; // timeout in seconds + p->nRatioMin = 0; // stop when less than this % of object is abstracted + p->nRatioMax = 30; // restart when more than this % of object is abstracted + p->fUseTermVars = 0; // use terminal variables + p->fUseRollback = 0; // use rollback to the starting number of frames + p->fPropFanout = 1; // propagate fanouts during refinement + p->fVerbose = 0; // verbose flag + p->iFrame = -1; // the number of frames covered + p->iFrameProved = -1; // the number of frames proved + p->nFramesNoChangeLim = 1; // the number of frames without change to dump abstraction +} + +/**Function************************************************************* + + Synopsis [Converting VTA vector to GLA vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta ) +{ + Gia_Obj_t * pObj; + Vec_Int_t * vGla; + int nObjMask, nObjs = Gia_ManObjNum(p); + int i, Entry, nFrames = Vec_IntEntry( vVta, 0 ); + assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) ); + // get the bitmask + nObjMask = (1 << Abc_Base2Log(nObjs)) - 1; + assert( nObjs <= nObjMask ); + // go through objects + vGla = Vec_IntStart( nObjs ); + Vec_IntForEachEntryStart( vVta, Entry, i, nFrames+2 ) + { + pObj = Gia_ManObj( p, (Entry & nObjMask) ); + assert( Gia_ObjIsRo(p, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsConst0(pObj) ); + Vec_IntAddToEntry( vGla, (Entry & nObjMask), 1 ); + } + Vec_IntWriteEntry( vGla, 0, nFrames ); + return vGla; +} + +/**Function************************************************************* + + Synopsis [Converting GLA vector to VTA vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames ) +{ + Vec_Int_t * vVta; + int nObjBits, nObjMask, nObjs = Gia_ManObjNum(p); + int i, k, j, Entry, Counter, nGlaSize; + //. get the GLA size + nGlaSize = Vec_IntSum(vGla); + // get the bitmask + nObjBits = Abc_Base2Log(nObjs); + nObjMask = (1 << Abc_Base2Log(nObjs)) - 1; + assert( nObjs <= nObjMask ); + // go through objects + vVta = Vec_IntAlloc( 1000 ); + Vec_IntPush( vVta, nFrames ); + Counter = nFrames + 2; + for ( i = 0; i <= nFrames; i++, Counter += i * nGlaSize ) + Vec_IntPush( vVta, Counter ); + for ( i = 0; i < nFrames; i++ ) + for ( k = 0; k <= i; k++ ) + Vec_IntForEachEntry( vGla, Entry, j ) + if ( Entry ) + Vec_IntPush( vVta, (k << nObjBits) | j ); + Counter = Vec_IntEntry(vVta, nFrames+1); + assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) ); + return vVta; +} + +/**Function************************************************************* + + Synopsis [Converting GLA vector to FLA vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FlaConvertToGla_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + Vec_IntWriteEntry( vGla, Gia_ObjId(p, pObj), 1 ); + if ( Gia_ObjIsRo(p, pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); + Gia_FlaConvertToGla_rec( p, Gia_ObjFanin1(pObj), vGla ); +} + +/**Function************************************************************* + + Synopsis [Converting FLA vector to GLA vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla ) +{ + Vec_Int_t * vGla; + Gia_Obj_t * pObj; + int i; + // mark const0 and relevant CI objects + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p)); + Gia_ManForEachPi( p, pObj, i ) + Gia_ObjSetTravIdCurrent(p, pObj); + Gia_ManForEachRo( p, pObj, i ) + if ( !Vec_IntEntry(vFla, i) ) + Gia_ObjSetTravIdCurrent(p, pObj); + // label all objects reachable from the PO and selected flops + vGla = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_IntWriteEntry( vGla, 0, 1 ); + Gia_ManForEachPo( p, pObj, i ) + Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); + Gia_ManForEachRi( p, pObj, i ) + if ( Vec_IntEntry(vFla, i) ) + Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla ); + return vGla; +} + +/**Function************************************************************* + + Synopsis [Converting GLA vector to FLA vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla ) +{ + Vec_Int_t * vFla; + Gia_Obj_t * pObj; + int i; + vFla = Vec_IntStart( Gia_ManRegNum(p) ); + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) + Vec_IntWriteEntry( vFla, i, 1 ); + return vFla; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla ) +{ + Gia_Obj_t * pObj; + int i, Count = 0; + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) + Count++; + return Count; +} +int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla ) +{ + Gia_Obj_t * pObj; + int i, Count = 0; + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) ) + Count++; + return Count; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/absVta.c b/src/proof/abs/absVta.c new file mode 100644 index 00000000..7e85c661 --- /dev/null +++ b/src/proof/abs/absVta.c @@ -0,0 +1,1765 @@ +/**CFile**************************************************************** + + FileName [absVta.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Abstraction package.] + + Synopsis [Variable time-frame abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: absVta.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sat/bsat/satSolver2.h" +#include "base/main/main.h" +#include "abs.h" + +ABC_NAMESPACE_IMPL_START + +#define VTA_LARGE 0xFFFFFFF + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vta_Obj_t_ Vta_Obj_t; // object +struct Vta_Obj_t_ +{ + int iObj; + int iFrame; + int iNext; + unsigned Prio : 28; // related to VTA_LARGE + unsigned Value : 2; + unsigned fAdded : 1; + unsigned fVisit : 1; +}; + +typedef struct Vta_Man_t_ Vta_Man_t; // manager +struct Vta_Man_t_ +{ + // user data + Gia_Man_t * pGia; // AIG manager + Abs_Par_t * pPars; // parameters + // internal data + int nObjs; // the number of objects + int nObjsAlloc; // the number of objects allocated + int nBins; // number of hash table entries + int * pBins; // hash table bins + Vta_Obj_t * pObjs; // storage for objects + Vec_Int_t * vOrder; // objects in DPS order + // abstraction + int nObjBits; // the number of bits to represent objects + unsigned nObjMask; // object mask + Vec_Ptr_t * vFrames; // start abstraction for each frame + int nWords; // the number of words in the record + int nCexes; // the number of CEXes + int nObjAdded; // objects added to the abstraction + Vec_Int_t * vSeens; // seen objects + Vec_Bit_t * vSeenGla; // seen objects in all frames + int nSeenGla; // seen objects in all frames + int nSeenAll; // seen objects in all frames + // other data + Vec_Ptr_t * vCores; // unsat core for each frame + sat_solver2 * pSat; // incremental SAT solver + Vec_Int_t * vAddedNew; // the IDs of variables added to the solver + // statistics + clock_t timeSat; + clock_t timeUnsat; + clock_t timeCex; + clock_t timeOther; +}; + + +// ternary simulation + +#define VTA_VAR0 1 +#define VTA_VAR1 2 +#define VTA_VARX 3 + +static inline int Vta_ValIs0( Vta_Obj_t * pThis, int fCompl ) +{ + if ( pThis->Value == VTA_VAR1 && fCompl ) + return 1; + if ( pThis->Value == VTA_VAR0 && !fCompl ) + return 1; + return 0; +} +static inline int Vta_ValIs1( Vta_Obj_t * pThis, int fCompl ) +{ + if ( pThis->Value == VTA_VAR0 && fCompl ) + return 1; + if ( pThis->Value == VTA_VAR1 && !fCompl ) + return 1; + return 0; +} + +static inline Vta_Obj_t * Vta_ManObj( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; } +static inline int Vta_ObjId( Vta_Man_t * p, Vta_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } + +#define Vta_ManForEachObj( p, pObj, i ) \ + for ( i = 1; (i < p->nObjs) && ((pObj) = Vta_ManObj(p, i)); i++ ) +#define Vta_ManForEachObjObj( p, pObjVta, pObjGia, i ) \ + for ( i = 1; (i < p->nObjs) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ ) +#define Vta_ManForEachObjObjReverse( p, pObjVta, pObjGia, i ) \ + for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ ) + +#define Vta_ManForEachObjVec( vVec, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Vta_ManForEachObjVecReverse( vVec, p, pObj, i ) \ + for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i-- ) + +#define Vta_ManForEachObjObjVec( vVec, p, pObj, pObjG, i ) \ + for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i++ ) +#define Vta_ManForEachObjObjVecReverse( vVec, p, pObj, pObjG, i ) \ + for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i-- ) + + +// abstraction is given as an array of integers: +// - the first entry is the number of timeframes (F) +// - the next (F+1) entries give the beginning position of each timeframe +// - the following entries give the object IDs +// invariant: assert( vec[vec[0]+1] == size(vec) ); + +extern void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Converting from one array to per-frame arrays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_VtaAbsToFrames( Vec_Int_t * vAbs ) +{ + Vec_Ptr_t * vFrames; + Vec_Int_t * vFrame; + int i, k, Entry, iStart, iStop = -1; + int nFrames = Vec_IntEntry( vAbs, 0 ); + assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) ); + vFrames = Vec_PtrAlloc( nFrames ); + for ( i = 0; i < nFrames; i++ ) + { + iStart = Vec_IntEntry( vAbs, i+1 ); + iStop = Vec_IntEntry( vAbs, i+2 ); + vFrame = Vec_IntAlloc( iStop - iStart ); + Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop ) + Vec_IntPush( vFrame, Entry ); + Vec_PtrPush( vFrames, vFrame ); + } + assert( iStop == Vec_IntSize(vAbs) ); + return vFrames; +} + +/**Function************************************************************* + + Synopsis [Converting from per-frame arrays to one integer array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_VtaFramesToAbs( Vec_Vec_t * vFrames ) +{ + Vec_Int_t * vOne, * vAbs; + int i, k, Entry, nSize; + vAbs = Vec_IntAlloc( 2 + Vec_VecSize(vFrames) + Vec_VecSizeSize(vFrames) ); + Vec_IntPush( vAbs, Vec_VecSize(vFrames) ); + nSize = Vec_VecSize(vFrames) + 2; + Vec_VecForEachLevelInt( vFrames, vOne, i ) + { + Vec_IntPush( vAbs, nSize ); + nSize += Vec_IntSize( vOne ); + } + Vec_IntPush( vAbs, nSize ); + assert( Vec_IntSize(vAbs) == Vec_VecSize(vFrames) + 2 ); + Vec_VecForEachLevelInt( vFrames, vOne, i ) + Vec_IntForEachEntry( vOne, Entry, k ) + Vec_IntPush( vAbs, Entry ); + assert( Vec_IntEntry(vAbs, Vec_IntEntry(vAbs,0)+1) == Vec_IntSize(vAbs) ); + return vAbs; +} + +/**Function************************************************************* + + Synopsis [Detects how many frames are completed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vta_ManDeriveAbsAll( Vec_Int_t * p, int nWords ) +{ + Vec_Int_t * vRes; + unsigned * pThis; + int i, w, nObjs = Vec_IntSize(p) / nWords; + assert( Vec_IntSize(p) % nWords == 0 ); + vRes = Vec_IntAlloc( nObjs ); + for ( i = 0; i < nObjs; i++ ) + { + pThis = (unsigned *)Vec_IntEntryP( p, nWords * i ); + for ( w = 0; w < nWords; w++ ) + if ( pThis[w] ) + break; + Vec_IntPush( vRes, (int)(w < nWords) ); + } + return vRes; +} + +/**Function************************************************************* + + Synopsis [Collect nodes/flops involved in different timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vec_IntDoubleWidth( Vec_Int_t * p, int nWords ) +{ + int * pArray = ABC_CALLOC( int, Vec_IntSize(p) * 2 ); + int i, w, nObjs = Vec_IntSize(p) / nWords; + assert( Vec_IntSize(p) % nWords == 0 ); + for ( i = 0; i < nObjs; i++ ) + for ( w = 0; w < nWords; w++ ) + pArray[2 * nWords * i + w] = p->pArray[nWords * i + w]; + ABC_FREE( p->pArray ); + p->pArray = pArray; + p->nSize *= 2; + p->nCap = p->nSize; + return 2 * nWords; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vga_ManHash( int iObj, int iFrame, int nBins ) +{ + return ((unsigned)((iObj + iFrame)*(iObj + iFrame + 1))) % nBins; +} +static inline int * Vga_ManLookup( Vta_Man_t * p, int iObj, int iFrame ) +{ + Vta_Obj_t * pThis; + int * pPlace = p->pBins + Vga_ManHash( iObj, iFrame, p->nBins ); + for ( pThis = Vta_ManObj(p, *pPlace); + pThis; pPlace = &pThis->iNext, + pThis = Vta_ManObj(p, *pPlace) ) + if ( pThis->iObj == iObj && pThis->iFrame == iFrame ) + break; + return pPlace; +} +static inline Vta_Obj_t * Vga_ManFind( Vta_Man_t * p, int iObj, int iFrame ) +{ + int * pPlace = Vga_ManLookup( p, iObj, iFrame ); + return Vta_ManObj(p, *pPlace); +} +static inline Vta_Obj_t * Vga_ManFindOrAdd( Vta_Man_t * p, int iObj, int iFrame ) +{ + Vta_Obj_t * pThis; + int i, * pPlace; + assert( iObj >= 0 && iFrame >= -1 ); + if ( p->nObjs == p->nObjsAlloc ) + { + // resize objects + p->pObjs = ABC_REALLOC( Vta_Obj_t, p->pObjs, 2 * p->nObjsAlloc ); + memset( p->pObjs + p->nObjsAlloc, 0, p->nObjsAlloc * sizeof(Vta_Obj_t) ); + p->nObjsAlloc *= 2; + // rehash entries in the table + ABC_FREE( p->pBins ); + p->nBins = Abc_PrimeCudd( 2 * p->nBins ); + p->pBins = ABC_CALLOC( int, p->nBins ); + Vta_ManForEachObj( p, pThis, i ) + { + pThis->iNext = 0; + pPlace = Vga_ManLookup( p, pThis->iObj, pThis->iFrame ); + assert( *pPlace == 0 ); + *pPlace = i; + } + } + pPlace = Vga_ManLookup( p, iObj, iFrame ); + if ( *pPlace ) + return Vta_ManObj(p, *pPlace); + *pPlace = p->nObjs++; + pThis = Vta_ManObj(p, *pPlace); + pThis->iObj = iObj; + pThis->iFrame = iFrame; + return pThis; +} +static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame ) +{ + int * pPlace = Vga_ManLookup( p, iObj, iFrame ); + Vta_Obj_t * pThis = Vta_ManObj(p, *pPlace); + assert( pThis != NULL ); + *pPlace = pThis->iNext; + pThis->iNext = -1; +} + + +/**Function************************************************************* + + Synopsis [Derives counter-example using current assignments.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Vga_ManDeriveCex( Vta_Man_t * p ) +{ + Abc_Cex_t * pCex; + Vta_Obj_t * pThis; + Gia_Obj_t * pObj; + int i; + pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); + pCex->iPo = 0; + pCex->iFrame = p->pPars->iFrame; + Vta_ManForEachObjObj( p, pThis, pObj, i ) + if ( Gia_ObjIsPi(p->pGia, pObj) && sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ) + Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) ); + return pCex; +} + +/**Function************************************************************* + + Synopsis [Remaps core into frame/node pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vta_ManUnsatCoreRemap( Vta_Man_t * p, Vec_Int_t * vCore ) +{ + Vta_Obj_t * pThis; + int i, Entry; + Vec_IntForEachEntry( vCore, Entry, i ) + { + pThis = Vta_ManObj( p, Entry ); + Entry = (pThis->iFrame << p->nObjBits) | pThis->iObj; + Vec_IntWriteEntry( vCore, i, Entry ); + } +} + +/**Function************************************************************* + + Synopsis [Compares two objects by their distance.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vta_ManComputeDepthIncrease( Vta_Obj_t ** pp1, Vta_Obj_t ** pp2 ) +{ + int Diff = (*pp1)->Prio - (*pp2)->Prio; + if ( Diff < 0 ) + return -1; + if ( Diff > 0 ) + return 1; + Diff = (*pp1) - (*pp2); + if ( Diff < 0 ) + return -1; + if ( Diff > 0 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the object is already used.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj ) +{ + int i; + unsigned * pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj ); + for ( i = 0; i < p->nWords; i++ ) + if ( pInfo[i] ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Finds predecessors of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vta_ObjPreds( Vta_Man_t * p, Vta_Obj_t * pThis, Gia_Obj_t * pObj, Vta_Obj_t ** ppThis0, Vta_Obj_t ** ppThis1 ) +{ + *ppThis0 = NULL; + *ppThis1 = NULL; +// if ( !pThis->fAdded ) +// return; + assert( !Gia_ObjIsPi(p->pGia, pObj) ); + if ( Gia_ObjIsConst0(pObj) || (Gia_ObjIsCi(pObj) && pThis->iFrame == 0) ) + return; + if ( Gia_ObjIsAnd(pObj) ) + { + *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); + *ppThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); +// assert( *ppThis0 && *ppThis1 ); + return; + } + assert( Gia_ObjIsRo(p->pGia, pObj) && pThis->iFrame > 0 ); + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); +// assert( *ppThis0 ); +} + +/**Function************************************************************* + + Synopsis [Collect const/PI/RO/AND in a topological order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vta_ManCollectNodes_rec( Vta_Man_t * p, Vta_Obj_t * pThis, Vec_Int_t * vOrder ) +{ + Gia_Obj_t * pObj; + Vta_Obj_t * pThis0, * pThis1; + if ( pThis->fVisit ) + return; + pThis->fVisit = 1; + pObj = Gia_ManObj( p->pGia, pThis->iObj ); + if ( pThis->fAdded ) + { + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + if ( pThis0 ) Vta_ManCollectNodes_rec( p, pThis0, vOrder ); + if ( pThis1 ) Vta_ManCollectNodes_rec( p, pThis1, vOrder ); + } + Vec_IntPush( vOrder, Vta_ObjId(p, pThis) ); +} +Vec_Int_t * Vta_ManCollectNodes( Vta_Man_t * p, int f ) +{ + Vta_Obj_t * pThis; + Gia_Obj_t * pObj; + Vec_IntClear( p->vOrder ); + pObj = Gia_ManPo( p->pGia, 0 ); + pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f ); + assert( pThis != NULL ); + assert( !pThis->fVisit ); + Vta_ManCollectNodes_rec( p, pThis, p->vOrder ); + assert( pThis->fVisit ); + return p->vOrder; +} + +/**Function************************************************************* + + Synopsis [Refines abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vta_ManSatVerify( Vta_Man_t * p ) +{ + Vta_Obj_t * pThis, * pThis0, * pThis1; + Gia_Obj_t * pObj; + int i; + Vta_ManForEachObj( p, pThis, i ) + pThis->Value = (sat_solver2_var_value(p->pSat, i) ? VTA_VAR1 : VTA_VAR0); + Vta_ManForEachObjObj( p, pThis, pObj, i ) + { + if ( !pThis->fAdded ) + continue; + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + if ( Gia_ObjIsAnd(pObj) ) + { + if ( pThis->Value == VTA_VAR1 ) + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); + else if ( pThis->Value == VTA_VAR0 ) + assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ); + else assert( 0 ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + if ( pThis->iFrame == 0 ) + assert( pThis->Value == VTA_VAR0 ); + else if ( pThis->Value == VTA_VAR0 ) + assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ); + else if ( pThis->Value == VTA_VAR1 ) + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ); + else assert( 0 ); + } + } +} + +/**Function************************************************************* + + Synopsis [Refines abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vta_ManProfileAddition( Vta_Man_t * p, Vec_Int_t * vTermsToAdd ) +{ + Vta_Obj_t * pThis; + Gia_Obj_t * pObj; + // profile the added ones + int i, * pCounters = ABC_CALLOC( int, p->pPars->iFrame+1 ); + Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i ) + pCounters[pThis->iFrame]++; + for ( i = 0; i <= p->pPars->iFrame; i++ ) + Abc_Print( 1, "%2d", pCounters[i] ); + Abc_Print( 1, "***\n" ); +} + +/**Function************************************************************* + + Synopsis [Refines abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p, int f ) +{ + int fVerify = 0; + Abc_Cex_t * pCex = NULL; + Vec_Int_t * vOrder, * vTermsToAdd; + Vec_Ptr_t * vTermsUsed, * vTermsUnused; + Vta_Obj_t * pThis, * pThis0, * pThis1, * pTop; + Gia_Obj_t * pObj; + int i, Counter; + + if ( fVerify ) + Vta_ManSatVerify( p ); + + // collect nodes in a topological order + vOrder = Vta_ManCollectNodes( p, f ); + Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) + { + pThis->Prio = VTA_LARGE; + pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0; + pThis->fVisit = 0; + } + + // verify + if ( fVerify ) + Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) + { + if ( !pThis->fAdded ) + continue; + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + if ( Gia_ObjIsAnd(pObj) ) + { + if ( pThis->Value == VTA_VAR1 ) + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); + else if ( pThis->Value == VTA_VAR0 ) + assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ); + else assert( 0 ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + if ( pThis->iFrame == 0 ) + assert( pThis->Value == VTA_VAR0 ); + else if ( pThis->Value == VTA_VAR0 ) + assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ); + else if ( pThis->Value == VTA_VAR1 ) + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ); + else assert( 0 ); + } + } + + // compute distance in reverse order + pThis = Vta_ManObj( p, Vec_IntEntryLast(vOrder) ); + pThis->Prio = 1; + // collect used and unused terms + vTermsUsed = Vec_PtrAlloc( 1015 ); + vTermsUnused = Vec_PtrAlloc( 1016 ); + Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) + { + // there is no unreachable states + assert( pThis->Prio < VTA_LARGE ); + // skip constants and PIs + if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) + { + pThis->Prio = 0; // set highest priority + continue; + } + // collect terminals + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); + if ( !pThis->fAdded ) + { + assert( pThis->Prio > 0 ); + if ( Vta_ManObjIsUsed(p, pThis->iObj) ) + Vec_PtrPush( vTermsUsed, pThis ); + else + Vec_PtrPush( vTermsUnused, pThis ); + continue; + } + // propagate + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + if ( pThis0 ) + pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 ); + if ( pThis1 ) + pThis1->Prio = Abc_MinInt( pThis1->Prio, pThis->Prio + 1 ); + } + +/* + Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) + if ( pThis->Prio > 0 ) + pThis->Prio = 10; +*/ +/* + // update priorities according to reconvergence counters + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) + { + Vta_Obj_t * pThis0, * pThis1; + Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj ); + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + pThis->Prio += 10000000; + if ( pThis0 ) + pThis->Prio -= 1000000 * pThis0->fAdded; + if ( pThis1 ) + pThis->Prio -= 1000000 * pThis1->fAdded; + } + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) + { + Vta_Obj_t * pThis0, * pThis1; + Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj ); + Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 ); + pThis->Prio += 10000000; + if ( pThis0 ) + pThis->Prio -= 1000000 * pThis0->fAdded; + if ( pThis1 ) + pThis->Prio -= 1000000 * pThis1->fAdded; + } +*/ + + + // update priorities according to reconvergence counters + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) + pThis->Prio = pThis->iObj; + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) + pThis->Prio = pThis->iObj; + + + // objects with equal distance should receive priority based on number + // those objects whose prototypes have been added in other timeframes + // should have higher priority than the current object + Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease ); + Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease ); + if ( Vec_PtrSize(vTermsUsed) > 1 ) + { + pThis0 = (Vta_Obj_t *)Vec_PtrEntry(vTermsUsed, 0); + pThis1 = (Vta_Obj_t *)Vec_PtrEntryLast(vTermsUsed); + assert( pThis0->Prio <= pThis1->Prio ); + } + // assign the priority based on these orders + Counter = 1; + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) + pThis->Prio = Counter++; + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) + pThis->Prio = Counter++; +// Abc_Print( 1, "Used %d Unused %d\n", Vec_PtrSize(vTermsUsed), Vec_PtrSize(vTermsUnused) ); + + + // propagate in the direct order + Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) + { + assert( pThis->fVisit == 0 ); + assert( pThis->Prio < VTA_LARGE ); + // skip terminal objects + if ( !pThis->fAdded ) + continue; + // assumes that values are assigned!!! + assert( pThis->Value != 0 ); + // propagate + if ( Gia_ObjIsAnd(pObj) ) + { + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); + pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); + assert( pThis0 && pThis1 ); + if ( pThis->Value == VTA_VAR1 ) + { + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); + pThis->Prio = Abc_MaxInt( pThis0->Prio, pThis1->Prio ); + } + else if ( pThis->Value == VTA_VAR0 ) + { + if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) + pThis->Prio = Abc_MinInt( pThis0->Prio, pThis1->Prio ); // choice!!! + else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) + pThis->Prio = pThis0->Prio; + else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) + pThis->Prio = pThis1->Prio; + else assert( 0 ); + } + else assert( 0 ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( pThis->iFrame > 0 ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); + assert( pThis0 ); + pThis->Prio = pThis0->Prio; + } + else + pThis->Prio = 0; + } + else if ( Gia_ObjIsConst0(pObj) ) + pThis->Prio = 0; + else + assert( 0 ); + } + + // select important values + pTop = Vta_ManObj( p, Vec_IntEntryLast(vOrder) ); + pTop->fVisit = 1; + vTermsToAdd = Vec_IntAlloc( 100 ); + Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i ) + { + if ( !pThis->fVisit ) + continue; + pThis->fVisit = 0; + assert( pThis->Prio >= 0 && pThis->Prio <= pTop->Prio ); + // skip terminal objects + if ( !pThis->fAdded ) + { + assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ); + Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) ); + continue; + } + // assumes that values are assigned!!! + assert( pThis->Value != 0 ); + // propagate + if ( Gia_ObjIsAnd(pObj) ) + { + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); + pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); + assert( pThis0 && pThis1 ); + if ( pThis->Value == VTA_VAR1 ) + { + assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); + assert( pThis0->Prio <= pThis->Prio ); + assert( pThis1->Prio <= pThis->Prio ); + pThis0->fVisit = 1; + pThis1->fVisit = 1; + } + else if ( pThis->Value == VTA_VAR0 ) + { + if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) + { + if ( pThis0->fVisit ) + { + } + else if ( pThis1->fVisit ) + { + } + else if ( pThis0->Prio <= pThis1->Prio ) // choice!!! + { + pThis0->fVisit = 1; + assert( pThis0->Prio == pThis->Prio ); + } + else + { + pThis1->fVisit = 1; + assert( pThis1->Prio == pThis->Prio ); + } + } + else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) + { + pThis0->fVisit = 1; + assert( pThis0->Prio == pThis->Prio ); + } + else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) + { + pThis1->fVisit = 1; + assert( pThis1->Prio == pThis->Prio ); + } + else assert( 0 ); + } + else assert( 0 ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( pThis->iFrame > 0 ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); + assert( pThis0 ); + pThis0->fVisit = 1; + assert( pThis0->Prio == pThis->Prio ); + } + } + else if ( !Gia_ObjIsConst0(pObj) ) + assert( 0 ); + } + + if ( p->pPars->fAddLayer ) + { + // mark those currently included + Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) + { + assert( pThis->fVisit == 0 ); + pThis->fVisit = 1; + } + // add used terms, which have close relationship + Counter = Vec_IntSize(vTermsToAdd); + Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) + { + if ( pThis->fVisit ) + continue; + // Vta_ObjPreds( p, pThis, Gia_ManObj(p->pGia, pThis->iObj), &pThis0, &pThis1 ); + // if ( (pThis0 && (pThis0->fAdded || pThis0->fVisit)) || (pThis1 && (pThis1->fAdded || pThis1->fVisit)) ) + Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) ); + } + // remove those currenty included + Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) + pThis->fVisit = 0; + } +// printf( "\n%d -> %d\n", Counter, Vec_IntSize(vTermsToAdd) ); +//Vec_IntReverseOrder( vTermsToAdd ); +//Vec_IntSort( vTermsToAdd, 1 ); + + + // cleanup + Vec_PtrFree( vTermsUsed ); + Vec_PtrFree( vTermsUnused ); + + + if ( fVerify ) + { + // verify + Vta_ManForEachObjVec( vOrder, p, pThis, i ) + pThis->Value = VTA_VARX; + Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i ) + { + assert( !pThis->fAdded ); + pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0; + } + // simulate + Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i ) + { + assert( pThis->fVisit == 0 ); + if ( !pThis->fAdded ) + continue; + if ( Gia_ObjIsAnd(pObj) ) + { + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); + pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame ); + assert( pThis0 && pThis1 ); + if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ) + pThis->Value = VTA_VAR1; + else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) + pThis->Value = VTA_VAR0; + else + pThis->Value = VTA_VARX; + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( pThis->iFrame > 0 ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); + assert( pThis0 ); + if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) + pThis->Value = VTA_VAR0; + else if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) ) + pThis->Value = VTA_VAR1; + else + pThis->Value = VTA_VARX; + } + else + { + pThis->Value = VTA_VAR0; + } + } + else if ( Gia_ObjIsConst0(pObj) ) + { + pThis->Value = VTA_VAR0; + } + else assert( 0 ); + // double check the solver + assert( pThis->Value == VTA_VARX || (int)pThis->Value == (sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0) ); + } + + // check the output + if ( !Vta_ValIs1(pTop, Gia_ObjFaninC0(Gia_ManPo(p->pGia, 0))) ) + Abc_Print( 1, "Vta_ManRefineAbstraction(): Terminary simulation verification failed!\n" ); +// else +// Abc_Print( 1, "Verification OK.\n" ); + } + + + // produce true counter-example + if ( pTop->Prio == 0 ) + pCex = Vga_ManDeriveCex( p ); + else + { +// Vta_ManProfileAddition( p, vTermsToAdd ); + + Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i ) + if ( !Gia_ObjIsPi(p->pGia, pObj) ) + Vga_ManAddClausesOne( p, pThis->iObj, pThis->iFrame ); + sat_solver2_simplify( p->pSat ); + } + p->nObjAdded += Vec_IntSize(vTermsToAdd); + Vec_IntFree( vTermsToAdd ); + return pCex; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vta_Man_t * Vga_ManStart( Gia_Man_t * pGia, Abs_Par_t * pPars ) +{ + Vta_Man_t * p; + p = ABC_CALLOC( Vta_Man_t, 1 ); + p->pGia = pGia; + p->pPars = pPars; + // internal data + p->nObjsAlloc = (1 << 18); + p->pObjs = ABC_CALLOC( Vta_Obj_t, p->nObjsAlloc ); + p->nObjs = 1; + p->nBins = Abc_PrimeCudd( 2*p->nObjsAlloc ); + p->pBins = ABC_CALLOC( int, p->nBins ); + p->vOrder = Vec_IntAlloc( 1013 ); + // abstraction + p->nObjBits = Abc_Base2Log( Gia_ManObjNum(pGia) ); + p->nObjMask = (1 << p->nObjBits) - 1; + assert( Gia_ManObjNum(pGia) <= (int)p->nObjMask ); + p->nWords = 1; + p->vSeens = Vec_IntStart( Gia_ManObjNum(pGia) * p->nWords ); + p->vSeenGla = Vec_BitStart( Gia_ManObjNum(pGia) ); + p->nSeenGla = 1; + p->nSeenAll = 1; + // other data + p->vCores = Vec_PtrAlloc( 100 ); + p->pSat = sat_solver2_new(); + p->pSat->pPrf1 = Vec_SetAlloc( 20 ); +// p->pSat->fVerbose = p->pPars->fVerbose; +// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax ); + p->pSat->nLearntStart = p->pPars->nLearnedStart; + p->pSat->nLearntDelta = p->pPars->nLearnedDelta; + p->pSat->nLearntRatio = p->pPars->nLearnedPerce; + p->pSat->nLearntMax = p->pSat->nLearntStart; + // start the abstraction + assert( pGia->vObjClasses != NULL ); + p->vFrames = Gia_VtaAbsToFrames( pGia->vObjClasses ); + p->vAddedNew = Vec_IntAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Delete manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vga_ManStop( Vta_Man_t * p ) +{ + if ( p->pPars->fVerbose ) + Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n", + sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat), + sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded ); + Vec_VecFreeP( (Vec_Vec_t **)&p->vCores ); + Vec_VecFreeP( (Vec_Vec_t **)&p->vFrames ); + Vec_BitFreeP( &p->vSeenGla ); + Vec_IntFreeP( &p->vSeens ); + Vec_IntFreeP( &p->vOrder ); + Vec_IntFreeP( &p->vAddedNew ); + sat_solver2_delete( p->pSat ); + ABC_FREE( p->pBins ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns the output literal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f ) +{ + Gia_Obj_t * pObj = Gia_ManPo(p->pGia, 0); + Vta_Obj_t * pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f ); + assert( pThis != NULL && pThis->fAdded ); + if ( f == 0 && Gia_ObjIsRo(p->pGia, Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) ) + return -Vta_ObjId(p, pThis); + return Abc_Var2Lit( Vta_ObjId(p, pThis), Gia_ObjFaninC0(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Finds the set of clauses involved in the UNSAT core.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Vta_ManUnsatCore( int iLit, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls ) +{ + clock_t clk = clock(); + Vec_Int_t * vCore; + int RetValue, nConfPrev = pSat->stats.conflicts; + if ( piRetValue ) + *piRetValue = 1; + // consider special case when PO points to the flop + // this leads to immediate conflict in the first timeframe + if ( iLit < 0 ) + { + vCore = Vec_IntAlloc( 1 ); + Vec_IntPush( vCore, -iLit ); + return vCore; + } + // solve the problem + RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( pnConfls ) + *pnConfls = (int)pSat->stats.conflicts - nConfPrev; + if ( RetValue == l_Undef ) + { + if ( piRetValue ) + *piRetValue = -1; + return NULL; + } + if ( RetValue == l_True ) + { + if ( piRetValue ) + *piRetValue = 0; + return NULL; + } + if ( fVerbose ) + { +// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev ); +// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts ); +// Abc_PrintTime( 1, "Time", clock() - clk ); + } + assert( RetValue == l_False ); + // derive the UNSAT core + clk = clock(); + vCore = (Vec_Int_t *)Sat_ProofCore( pSat ); + if ( fVerbose ) + { +// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) ); +// Abc_PrintTime( 1, "Time", clock() - clk ); + } + return vCore; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames, int nConfls, int nCexes, clock_t Time, int fVerbose ) +{ + unsigned * pInfo; + int * pCountAll = NULL, * pCountUni = NULL; + int i, iFrame, iObj, Entry, fChanges = 0; + // print info about frames + if ( vCore ) + { + pCountAll = ABC_CALLOC( int, nFrames + 1 ); + pCountUni = ABC_CALLOC( int, nFrames + 1 ); + Vec_IntForEachEntry( vCore, Entry, i ) + { + iObj = (Entry & p->nObjMask); + iFrame = (Entry >> p->nObjBits); + assert( iFrame < nFrames ); + pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj ); + if ( !Abc_InfoHasBit(pInfo, iFrame) ) + { + Abc_InfoSetBit( pInfo, iFrame ); + pCountUni[iFrame+1]++; + pCountUni[0]++; + p->nSeenAll++; + } + pCountAll[iFrame+1]++; + pCountAll[0]++; + if ( !Vec_BitEntry(p->vSeenGla, iObj) ) + { + Vec_BitWriteEntry(p->vSeenGla, iObj, 1); + p->nSeenGla++; + fChanges = 1; + } + } + } + if ( !fVerbose ) + { + ABC_FREE( pCountAll ); + ABC_FREE( pCountUni ); + return fChanges; + } + + if ( Abc_FrameIsBatchMode() && !vCore ) + return fChanges; + +// Abc_Print( 1, "%5d%5d", pCountAll[0], pCountUni[0] ); + Abc_Print( 1, "%4d :", nFrames-1 ); + Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenGla / (Gia_ManRegNum(p->pGia) + Gia_ManAndNum(p->pGia) + 1)) ); + Abc_Print( 1, "%6d", p->nSeenGla ); + Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenAll / (p->nSeenGla * nFrames)) ); + Abc_Print( 1, "%8d", nConfls ); + if ( nCexes == 0 ) + Abc_Print( 1, "%5c", '-' ); + else + Abc_Print( 1, "%5d", nCexes ); +// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) ); + Abc_PrintInt( sat_solver2_nvars(p->pSat) ); + Abc_PrintInt( sat_solver2_nclauses(p->pSat) ); + Abc_PrintInt( sat_solver2_nlearnts(p->pSat) ); + if ( vCore == NULL ) + { + Abc_Print( 1, " ..." ); +// for ( k = 0; k < 7; k++ ) +// Abc_Print( 1, " " ); + Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); + Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) ); + Abc_Print( 1, "\r" ); + } + else + { + Abc_PrintInt( pCountAll[0] ); +/* + if ( nFrames > 7 ) + { + for ( k = 0; k < 3; k++ ) + Abc_Print( 1, "%5d", pCountAll[k+1] ); + Abc_Print( 1, " ..." ); + for ( k = nFrames-3; k < nFrames; k++ ) + Abc_Print( 1, "%5d", pCountAll[k+1] ); + } + else + { + for ( k = 0; k < nFrames; k++ ) + Abc_Print( 1, "%5d", pCountAll[k+1] ); + for ( k = nFrames; k < 7; k++ ) + Abc_Print( 1, " " ); + } +*/ + Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC ); + Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) ); + Abc_Print( 1, "\n" ); + } + fflush( stdout ); + + if ( vCore ) + { + ABC_FREE( pCountAll ); + ABC_FREE( pCountUni ); + } + return fChanges; +} + +/**Function************************************************************* + + Synopsis [Adds clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame ) +{ + Vta_Obj_t * pThis0, * pThis1; + Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj ); + Vta_Obj_t * pThis = Vga_ManFindOrAdd( p, iObj, iFrame ); + int iThis0, iMainVar = Vta_ObjId(p, pThis); + assert( pThis->iObj == iObj && pThis->iFrame == iFrame ); + if ( pThis->fAdded ) + return; + pThis->fAdded = 1; + Vec_IntPush( p->vAddedNew, iMainVar ); + if ( Gia_ObjIsAnd(pObj) ) + { + pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame ); + iThis0 = Vta_ObjId(p, pThis0); + pThis1 = Vga_ManFindOrAdd( p, Gia_ObjFaninId1p(p->pGia, pObj), iFrame ); + sat_solver2_add_and( p->pSat, iMainVar, iThis0, Vta_ObjId(p, pThis1), + Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0, iMainVar ); + } + else if ( Gia_ObjIsRo(p->pGia, pObj) ) + { + if ( iFrame == 0 ) + { + if ( p->pPars->fUseTermVars ) + { + pThis0 = Vga_ManFindOrAdd( p, iObj, -1 ); + sat_solver2_add_constraint( p->pSat, iMainVar, Vta_ObjId(p, pThis0), 1, 0, iMainVar ); + } + else + { + sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar ); + } + } + else + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame-1 ); + sat_solver2_add_buffer( p->pSat, iMainVar, Vta_ObjId(p, pThis0), Gia_ObjFaninC0(pObj), 0, iMainVar ); + } + } + else if ( Gia_ObjIsConst0(pObj) ) + { + sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar ); + } + else //if ( !Gia_ObjIsPi(p->pGia, pObj) ) + assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vga_ManLoadSlice( Vta_Man_t * p, Vec_Int_t * vOne, int Lift ) +{ + int i, Entry; + Vec_IntForEachEntry( vOne, Entry, i ) + Vga_ManAddClausesOne( p, Entry & p->nObjMask, (Entry >> p->nObjBits) + Lift ); + sat_solver2_simplify( p->pSat ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vga_ManPrintCore( Vta_Man_t * p, Vec_Int_t * vCore, int Lift ) +{ + int i, Entry, iObj, iFrame; + Vec_IntForEachEntry( vCore, Entry, i ) + { + iObj = (Entry & p->nObjMask); + iFrame = (Entry >> p->nObjBits); + Abc_Print( 1, "%d*%d ", iObj, iFrame+Lift ); + } + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vga_ManRollBack( Vta_Man_t * p, int nObjOld ) +{ + Vta_Obj_t * pThis = p->pObjs + nObjOld; + Vta_Obj_t * pLimit = p->pObjs + p->nObjs; + int i, Entry; + for ( ; pThis < pLimit; pThis++ ) + Vga_ManDelete( p, pThis->iObj, pThis->iFrame ); + memset( p->pObjs + nObjOld, 0, sizeof(Vta_Obj_t) * (p->nObjs - nObjOld) ); + p->nObjs = nObjOld; + Vec_IntForEachEntry( p->vAddedNew, Entry, i ) + if ( Entry < p->nObjs ) + { + pThis = Vta_ManObj(p, Entry); + assert( pThis->fAdded == 1 ); + pThis->fAdded = 0; + } +} + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_VtaSendAbsracted( Vta_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p ); + Gia_Man_t * pAbs; + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Sending abstracted model...\n" ); + // create obj classes + Vec_IntFreeP( &p->pGia->vObjClasses ); + p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); + // create gate classes + Vec_IntFreeP( &p->pGia->vGateClasses ); + p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses ); + Vec_IntFreeP( &p->pGia->vObjClasses ); + // create abstrated model + pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses ); + Vec_IntFreeP( &p->pGia->vGateClasses ); + // send it out + Gia_ManToBridgeAbsNetlist( stdout, pAbs ); + Gia_ManStop( pAbs ); +} +void Gia_VtaSendCancel( Vta_Man_t * p, int fVerbose ) +{ + extern int Gia_ManToBridgeBadAbs( FILE * pFile ); + assert( Abc_FrameIsBridgeMode() ); +// if ( fVerbose ) +// Abc_Print( 1, "Cancelling previously sent model...\n" ); + Gia_ManToBridgeBadAbs( stdout ); +} + +/**Function************************************************************* + + Synopsis [Send abstracted model or send cancel.] + + Description [Counter-example will be sent automatically when &vta terminates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_VtaDumpAbsracted( Vta_Man_t * p, int fVerbose ) +{ + char * pFileNameDef = "vabs.aig"; + char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef; + Gia_Man_t * pAbs; + if ( fVerbose ) + Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName ); + // create obj classes + Vec_IntFreeP( &p->pGia->vObjClasses ); + p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); + // create gate classes + Vec_IntFreeP( &p->pGia->vGateClasses ); + p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses ); + Vec_IntFreeP( &p->pGia->vObjClasses ); + // create abstrated model + pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses ); + Vec_IntFreeP( &p->pGia->vGateClasses ); + // send it out + Gia_WriteAiger( pAbs, pFileName, 0, 0 ); + Gia_ManStop( pAbs ); +} + + +/**Function************************************************************* + + Synopsis [Print memory report.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_VtaPrintMemory( Vta_Man_t * p ) +{ + double memTot = 0; + double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t); + double memSat = sat_solver2_memory( p->pSat, 1 ); + double memPro = sat_solver2_memory_proof( p->pSat ); + double memMap = p->nObjsAlloc * sizeof(Vta_Obj_t) + p->nBins * sizeof(int); + double memOth = sizeof(Vta_Man_t); + memOth += Vec_IntCap(p->vOrder) * sizeof(int); + memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vFrames ); + memOth += Vec_BitCap(p->vSeenGla) * sizeof(int); + memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCores ); + memOth += Vec_IntCap(p->vAddedNew) * sizeof(int); + memTot = memAig + memSat + memPro + memMap + memOth; + ABC_PRMP( "Memory: AIG ", memAig, memTot ); + ABC_PRMP( "Memory: SAT ", memSat, memTot ); + ABC_PRMP( "Memory: Proof ", memPro, memTot ); + ABC_PRMP( "Memory: Map ", memMap, memTot ); + ABC_PRMP( "Memory: Other ", memOth, memTot ); + ABC_PRMP( "Memory: TOTAL ", memTot, memTot ); +} + + +/**Function************************************************************* + + Synopsis [Collect nodes/flops involved in different timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_VtaPerformInt( Gia_Man_t * pAig, Abs_Par_t * pPars ) +{ + Vta_Man_t * p; + Vec_Int_t * vCore; + Abc_Cex_t * pCex = NULL; + int i, f, nConfls, Status, nObjOld, RetValue = -1, nCountNoChange = 0, fOneIsSent = 0; + clock_t clk = clock(), clk2; + // preconditions + assert( Gia_ManPoNum(pAig) == 1 ); + assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) ) + { + if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) ) + { + printf( "Sequential miter is trivially UNSAT.\n" ); + return 1; + } + ABC_FREE( pAig->pCexSeq ); + pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 ); + printf( "Sequential miter is trivially SAT.\n" ); + return 0; + } + + // compute intial abstraction + if ( pAig->vObjClasses == NULL ) + { + pAig->vObjClasses = Vec_IntAlloc( 5 ); + Vec_IntPush( pAig->vObjClasses, 1 ); + Vec_IntPush( pAig->vObjClasses, 3 ); + Vec_IntPush( pAig->vObjClasses, 4 ); + Vec_IntPush( pAig->vObjClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)) ); + } + // start the manager + p = Vga_ManStart( pAig, pPars ); + // set runtime limit + if ( p->pPars->nTimeOut ) + sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() ); + // perform initial abstraction + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "Running variable-timeframe abstraction (VTA) with the following parameters:\n" ); + Abc_Print( 1, "FramePast = %d FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%\n", + pPars->nFramesPast, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin ); + Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n", + pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce ); +// Abc_Print( 1, "Frame %% Abs %% Confl Cex SatVar Core F0 F1 F2 ...\n" ); + Abc_Print( 1, " Frame %% Abs %% Confl Cex Vars Clas Lrns Core Time Mem\n" ); + } + assert( Vec_PtrSize(p->vFrames) > 0 ); + for ( f = i = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++ ) + { + int nConflsBeg = sat_solver2_nconflicts(p->pSat); + p->pPars->iFrame = f; + // realloc storage for abstraction marks + if ( f == p->nWords * 32 ) + p->nWords = Vec_IntDoubleWidth( p->vSeens, p->nWords ); + + // create bookmark to be used for rollback + nObjOld = p->nObjs; + sat_solver2_bookmark( p->pSat ); + Vec_IntClear( p->vAddedNew ); + + // load new timeframe + Vga_ManAddClausesOne( p, 0, f ); + if ( f < Vec_PtrSize(p->vFrames) ) + Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vFrames, f), 0 ); + else + { + for ( i = 1; i <= Abc_MinInt(p->pPars->nFramesPast, f); i++ ) + Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vCores, f-i), i ); + } + + // iterate as long as there are counter-examples + for ( i = 0; ; i++ ) + { + clk2 = clock(); + vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls ); + assert( (vCore != NULL) == (Status == 1) ); + if ( Status == -1 ) // resource limit is reached + { + Vga_ManRollBack( p, nObjOld ); + goto finish; + } + // check timeout + if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit ) + { + Vga_ManRollBack( p, nObjOld ); + goto finish; + } + if ( vCore != NULL ) + { + p->timeUnsat += clock() - clk2; + break; + } + p->timeSat += clock() - clk2; + assert( Status == 0 ); + p->nCexes++; + // perform the refinement + clk2 = clock(); + pCex = Vta_ManRefineAbstraction( p, f ); + p->timeCex += clock() - clk2; + if ( pCex != NULL ) + goto finish; + // print the result (do not count it towards change) + Vta_ManAbsPrintFrame( p, NULL, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose ); + } + assert( Status == 1 ); + // valid core is obtained + Vta_ManUnsatCoreRemap( p, vCore ); + Vec_IntSort( vCore, 1 ); + // update the SAT solver + sat_solver2_rollback( p->pSat ); + // update storage + Vga_ManRollBack( p, nObjOld ); + // load this timeframe + Vga_ManLoadSlice( p, vCore, 0 ); + Vec_IntFree( vCore ); + + // run SAT solver + clk2 = clock(); + vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls ); + p->timeUnsat += clock() - clk2; + assert( (vCore != NULL) == (Status == 1) ); + if ( Status == -1 ) // resource limit is reached + break; + if ( Status == 0 ) + { + Vta_ManSatVerify( p ); + // make sure, there was no initial abstraction (otherwise, it was invalid) + assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart ); + pCex = Vga_ManDeriveCex( p ); + break; + } + // add the core + Vta_ManUnsatCoreRemap( p, vCore ); + // add in direct topological order + Vec_IntSort( vCore, 1 ); + Vec_PtrPush( p->vCores, vCore ); + // print the result + if ( Vta_ManAbsPrintFrame( p, vCore, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose ) ) + { + // reset the counter of frames without change + nCountNoChange = 1; + p->pPars->nFramesNoChange = 0; + } + else if ( ++nCountNoChange == 2 ) // time to send + { + p->pPars->nFramesNoChange++; + if ( Abc_FrameIsBridgeMode() ) + { + // cancel old one if it was sent + if ( fOneIsSent ) + Gia_VtaSendCancel( p, pPars->fVerbose ); + // send new one + Gia_VtaSendAbsracted( p, pPars->fVerbose ); + fOneIsSent = 1; + } + } + // dump the model + if ( p->pPars->fDumpVabs && (f & 1) ) + { + char Command[1000]; + Abc_FrameSetStatus( -1 ); + Abc_FrameSetCex( NULL ); + Abc_FrameSetNFrames( f+1 ); + sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "vtabs.aig"), ".status") ); + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); + Gia_VtaDumpAbsracted( p, pPars->fVerbose ); + } + // check if the number of objects is below limit + if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 ) + { + Status = -1; + break; + } + } +finish: + // analize the results + if ( pCex == NULL ) + { + if ( p->pPars->fVerbose && Status == -1 ) + printf( "\n" ); + if ( Vec_PtrSize(p->vCores) == 0 ) + Abc_Print( 1, "Abstraction is not produced because first frame is not solved. " ); + else + { + assert( Vec_PtrSize(p->vCores) > 0 ); +// if ( pAig->vObjClasses != NULL ) +// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" ); + Vec_IntFreeP( &pAig->vObjClasses ); + pAig->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores ); + if ( Status == -1 ) + { + if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit ) + Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange ); + else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit ) + Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange ); + else if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 ) + Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f ); + else + Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f ); + } + else + { + p->pPars->iFrame++; + Abc_Print( 1, "VTA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange ); + } + } + } + else + { + if ( p->pPars->fVerbose ) + printf( "\n" ); + ABC_FREE( p->pGia->pCexSeq ); + p->pGia->pCexSeq = pCex; + if ( !Gia_ManVerifyCex( p->pGia, pCex, 0 ) ) + Abc_Print( 1, " Gia_VtaPerform(): CEX verification has failed!\n" ); + Abc_Print( 1, "Counter-example detected in frame %d. ", f ); + p->pPars->iFrame = pCex->iFrame - 1; + Vec_IntFreeP( &pAig->vObjClasses ); + RetValue = 0; + } + Abc_PrintTime( 1, "Time", clock() - clk ); + + if ( p->pPars->fVerbose ) + { + p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex; + ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk ); + ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk ); + ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk ); + ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk ); + ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk ); + Gia_VtaPrintMemory( p ); + } + + Vga_ManStop( p ); + fflush( stdout ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Collect nodes/flops involved in different timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_VtaPerform( Gia_Man_t * pAig, Abs_Par_t * pPars ) +{ + int RetValue = -1; + if ( pAig->vObjClasses == NULL && pPars->fUseRollback ) + { + int nFramesMaxOld = pPars->nFramesMax; + pPars->nFramesMax = pPars->nFramesStart; + RetValue = Gia_VtaPerformInt( pAig, pPars ); + pPars->nFramesMax = nFramesMaxOld; + } + if ( RetValue == 0 ) + return RetValue; + return Gia_VtaPerformInt( pAig, pPars ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/abs/module.make b/src/proof/abs/module.make new file mode 100644 index 00000000..4e652afd --- /dev/null +++ b/src/proof/abs/module.make @@ -0,0 +1,15 @@ +SRC += src/proof/abs/abs.c \ + src/proof/abs/absDup.c \ + src/proof/abs/absGla.c \ + src/proof/abs/absGlaOld.c \ + src/proof/abs/absIter.c \ + src/proof/abs/absOldCex.c \ + src/proof/abs/absOldRef.c \ + src/proof/abs/absOldSat.c \ + src/proof/abs/absOldSim.c \ + src/proof/abs/absOut.c \ + src/proof/abs/absPth.c \ + src/proof/abs/absRef.c \ + src/proof/abs/absRef2.c \ + src/proof/abs/absVta.c \ + src/proof/abs/absUtil.c -- cgit v1.2.3