From 6130e39b18b5f53902e4eab14f6d5cdde5219563 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 1 Nov 2010 01:35:04 -0700 Subject: initial commit of public abc --- src/aig/saig/module.make | 5 + src/aig/saig/saig.h | 111 ++-- src/aig/saig/saigAbs.c | 910 ++++++-------------------------- src/aig/saig/saigAbs2.c | 237 +++++++++ src/aig/saig/saigBmc.c | 917 ++++++++------------------------- src/aig/saig/saigBmc2.c | 937 +++++++++++++++++++++++++-------- src/aig/saig/saigBmc3.c | 1227 ++++++++++++++++++++++++++++++++++++++++++++ src/aig/saig/saigCone.c | 9 +- src/aig/saig/saigConstr.c | 384 ++++++++++++++ src/aig/saig/saigConstr2.c | 1001 ++++++++++++++++++++++++++++++++++++ src/aig/saig/saigDup.c | 24 +- src/aig/saig/saigHaig.c | 17 +- src/aig/saig/saigInd.c | 212 +++++++- src/aig/saig/saigIoa.c | 8 +- src/aig/saig/saigMiter.c | 40 +- src/aig/saig/saigPba.c | 752 +++++++++++++++++++++++++++ src/aig/saig/saigPhase.c | 56 +- src/aig/saig/saigRetFwd.c | 5 + src/aig/saig/saigRetMin.c | 38 +- src/aig/saig/saigRetStep.c | 5 + src/aig/saig/saigScl.c | 5 + src/aig/saig/saigSimExt.c | 249 ++++++++- src/aig/saig/saigSimFast.c | 10 +- src/aig/saig/saigSimMv.c | 45 +- src/aig/saig/saigSimSeq.c | 17 +- src/aig/saig/saigStrSim.c | 49 +- src/aig/saig/saigSwitch.c | 8 +- src/aig/saig/saigSynch.c | 39 +- src/aig/saig/saigTrans.c | 44 +- src/aig/saig/saigWnd.c | 51 +- src/aig/saig/saig_.c | 5 + 31 files changed, 5527 insertions(+), 1890 deletions(-) create mode 100644 src/aig/saig/saigAbs2.c create mode 100644 src/aig/saig/saigBmc3.c create mode 100644 src/aig/saig/saigConstr.c create mode 100644 src/aig/saig/saigConstr2.c create mode 100644 src/aig/saig/saigPba.c (limited to 'src/aig/saig') diff --git a/src/aig/saig/module.make b/src/aig/saig/module.make index e583bcfe..88935121 100644 --- a/src/aig/saig/module.make +++ b/src/aig/saig/module.make @@ -1,12 +1,17 @@ SRC += src/aig/saig/saigAbs.c \ + src/aig/saig/saigAbs2.c \ src/aig/saig/saigBmc.c \ src/aig/saig/saigBmc2.c \ + src/aig/saig/saigBmc3.c \ src/aig/saig/saigCone.c \ + src/aig/saig/saigConstr.c \ + src/aig/saig/saigConstr2.c \ src/aig/saig/saigDup.c \ src/aig/saig/saigHaig.c \ src/aig/saig/saigInd.c \ src/aig/saig/saigIoa.c \ src/aig/saig/saigMiter.c \ + src/aig/saig/saigPba.c \ src/aig/saig/saigPhase.c \ src/aig/saig/saigRetFwd.c \ src/aig/saig/saigRetMin.c \ diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index f72a3074..fc85d52a 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -21,6 +21,7 @@ #ifndef __SAIG_H__ #define __SAIG_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -32,9 +33,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -43,26 +45,57 @@ extern "C" { typedef struct Sec_MtrStatus_t_ Sec_MtrStatus_t; struct Sec_MtrStatus_t_ { - int nInputs; // the total number of inputs - int nNodes; // the total number of nodes - int nOutputs; // the total number of outputs - int nUnsat; // the number of UNSAT outputs - int nSat; // the number of SAT outputs - int nUndec; // the number of undecided outputs - int iOut; // the satisfied output + int nInputs; // the total number of inputs + int nNodes; // the total number of nodes + int nOutputs; // the total number of outputs + int nUnsat; // the number of UNSAT outputs + int nSat; // the number of SAT outputs + int nUndec; // the number of undecided outputs + int iOut; // the satisfied output +}; + +typedef struct Saig_ParBmc_t_ Saig_ParBmc_t; +struct Saig_ParBmc_t_ +{ + int nStart; // starting timeframe + int nFramesMax; // maximum number of timeframes + int nConfLimit; // maximum number of conflicts at a node + int nTimeOut; // approximate timeout in seconds + int fSolveAll; // does not stop at the first SAT output + int fDropSatOuts; // replace sat outputs by constant 0 + int fVerbose; // verbose + int iFrame; // explored up to this frame + int nFailOuts; // the number of failed outputs +}; + +typedef struct Saig_ParBbr_t_ Saig_ParBbr_t; +struct Saig_ParBbr_t_ +{ + int TimeLimit; + int nBddMax; + int nIterMax; + int fPartition; + int fReorder; + int fReorderImage; + int fVerbose; + int fSilent; + int fSkipOutCheck;// skip output checking + int iFrame; // explored up to this frame }; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Saig_ManPiNum( Aig_Man_t * p ) { return p->nTruePis; } -static inline int Saig_ManPoNum( Aig_Man_t * p ) { return p->nTruePos; } -static inline int Saig_ManCiNum( Aig_Man_t * p ) { return p->nTruePis + p->nRegs; } -static inline int Saig_ManCoNum( Aig_Man_t * p ) { return p->nTruePos + p->nRegs; } -static inline int Saig_ManRegNum( Aig_Man_t * p ) { return p->nRegs; } -static inline Aig_Obj_t * Saig_ManLo( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, Saig_ManPiNum(p)+i); } -static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPos, Saig_ManPoNum(p)+i); } +static inline int Saig_ManPiNum( Aig_Man_t * p ) { return p->nTruePis; } +static inline int Saig_ManPoNum( Aig_Man_t * p ) { return p->nTruePos; } +static inline int Saig_ManCiNum( Aig_Man_t * p ) { return p->nTruePis + p->nRegs; } +static inline int Saig_ManCoNum( Aig_Man_t * p ) { return p->nTruePos + p->nRegs; } +static inline int Saig_ManRegNum( Aig_Man_t * p ) { return p->nRegs; } +static inline int Saig_ManConstrNum( Aig_Man_t * p ) { return p->nConstrs; } +static inline Aig_Obj_t * Saig_ManLo( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, Saig_ManPiNum(p)+i); } +static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPos, Saig_ManPoNum(p)+i); } static inline int Saig_ObjIsPi( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPi(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPiNum(p); } static inline int Saig_ObjIsPo( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPo(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPoNum(p); } @@ -73,14 +106,14 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) { // iterator over the primary inputs/outputs #define Saig_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPis, pObj, i, Saig_ManPiNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPis, pObj, i, Saig_ManPiNum(p) ) #define Saig_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPos, pObj, i, Saig_ManPoNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPos, pObj, i, Saig_ManPoNum(p) ) // iterator over the latch inputs/outputs #define Saig_ManForEachLo( p, pObj, i ) \ - for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = Vec_PtrEntry(p->vPis, i+Saig_ManPiNum(p))), 1); i++ ) + for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = (Aig_Obj_t *)Vec_PtrEntry(p->vPis, i+Saig_ManPiNum(p))), 1); i++ ) #define Saig_ManForEachLi( p, pObj, i ) \ - for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = Vec_PtrEntry(p->vPos, i+Saig_ManPoNum(p))), 1); i++ ) + for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = (Aig_Obj_t *)Vec_PtrEntry(p->vPos, i+Saig_ManPoNum(p))), 1); i++ ) // iterator over the latch input and outputs #define Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) \ for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObjLi) = Saig_ManLi(p, i)), 1) \ @@ -89,21 +122,36 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) { //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - + /*=== sswAbs.c ==========================================================*/ +extern Aig_Man_t * Saig_ManCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +/*=== sswAbs2.c ==========================================================*/ +extern Aig_Man_t * Saig_ManConCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +/*=== sswPba.c ==========================================================*/ extern Aig_Man_t * Saig_ManProofAbstraction( 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 void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ); +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 ); +/*=== saigBmc3.c ==========================================================*/ +extern void Saig_ParBmcSetDefaultParams( Saig_ParBmc_t * p ); +extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * pPars ); /*=== saigCone.c ==========================================================*/ extern void Saig_ManPrintCones( Aig_Man_t * p ); +/*=== saigConstr.c ==========================================================*/ +extern Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig ); +extern Aig_Man_t * Saig_ManDupFoldConstrs( Aig_Man_t * pAig, Vec_Int_t * vConstrs ); +extern int Saig_ManDetectConstrTest( Aig_Man_t * p ); +extern void Saig_ManDetectConstrFuncTest( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ); +/*=== saigConstr2.c ==========================================================*/ +extern Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose ); +extern Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ); /*=== saigDup.c ==========================================================*/ extern Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * p ); -extern Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); +extern Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); /*=== saigHaig.c ==========================================================*/ extern Aig_Man_t * Saig_ManHaigRecord( Aig_Man_t * p, int nIters, int nSteps, int fRetimingOnly, int fAddBugs, int fUseCnf, int fVerbose ); /*=== saigInd.c ==========================================================*/ -extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ); +extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fVerbose, int fVeryVerbose ); /*=== saigIoa.c ==========================================================*/ extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName ); extern Aig_Man_t * Saig_ManReadBlif( char * pFileName ); @@ -115,6 +163,7 @@ extern Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ); extern Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames ); extern int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ); extern int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ); +extern int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, 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 ); /*=== saigRetFwd.c ==========================================================*/ @@ -128,8 +177,8 @@ extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fFo /*=== saigScl.c ==========================================================*/ extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); /*=== saigSimExt.c ==========================================================*/ -//extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo ); -//extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex ); +extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ); +extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); /*=== saigSimMv.c ==========================================================*/ extern int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose ); /*=== saigStrSim.c ==========================================================*/ @@ -145,9 +194,11 @@ extern Aig_Man_t * Saig_ManWindowExtract( Aig_Man_t * p, Aig_Obj_t * pObj, extern Aig_Man_t * Saig_ManWindowInsert( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist, Aig_Man_t * pWnd ); extern Aig_Obj_t * Saig_ManFindPivot( Aig_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/saig/saigAbs.c b/src/aig/saig/saigAbs.c index 2fac60f5..194add25 100644 --- a/src/aig/saig/saigAbs.c +++ b/src/aig/saig/saigAbs.c @@ -6,7 +6,7 @@ PackageName [Sequential AIG package.] - Synopsis [Proof-based abstraction.] + Synopsis [Counter-example-based abstraction.] Author [Alan Mishchenko] @@ -19,110 +19,24 @@ ***********************************************************************/ #include "saig.h" - -#include "cnf.h" -#include "satSolver.h" -#include "satStore.h" #include "ssw.h" -#include "ioa.h" #include "fra.h" +#include "bbr.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline char Saig_AbsVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { return Vec_StrGetEntry( p, nObjs*i+pObj->Id ); } -static inline void Saig_AbsSetVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { Vec_StrSetEntry( p, nObjs*i+pObj->Id, (char)1 ); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Finds the set of clauses involved in the UNSAT core.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsSolverUnsatCore( sat_solver * pSat, int nConfMax, int fVerbose ) -{ - Vec_Int_t * vCore; - void * pSatCnf; - Intp_Man_t * pManProof; - int RetValue, clk = clock(); - // solve the problem - RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( RetValue == l_Undef ) - { - printf( "Conflict limit is reached.\n" ); - return NULL; - } - if ( RetValue == l_True ) - { - printf( "The BMC problem is SAT.\n" ); - return NULL; - } - if ( fVerbose ) - { - printf( "SAT solver returned UNSAT after %d conflicts. ", pSat->stats.conflicts ); - ABC_PRT( "Time", clock() - clk ); - } - assert( RetValue == l_False ); - pSatCnf = sat_solver_store_release( pSat ); - // derive the UNSAT core - clk = clock(); - pManProof = Intp_ManAlloc(); - vCore = Intp_ManUnsatCore( pManProof, pSatCnf, 0 ); - Intp_ManFree( pManProof ); - Sto_ManFree( pSatCnf ); - if ( fVerbose ) - { - printf( "SAT core contains %d clauses (out of %d). ", Vec_IntSize(vCore), pSat->stats.clauses ); - ABC_PRT( "Time", clock() - clk ); - } - return vCore; -} - - -/**Function************************************************************* - - Synopsis [Mark visited nodes recursively.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * pObj, int i ) -{ - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ) ) - return 1; - Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ); - if ( Saig_ObjIsPi( p, pObj ) ) - return 1; - if ( Saig_ObjIsLo( p, pObj ) ) - { - if ( i == 0 ) - return 1; - return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 ); - } - if ( Aig_ObjIsPo( pObj ) ) - return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); - Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); - Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin1(pObj), i ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Mark visited nodes.] + Synopsis [Collects internal nodes in the DFS order.] Description [] @@ -131,47 +45,29 @@ int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * SeeAlso [] ***********************************************************************/ -Vec_Str_t * Saig_AbsMarkVisited( Aig_Man_t * p, int nFramesMax ) +int Saig_ManFindFirstFlop_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) { - Vec_Str_t * vObj2Visit; - Aig_Obj_t * pObj; - int i, f; - vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax ); -// Saig_ManForEachLo( p, pObj, i ) -// Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 ); - for ( f = 0; f < nFramesMax; f++ ) + int RetValue; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return -1; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Saig_ObjIsPi(p, pObj) ) + return -1; + if ( Saig_ObjIsLo(p, pObj) ) { - Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f ); - Saig_ManForEachPo( p, pObj, i ) - Saig_AbsMarkVisited_rec( p, vObj2Visit, pObj, f ); + assert( Aig_ObjPioNum(pObj) >= Saig_ManPiNum(p) ); + return Aig_ObjPioNum(pObj)-Saig_ManPiNum(p); } - return vObj2Visit; -} - -/**Function************************************************************* - - Synopsis [Performs the actual construction of the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) -{ - if ( pObj->pData ) - return pObj->pData; assert( Aig_ObjIsNode(pObj) ); - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pFrame, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + RetValue = Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin0(pObj) ); + if ( RetValue >= 0 ) + return RetValue; + return Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Derives a vector of AIG managers, one for each frame.] + Synopsis [Returns the index of the flop that appears in the support.] Description [] @@ -180,462 +76,12 @@ Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose ) +int Saig_ManFindFirstFlop( Aig_Man_t * p ) { - Vec_Ptr_t * vFrames, * vLoObjs, * vLiObjs; - Vec_Str_t * vObj2Visit; - Aig_Man_t * pFrame; - Aig_Obj_t * pObj; - int f, i; - vObj2Visit = Saig_AbsMarkVisited( p, nFramesMax ); - vFrames = Vec_PtrAlloc( nFramesMax ); - vLoObjs = Vec_PtrAlloc( 100 ); - vLiObjs = Vec_PtrAlloc( 100 ); - for ( f = 0; f < nFramesMax; f++ ) - { - Aig_ManCleanData( p ); - pFrame = Aig_ManStart( 1000 ); - Aig_ManConst1(p)->pData = Aig_ManConst1(pFrame); - // create PIs - Vec_PtrClear( vLoObjs ); - Vec_PtrClear( vLiObjs ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) - { - pObj->pData = Aig_ObjCreatePi(pFrame); - if ( i >= Saig_ManPiNum(p) ) - Vec_PtrPush( vLoObjs, pObj ); - } - } - // remember the number of (implicit) registers in this frame - pFrame->nAsserts = Vec_PtrSize(vLoObjs); - // create POs - Aig_ManForEachPo( p, pObj, i ) - { - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) - { - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); - pObj->pData = Aig_ObjCreatePo( pFrame, Aig_ObjChild0Copy(pObj) ); - if ( i >= Saig_ManPoNum(p) ) - Vec_PtrPush( vLiObjs, pObj ); - } - } -// Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) ); - Vec_PtrPush( vFrames, Cnf_DeriveSimple(pFrame, Aig_ManPoNum(pFrame)) ); - // set the new PIs to point to the corresponding registers - Aig_ManCleanData( pFrame ); - Vec_PtrForEachEntry( vLoObjs, pObj, i ) - ((Aig_Obj_t *)pObj->pData)->pData = pObj; - Vec_PtrForEachEntry( vLiObjs, pObj, i ) - ((Aig_Obj_t *)pObj->pData)->pData = pObj; - if ( fVerbose ) - printf( "%3d : PI =%8d. PO =%8d. Flop =%8d. Node =%8d.\n", - f, Aig_ManPiNum(pFrame), Aig_ManPoNum(pFrame), pFrame->nAsserts, Aig_ManNodeNum(pFrame) ); - } - Vec_PtrFree( vLoObjs ); - Vec_PtrFree( vLiObjs ); - Vec_StrFree( vObj2Visit ); - return vFrames; -} - -/**Function************************************************************* + Aig_ManIncrementTravId( p ); + Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) ); + return Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin0(Aig_ManPo(p, 0)) ); - Synopsis [Derives a vector of AIG managers, one for each frame.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -sat_solver * Saig_AbsCreateSolverDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames ) -{ - sat_solver * pSat; - Cnf_Dat_t * pCnf, * pCnfPrev; - Vec_Int_t * vPoLits; - Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; - int f, i, Lit, Lits[2], iVarOld, iVarNew, nSatVars, nRegisters; - // start array of output literals - vPoLits = Vec_IntAlloc( 100 ); - // count the number of CNF variables - nSatVars = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - nSatVars += pCnf->nVars; - - // create the SAT solver - pSat = sat_solver_new(); - sat_solver_store_alloc( pSat ); - sat_solver_setnvars( pSat, nSatVars ); - - // add clauses for the timeframes - nSatVars = 0; -// Vec_PtrForEachEntryReverse( vFrames, pCnf, f ) - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - // lift clauses of this CNF - Cnf_DataLift( pCnf, nSatVars ); - nSatVars += pCnf->nVars; - // copy clauses into the manager - for ( i = 0; i < pCnf->nClauses; i++ ) - { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - { - printf( "The BMC problem is trivially UNSAT.\n" ); - sat_solver_delete( pSat ); - Vec_IntFree( vPoLits ); - return NULL; - } - } - // remember output literal - Aig_ManForEachPo( pCnf->pMan, pObjPo, i ) - { - if ( i == Saig_ManPoNum(p) ) - break; - Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); - } - } - - // add auxiliary clauses (output, connectors, initial) - // add output clause - if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) - { - printf( "SAT solver is not created correctly.\n" ); - assert( 0 ); - } - Vec_IntFree( vPoLits ); - - // add connecting clauses - pCnfPrev = Vec_PtrEntry( vFrames, 0 ); - Vec_PtrForEachEntryStart( vFrames, pCnf, f, 1 ) - { - nRegisters = pCnf->pMan->nAsserts; - assert( nRegisters <= Aig_ManPoNum(pCnfPrev->pMan) ); - assert( nRegisters <= Aig_ManPiNum(pCnf->pMan) ); - for ( i = 0; i < nRegisters; i++ ) - { - pObjLi = Aig_ManPo( pCnfPrev->pMan, Aig_ManPoNum(pCnfPrev->pMan) - nRegisters + i ); - pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); - // get variable numbers - iVarOld = pCnfPrev->pVarNums[pObjLi->Id]; - iVarNew = pCnf->pVarNums[pObjLo->Id]; - // add clauses connecting existing variables - Lits[0] = toLitCond( iVarOld, 0 ); - Lits[1] = toLitCond( iVarNew, 1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( iVarOld, 1 ); - Lits[1] = toLitCond( iVarNew, 0 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - pCnfPrev = pCnf; - } - // add unit clauses - pCnf = Vec_PtrEntry( vFrames, 0 ); - nRegisters = pCnf->pMan->nAsserts; - for ( i = 0; i < nRegisters; i++ ) - { - pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); - assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); - Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); - if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) - assert( 0 ); - } - sat_solver_store_mark_roots( pSat ); - return pSat; -} - - -/**Function************************************************************* - - Synopsis [Creates SAT solver for BMC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -sat_solver * Saig_AbsCreateSolver( Cnf_Dat_t * pCnf, int nFrames ) -{ - sat_solver * pSat; - Vec_Int_t * vPoLits; - Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; - int f, i, Lit, Lits[2], iVarOld, iVarNew; - // start array of output literals - vPoLits = Vec_IntAlloc( nFrames * Saig_ManPoNum(pCnf->pMan) ); - // create the SAT solver - pSat = sat_solver_new(); - sat_solver_store_alloc( pSat ); - sat_solver_setnvars( pSat, pCnf->nVars * nFrames ); - - // add clauses for the timeframes - for ( f = 0; f < nFrames; f++ ) - { - for ( i = 0; i < pCnf->nClauses; i++ ) - { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - { - printf( "The BMC problem is trivially UNSAT.\n" ); - sat_solver_delete( pSat ); - Vec_IntFree( vPoLits ); - return NULL; - } - } - // remember output literal - Saig_ManForEachPo( pCnf->pMan, pObjPo, i ) - Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); - // lift CNF to the next frame - Cnf_DataLift( pCnf, pCnf->nVars ); - } - // put CNF back to the original level - Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); - - // add auxiliary clauses (output, connectors, initial) - // add output clause - if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) - assert( 0 ); - Vec_IntFree( vPoLits ); - // add connecting clauses - for ( f = 0; f < nFrames; f++ ) - { - // connect to the previous timeframe - if ( f > 0 ) - { - Saig_ManForEachLiLo( pCnf->pMan, pObjLi, pObjLo, i ) - { - iVarOld = pCnf->pVarNums[pObjLi->Id] - pCnf->nVars; - iVarNew = pCnf->pVarNums[pObjLo->Id]; - // add clauses connecting existing variables - Lits[0] = toLitCond( iVarOld, 0 ); - Lits[1] = toLitCond( iVarNew, 1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( iVarOld, 1 ); - Lits[1] = toLitCond( iVarNew, 0 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - } - // lift CNF to the next frame - Cnf_DataLift( pCnf, pCnf->nVars ); - } - // put CNF back to the original level - Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); - // add unit clauses - Saig_ManForEachLo( pCnf->pMan, pObjLo, i ) - { - assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); - Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); - if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) - assert( 0 ); - } - sat_solver_store_mark_roots( pSat ); - return pSat; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsCollectRegistersDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames, Vec_Int_t * vCore ) -{ - Aig_Obj_t * pObj; - Cnf_Dat_t * pCnf; - Vec_Int_t * vFlops; - int * pVars, * pFlops; - int i, f, iClause, iReg, * piLit, nSatVars, nSatClauses; - // count the number of CNF variables - nSatVars = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - nSatVars += pCnf->nVars; - // mark register variables - pVars = ABC_ALLOC( int, nSatVars ); - for ( i = 0; i < nSatVars; i++ ) - pVars[i] = -1; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - Aig_ManForEachPi( pCnf->pMan, pObj, i ) - { - assert( pCnf->pVarNums[pObj->Id] >= 0 ); - assert( pCnf->pVarNums[pObj->Id] < nSatVars ); - if ( pObj->pData == NULL ) - continue; - iReg = Aig_ObjPioNum(pObj->pData) - Saig_ManPiNum(p); - assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); - pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; - } - Aig_ManForEachPo( pCnf->pMan, pObj, i ) - { - assert( pCnf->pVarNums[pObj->Id] >= 0 ); - assert( pCnf->pVarNums[pObj->Id] < nSatVars ); - if ( pObj->pData == NULL ) - continue; - iReg = Aig_ObjPioNum(pObj->pData) - Saig_ManPoNum(p); - assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); - pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; - } - } - // mark used registers - pFlops = ABC_CALLOC( int, Aig_ManRegNum(p) ); - Vec_IntForEachEntry( vCore, iClause, i ) - { - nSatClauses = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - if ( iClause < nSatClauses + pCnf->nClauses ) - break; - nSatClauses += pCnf->nClauses; - } - if ( f == Vec_PtrSize(vFrames) ) - continue; - iClause = iClause - nSatClauses; - assert( iClause >= 0 ); - assert( iClause < pCnf->nClauses ); - // consider the clause - for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) - { - iReg = pVars[ lit_var(*piLit) ]; - if ( iReg >= 0 ) - pFlops[iReg] = 1; - } - } - // collect registers - vFlops = Vec_IntAlloc( Aig_ManRegNum(p) ); - for ( i = 0; i < Aig_ManRegNum(p); i++ ) - if ( pFlops[i] ) - Vec_IntPush( vFlops, i ); - ABC_FREE( pFlops ); - ABC_FREE( pVars ); - return vFlops; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsCollectRegisters( Cnf_Dat_t * pCnf, int nFrames, Vec_Int_t * vCore ) -{ - Aig_Obj_t * pObj; - Vec_Int_t * vFlops; - int * pVars, * pFlops; - int i, iClause, iReg, * piLit; - // mark register variables - pVars = ABC_ALLOC( int, pCnf->nVars ); - for ( i = 0; i < pCnf->nVars; i++ ) - pVars[i] = -1; - Saig_ManForEachLi( pCnf->pMan, pObj, i ) - pVars[ pCnf->pVarNums[pObj->Id] ] = i; - Saig_ManForEachLo( pCnf->pMan, pObj, i ) - pVars[ pCnf->pVarNums[pObj->Id] ] = i; - // mark used registers - pFlops = ABC_CALLOC( int, Aig_ManRegNum(pCnf->pMan) ); - Vec_IntForEachEntry( vCore, iClause, i ) - { - // skip auxiliary clauses - if ( iClause >= pCnf->nClauses * nFrames ) - continue; - // consider the clause - iClause = iClause % pCnf->nClauses; - for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) - { - iReg = pVars[ lit_var(*piLit) ]; - if ( iReg >= 0 ) - pFlops[iReg] = 1; - } - } - // collect registers - vFlops = Vec_IntAlloc( Aig_ManRegNum(pCnf->pMan) ); - for ( i = 0; i < Aig_ManRegNum(pCnf->pMan); i++ ) - if ( pFlops[i] ) - Vec_IntPush( vFlops, i ); - ABC_FREE( pFlops ); - ABC_FREE( pVars ); - return vFlops; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_AbsFreeCnfs( Vec_Ptr_t * vFrames ) -{ - Cnf_Dat_t * pCnf; - int i; - Vec_PtrForEachEntry( vFrames, pCnf, i ) - { - Aig_ManStop( pCnf->pMan ); - Cnf_DataFree( pCnf ); - } - Vec_PtrFree( vFrames ); -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) -{ - Vec_Ptr_t * vFlopPtrs, * vSupp; - Aig_Obj_t * pObj; - int i, Entry; - // collect latch inputs - vFlopPtrs = Vec_PtrAlloc( 1000 ); - Vec_IntForEachEntry( vFlops, Entry, i ) - { - Vec_PtrPush( vFlopPtrs, Saig_ManLi(p, Entry) ); - pObj = Saig_ManLo(p, Entry); - pObj->fMarkA = 1; - } - // collect latch outputs - vSupp = Vec_PtrAlloc( 1000 ); - Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vFlopPtrs), Vec_PtrSize(vFlopPtrs), vSupp ); - Vec_PtrFree( vFlopPtrs ); - // mark influencing flops - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->fMarkA = 1; - Vec_PtrFree( vSupp ); - // reload flops - Vec_IntClear( vFlops ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( pObj->fMarkA == 0 ) - continue; - pObj->fMarkA = 0; - if ( Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) >= 0 ) - Vec_IntPush( vFlops, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); - } } /**Function************************************************************* @@ -649,11 +95,15 @@ void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCexAbs ) +Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; int i, f; + if ( !Ssw_SmlRunCounterExample( pAbs, pCexAbs ) ) + printf( "Saig_ManCexRemap(): The intial counter-example is invalid.\n" ); + else + printf( "Saig_ManCexRemap(): The intial counter-example is correct.\n" ); // start the counter-example pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); pCex->iFrame = pCexAbs->iFrame; @@ -672,7 +122,7 @@ Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCex // verify the counter example if ( !Ssw_SmlRunCounterExample( p, pCex ) ) { - printf( "Saig_ManCexShrink(): Counter-example is invalid.\n" ); + printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" ); Ssw_SmlFreeCounterExample( pCex ); pCex = NULL; } @@ -695,7 +145,7 @@ Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCex SeeAlso [] ***********************************************************************/ -int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) +int Saig_ManCexFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) { Aig_Obj_t * pObj; int i; @@ -710,7 +160,7 @@ int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Refines abstraction using one step.] Description [] @@ -719,15 +169,12 @@ int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int * pnUseStart, int fVerbose ) +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 void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ); - extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex, int fVerbose ); - extern int Aig_ManVerifyUsingBdds( Aig_Man_t * p, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ); - - Vec_Int_t * vFlopsNew;//, * vPiToReg; -// Aig_Obj_t * pObj; - int i, Entry;//, iFlop; + 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 ); + Vec_Int_t * vFlopsNew; + int i, Entry; + *piRetValue = -1; if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 ) { Fra_Sec_t SecPar, * pSecPar = &SecPar; @@ -738,66 +185,92 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF } else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) ) { - int nBddMax = 1000000; - int nIterMax = nFrames; - int fPartition = 1; - int fReorder = 1; - int fReorderImage = 1; - Aig_ManVerifyUsingBdds( pAbs, nBddMax, nIterMax, fPartition, fReorder, fReorderImage, fVerbose, 0 ); + 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; + Aig_ManVerifyUsingBdds( pAbs, pPars ); } else - Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 20, nConfMaxOne, 1000000, fVerbose, 0 ); + { + Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 0, nConfMaxOne, 0, fVerbose, 0, pnFrames ); + } if ( pAbs->pSeqModel == NULL ) return NULL; if ( pnUseStart ) - *pnUseStart = ((Fra_Cex_t *)pAbs->pSeqModel)->iFrame; -// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManPiNum(p), pAbs->pSeqModel, fVerbose ); - vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); + *pnUseStart = pAbs->pSeqModel->iFrame; + vFlopsNew = Saig_ManExtendCounterExampleTest( 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_ManCexShrink( p, pAbs, pAbs->pSeqModel ); + 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.\n", Vec_IntSize(vFlopsNew) ); - // vFlopsNew contains PI number that should be kept in pAbs -/* - // for each additional PI, collect the number of a register it stands for - Vec_IntForEachEntry( vFlops, Entry, i ) - { - pObj = Saig_ManLo( p, Entry ); - pObj->fMarkA = 1; - } - vPiToReg = Vec_IntAlloc( 1000 ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( pObj->fMarkA ) - { - pObj->fMarkA = 0; - continue; - } - if ( i < Saig_ManPiNum(p) ) - Vec_IntPush( vPiToReg, -1 ); - else - Vec_IntPush( vPiToReg, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); - } - // collect registers + // add to the abstraction Vec_IntForEachEntry( vFlopsNew, Entry, i ) { - iFlop = Vec_IntEntry( vPiToReg, Entry ); - assert( iFlop >= 0 ); - assert( iFlop < Aig_ManRegNum(p) ); - Vec_IntPush( vFlops, iFlop ); + Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); + assert( Entry >= Saig_ManPiNum(p) ); + assert( Entry < Aig_ManPiNum(p) ); + Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); } - Vec_IntFree( vPiToReg ); Vec_IntFree( vFlopsNew ); Vec_IntSort( vFlops, 0 ); Vec_IntForEachEntryStart( vFlops, Entry, i, 1 ) assert( Vec_IntEntry(vFlops, i-1) != Entry ); -*/ + + return Saig_ManDeriveAbstraction( p, vFlops ); +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using one step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ) +{ + Aig_Man_t * pAbs; + Vec_Int_t * vFlopsNew; + int i, Entry; + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + vFlopsNew = Saig_ManExtendCounterExampleTest( 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_ManPiNum(pAbs), Aig_ManPiNum(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.\n", Vec_IntSize(vFlopsNew) ); + // vFlopsNew contains PI number that should be kept in pAbs // add to the abstraction Vec_IntForEachEntry( vFlopsNew, Entry, i ) { @@ -807,17 +280,13 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF 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_ManAbstraction( p, vFlops ); + Aig_ManStop( pAbs ); + return 1; } /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Computes the flops to remain after abstraction.] Description [] @@ -826,138 +295,67 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManProofAbstraction_int( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ) { - Aig_Man_t * pResult, * pTemp; - Cnf_Dat_t * pCnf; - Vec_Ptr_t * vFrames; - sat_solver * pSat; - Vec_Int_t * vCore; + int nUseStart = 0; + Aig_Man_t * pAbs, * pTemp; Vec_Int_t * vFlops; - int Iter, clk = clock(), clk2 = clock(); + int Iter, clk = clock(), clk2 = clock();//, iFlop; assert( Aig_ManRegNum(p) > 0 ); + if ( pPars->fVerbose ) + printf( "Performing counter-example-based refinement.\n" ); Aig_ManSetPioNumbers( p ); - - if ( pPars->fSkipProof ) - { -// assert( 0 ); - if ( pPars->fVerbose ) - printf( "Performing counter-example-based refinement.\n" ); -// vFlops = Vec_IntStartNatural( 100 ); -// Vec_IntPush( vFlops, 0 ); - vFlops = Vec_IntStartNatural( 1 ); - } - else - { - if ( pPars->fVerbose ) - printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", pPars->nFramesMax, pPars->nConfMax ); - if ( pPars->fDynamic ) - { - // create CNF for the frames - vFrames = Saig_AbsCreateFrames( p, pPars->nFramesMax, pPars->fVerbose ); - // create dynamic solver - pSat = Saig_AbsCreateSolverDyn( p, vFrames ); - } - else - { - // create CNF for the AIG - pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) ); - // create SAT solver for the unrolled AIG - pSat = Saig_AbsCreateSolver( pCnf, pPars->nFramesMax ); - } - if ( pPars->fVerbose ) - { - printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses ); - ABC_PRT( "Time", clock() - clk2 ); - } - // compute UNSAT core - vCore = Saig_AbsSolverUnsatCore( pSat, pPars->nConfMax, pPars->fVerbose ); - sat_solver_delete( pSat ); - if ( vCore == NULL ) - { - Saig_AbsFreeCnfs( vFrames ); - return NULL; - } - // collect registers - if ( pPars->fDynamic ) - { - vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore ); - Saig_AbsFreeCnfs( vFrames ); - } - else - { - vFlops = Saig_AbsCollectRegisters( pCnf, pPars->nFramesMax, vCore ); - Cnf_DataFree( pCnf ); - } - Vec_IntFree( vCore ); - if ( pPars->fVerbose ) - { - printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) ); - ABC_PRT( "Time", clock() - clk ); - } - } + vFlops = Vec_IntStartNatural( 1 ); /* - // extend the abstraction - if ( fExtend ) - { - if ( fVerbose ) - printf( "Support extended from %d flops to", Vec_IntSize(vFlops) ); - Saig_AbsExtendOneStep( p, vFlops ); - if ( fVerbose ) - printf( " %d flops.\n", Vec_IntSize(vFlops) ); - } + iFlop = Saig_ManFindFirstFlop( p ); + assert( iFlop >= 0 ); + vFlops = Vec_IntAlloc( 1 ); + Vec_IntPush( vFlops, iFlop ); */ // create the resulting AIG - pResult = Saig_ManAbstraction( p, vFlops ); - - if ( pPars->fExtend ) + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + if ( !pPars->fVerbose ) { - int nUseStart = 0; - 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 ) { - printf( "Init : " ); - Aig_ManPrintStats( pResult ); + ABC_FREE( p->pSeqModel ); + p->pSeqModel = pAbs->pSeqModel; + pAbs->pSeqModel = NULL; + Aig_ManStop( pAbs ); + break; } - printf( "Refining abstraction...\n" ); - for ( Iter = 0; ; Iter++ ) - { - pTemp = Saig_ManProofRefine( p, pResult, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fUseStart?&nUseStart:NULL, pPars->fVerbose ); - if ( pTemp == NULL ) - break; - Aig_ManStop( pResult ); - pResult = pTemp; - printf( "ITER %4d : ", Iter ); - if ( !pPars->fVerbose ) - Aig_ManPrintStats( pResult ); -// else -// printf( " -----------------------------------------------------\n" ); - // output the intermediate result of abstraction - Ioa_WriteAiger( pResult, "gabs.aig", 0, 0 ); + 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(pTemp))/Aig_ManRegNum(p) < 1.0*pPars->nRatio ) - { - printf( "Refinements is stopped because flop reduction is less than %d%%\n", pPars->nRatio ); - Aig_ManStop( pResult ); - pResult = NULL; - break; - } + // 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; } } - // write the final result - if ( pResult ) - Aig_ManStop( pResult ); - else - { - Vec_IntFree( vFlops ); - vFlops = NULL; - } return vFlops; } /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Performs counter-example-based abstraction.] Description [] @@ -966,15 +364,15 @@ Vec_Int_t * Saig_ManProofAbstraction_int( Aig_Man_t * p, Gia_ParAbs_t * pPars ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +Aig_Man_t * Saig_ManCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) { Vec_Int_t * vFlops; Aig_Man_t * pAbs = NULL; - vFlops = Saig_ManProofAbstraction_int( p, pPars ); + vFlops = Saig_ManCexAbstractionFlops( p, pPars ); // write the final result if ( vFlops ) { - pAbs = Saig_ManAbstraction( p, vFlops ); + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); Vec_IntFree( vFlops ); @@ -987,3 +385,5 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigAbs2.c b/src/aig/saig/saigAbs2.c new file mode 100644 index 00000000..a4d0f973 --- /dev/null +++ b/src/aig/saig/saigAbs2.c @@ -0,0 +1,237 @@ +/**CFile**************************************************************** + + FileName [saigAbs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Counter-example-based abstraction with constraints.] + + 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" +#include "ssw.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern int Saig_ManFindFirstFlop( Aig_Man_t * p ); +extern 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 ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the array of constraint numbers that are violated.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManFindViolatedConstrs( Aig_Man_t * p, Abc_Cex_t * pCexAbs ) +{ + Vec_Int_t * vFailed; + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + int * pPoMap, i, k, iBit; + pPoMap = ABC_CALLOC( int, Saig_ManPoNum(p) ); + Aig_ManCleanMarkA(p); + Saig_ManForEachLo( p, pObj, i ) + pObj->fMarkA = 0; + assert( pCexAbs->nBits == pCexAbs->nRegs + (pCexAbs->iFrame + 1) * pCexAbs->nPis ); + for ( i = 0; i <= pCexAbs->iFrame; i++ ) + { + iBit = pCexAbs->nRegs + i * pCexAbs->nPis; + Saig_ManForEachPi( p, pObj, k ) + pObj->fMarkA = Aig_InfoHasBit(pCexAbs->pData, iBit++); + Aig_ManForEachNode( p, pObj, k ) + pObj->fMarkA = (Aig_ObjFanin0(pObj)->fMarkA ^ Aig_ObjFaninC0(pObj)) & + (Aig_ObjFanin1(pObj)->fMarkA ^ Aig_ObjFaninC1(pObj)); + Aig_ManForEachPo( p, pObj, k ) + pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA ^ Aig_ObjFaninC0(pObj); + Saig_ManForEachPo( p, pObj, k ) + pPoMap[k] |= pObj->fMarkA; + Saig_ManForEachLiLo( p, pObjRi, pObjRo, k ) + pObjRo->fMarkA = pObjRi->fMarkA; + } + Aig_ManCleanMarkA(p); + // collect numbers of failed constraints + vFailed = Vec_IntAlloc( Saig_ManPoNum(p) ); + Saig_ManForEachPo( p, pObj, k ) + if ( pPoMap[k] ) + Vec_IntPush( vFailed, k ); + ABC_FREE( pPoMap ); + return vFailed; +} + +/**Function************************************************************* + + Synopsis [Computes the flops to remain after abstraction.] + + Description [Updates the set of included constraints.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManConCexAbstractionFlops( Aig_Man_t * pInit, Gia_ParAbs_t * pPars, Vec_Int_t * vConstrs ) +{ + int nUseStart = 0; + Aig_Man_t * pCur, * pAbs, * pTemp; + Vec_Int_t * vFlops, * vFlopsCopy, * vConstrsToAdd; + int i, Entry, iFlop, Iter, clk = clock(), clk2 = clock(); + assert( Aig_ManRegNum(pInit) > 0 ); + if ( pPars->fVerbose ) + printf( "Performing counter-example-based refinement with constraints.\n" ); +// Aig_ManSetPioNumbers( p ); + // create constrained AIG + pCur = Saig_ManDupFoldConstrs( pInit, vConstrs ); + assert( Saig_ManPoNum(pCur) == 1 ); + printf( "cur>>> " ); Aig_ManPrintStats( pCur ); + // start the flop map + iFlop = Saig_ManFindFirstFlop( pCur ); + assert( iFlop >= 0 ); +// vFlops = Vec_IntStartNatural( 1 ); + vFlops = Vec_IntAlloc( 1 ); + Vec_IntPush( vFlops, iFlop ); + // create the abstraction + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + printf( "abs>>> " ); Aig_ManPrintStats( pAbs ); + if ( !pPars->fVerbose ) + { + printf( "Init : " ); + Aig_ManPrintStats( pAbs ); + } + printf( "Refining abstraction...\n" ); + for ( Iter = 0; ; Iter++ ) + { + while ( 1 ) + { + vFlopsCopy = Vec_IntDup( vFlops ); + pTemp = Saig_ManCexRefine( pCur, pAbs, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fVerbose, pPars->fUseStart?&nUseStart:NULL, &pPars->Status, &pPars->nFramesDone ); + if ( pTemp == NULL ) + { + Vec_IntFree( vFlopsCopy ); + break; + } + vConstrsToAdd = Saig_ManFindViolatedConstrs( pInit, pAbs->pSeqModel ); + if ( Vec_IntSize(vConstrsToAdd) == 0 ) + { + Vec_IntFree( vConstrsToAdd ); + Vec_IntFree( vFlopsCopy ); + break; + } + // add the constraints to the base set + Vec_IntForEachEntry( vConstrsToAdd, Entry, i ) + { +// assert( Vec_IntFind(vConstrs, Entry) == -1 ); + Vec_IntPushUnique( vConstrs, Entry ); + } + printf( "Adding %3d constraints. The total is %3d (out of %3d).\n", + Vec_IntSize(vConstrsToAdd), Vec_IntSize(vConstrs), Saig_ManPoNum(pInit)-1 ); + Vec_IntFree( vConstrsToAdd ); + // update the current one + Aig_ManStop( pCur ); + pCur = Saig_ManDupFoldConstrs( pInit, vConstrs ); + printf( "cur>>> " ); Aig_ManPrintStats( pCur ); + // update the flop map + Vec_IntFree( vFlops ); + vFlops = vFlopsCopy; +// Vec_IntFree( vFlopsCopy ); +// vFlops = vFlops; + // update abstraction + Aig_ManStop( pAbs ); + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + printf( "abs>>> " ); Aig_ManPrintStats( pAbs ); + } + Aig_ManStop( pAbs ); + if ( pTemp == NULL ) + break; + 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(pCur)-Aig_ManRegNum(pAbs))/Aig_ManRegNum(pCur) < 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; + } + } + ABC_FREE( pInit->pSeqModel ); + pInit->pSeqModel = pCur->pSeqModel; + pCur->pSeqModel = NULL; + Aig_ManStop( pCur ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs counter-example-based abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManConCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops, * vConstrs; + Aig_Man_t * pCur, * pAbs = NULL; + assert( Saig_ManPoNum(p) > 1 ); // should contain constraint outputs + // start included constraints + vConstrs = Vec_IntAlloc( 100 ); + // perform refinement + vFlops = Saig_ManConCexAbstractionFlops( p, pPars, vConstrs ); + // write the final result + if ( vFlops ) + { + pCur = Saig_ManDupFoldConstrs( p, vConstrs ); + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + Aig_ManStop( pCur ); + + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); + printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); + Vec_IntFree( vFlops ); + } + Vec_IntFree( vConstrs ); + return pAbs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc.c b/src/aig/saig/saigBmc.c index ac1cbe5b..8aa3af80 100644 --- a/src/aig/saig/saigBmc.c +++ b/src/aig/saig/saigBmc.c @@ -19,375 +19,72 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" #include "cnf.h" #include "satStore.h" -#include "ssw.h" + +ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define AIG_VISITED ((Aig_Obj_t *)(ABC_PTRUINT_T)1) - -typedef struct Saig_Bmc_t_ Saig_Bmc_t; -struct Saig_Bmc_t_ -{ - // parameters - int nFramesMax; // the max number of timeframes to consider - int nNodesMax; // the max number of nodes to add - int nConfMaxOne; // the max number of conflicts at a target - int nConfMaxAll; // the max number of conflicts for all targets - int fVerbose; // enables verbose output - // AIG managers - Aig_Man_t * pAig; // the user's AIG manager - Aig_Man_t * pFrm; // Frames manager - Vec_Ptr_t * vVisited; // nodes visited in Frames - // node mapping - int nObjs; // the largest number of an AIG object - Vec_Ptr_t * vAig2Frm; // mapping of AIG nodees into Frames nodes -// Vec_Str_t * vAig2Frm2; // mapping of AIG nodees into Frames nodes - // SAT solver - sat_solver * pSat; // SAT solver - int nSatVars; // the number of used SAT variables - Vec_Int_t * vObj2Var; // mapping of frames objects in CNF variables - // subproblems - Vec_Ptr_t * vTargets; // targets to be solved in this interval - int iFramePrev; // previous frame - int iFrameLast; // last frame - int iOutputLast; // last output - int iFrameFail; // failed frame - int iOutputFail; // failed output -}; - -static inline int Saig_BmcSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vObj2Var, pObj->Id ); } -static inline void Saig_BmcSetSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vObj2Var, pObj->Id, Num); } - -static inline Aig_Obj_t * Saig_BmcObjFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { return Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } -static inline void Saig_BmcObjSetFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); } - -static inline Aig_Obj_t * Saig_BmcObjChild0( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)); } -static inline Aig_Obj_t * Saig_BmcObjChild1( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define ABS_ZER 1 -#define ABS_ONE 2 -#define ABS_UND 3 - -static inline int Abs_ManSimInfoNot( int Value ) -{ - if ( Value == ABS_ZER ) - return ABS_ONE; - if ( Value == ABS_ONE ) - return ABS_ZER; - return ABS_UND; -} - -static inline int Abs_ManSimInfoAnd( int Value0, int Value1 ) -{ - if ( Value0 == ABS_ZER || Value1 == ABS_ZER ) - return ABS_ZER; - if ( Value0 == ABS_ONE && Value1 == ABS_ONE ) - return ABS_ONE; - return ABS_UND; -} - -static inline int Abs_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame ); - return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); -} - -static inline void Abs_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) -{ - unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame ); - assert( Value >= ABS_ZER && Value <= ABS_UND ); - Value ^= Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); - pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); -} - /**Function************************************************************* - Synopsis [Performs ternary simulation for one node.] + Synopsis [Create timeframes of the manager for BMC.] - Description [] + Description [The resulting manager is combinational. POs correspond to \ + the property outputs in each time-frame.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Abs_ManExtendOneEval_rec( Vec_Ptr_t * vSimInfo, Aig_Man_t * p, Aig_Obj_t * pObj, int iFrame ) +Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) { - int Value0, Value1, Value; - Value = Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); - if ( Value ) - return Value; - if ( Aig_ObjIsPi(pObj) ) - { - assert( Saig_ObjIsLo(p, pObj) ); - Value = Abs_ManExtendOneEval_rec( vSimInfo, p, Saig_ObjLoToLi(p, pObj), iFrame-1 ); - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - return Value; - } - Value0 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin0(pObj), iFrame ); - if ( Aig_ObjFaninC0(pObj) ) - Value0 = Abs_ManSimInfoNot( Value0 ); - if ( Aig_ObjIsPo(pObj) ) - { - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); - return Value0; - } - assert( Aig_ObjIsNode(pObj) ); - if ( Value0 == ABS_ZER ) - Value = ABS_ZER; - else - { - Value1 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin1(pObj), iFrame ); - if ( Aig_ObjFaninC1(pObj) ) - Value1 = Abs_ManSimInfoNot( Value1 ); - Value = Abs_ManSimInfoAnd( Value0, Value1 ); - } - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - assert( Value ); - return Value; -} - -/**Function************************************************************* - - Synopsis [Performs ternary simulation for one design.] - - Description [The returned array contains the result of ternary - simulation for all the frames where the output could be proved 0.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abs_ManTernarySimulate( Aig_Man_t * p, int nFramesMax, int fVerbose ) -{ - Vec_Ptr_t * vSimInfo; - Aig_Obj_t * pObj; - int i, f, nFramesLimit, nFrameWords; - int clk = clock(); - assert( Aig_ManRegNum(p) > 0 ); - // the maximum number of frames will be determined to use at most 200Mb of RAM - nFramesLimit = 1 + (200000000 * 4)/Aig_ManObjNum(p); - nFramesLimit = ABC_MIN( nFramesLimit, nFramesMax ); - nFrameWords = Aig_BitWordNum( 2 * Aig_ManObjNum(p) ); - // allocate simulation info - vSimInfo = Vec_PtrAlloc( nFramesLimit ); - for ( f = 0; f < nFramesLimit; f++ ) - { - Vec_PtrPush( vSimInfo, ABC_CALLOC(unsigned, nFrameWords) ); - if ( f == 0 ) - { - Saig_ManForEachLo( p, pObj, i ) - Abs_ManSimInfoSet( vSimInfo, pObj, 0, ABS_ZER ); - } - Abs_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, ABS_ONE ); - Saig_ManForEachPi( p, pObj, i ) - Abs_ManSimInfoSet( vSimInfo, pObj, f, ABS_UND ); - Saig_ManForEachPo( p, pObj, i ) - Abs_ManExtendOneEval_rec( vSimInfo, p, pObj, f ); - // check if simulation has derived at least one fail or unknown - Saig_ManForEachPo( p, pObj, i ) - if ( Abs_ManSimInfoGet(vSimInfo, pObj, f) != ABS_ZER ) - { - if ( fVerbose ) - { - printf( "Ternary sim found non-zero output in frame %d. Used %5.2f Mb. ", - f, 0.25 * (f+1) * Aig_ManObjNum(p) / (1<<20) ); - ABC_PRT( "Time", clock() - clk ); - } - return vSimInfo; - } - } - if ( fVerbose ) - { - printf( "Ternary sim proved all outputs in the first %d frames. Used %5.2f Mb. ", - nFramesLimit, 0.25 * nFramesLimit * Aig_ManObjNum(p) / (1<<20) ); - ABC_PRT( "Time", clock() - clk ); - } - return vSimInfo; -} - -/**Function************************************************************* - - Synopsis [Free the array of simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_ManFreeAray( Vec_Ptr_t * p ) -{ - void * pTemp; - int i; - Vec_PtrForEachEntry( p, pTemp, i ) - ABC_FREE( pTemp ); - Vec_PtrFree( p ); -} - - -/**Function************************************************************* - - Synopsis [Create manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Saig_Bmc_t * Saig_BmcManStart( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose ) -{ - Saig_Bmc_t * p; - Aig_Obj_t * pObj; - int i, Lit; -// assert( Aig_ManRegNum(pAig) > 0 ); - p = (Saig_Bmc_t *)ABC_ALLOC( char, sizeof(Saig_Bmc_t) ); - memset( p, 0, sizeof(Saig_Bmc_t) ); - // set parameters - p->nFramesMax = nFramesMax; - p->nNodesMax = nNodesMax; - p->nConfMaxOne = nConfMaxOne; - p->nConfMaxAll = nConfMaxAll; - p->fVerbose = fVerbose; - p->pAig = pAig; - p->nObjs = Aig_ManObjNumMax(pAig); - // create node and variable mappings - p->vAig2Frm = Vec_PtrAlloc( 0 ); - Vec_PtrFill( p->vAig2Frm, 5 * p->nObjs, NULL ); - p->vObj2Var = Vec_IntAlloc( 0 ); - Vec_IntFill( p->vObj2Var, 5 * p->nObjs, 0 ); - // start the AIG manager and map primary inputs - p->pFrm = Aig_ManStart( 5 * p->nObjs ); + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f; + assert( Saig_ManRegNum(pAig) > 0 ); + pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); + // create variables for register outputs Saig_ManForEachLo( pAig, pObj, i ) - Saig_BmcObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrm) ); - // create SAT solver - p->nSatVars = 1; - p->pSat = sat_solver_new(); - sat_solver_setnvars( p->pSat, 2000 ); - Lit = toLit( p->nSatVars ); - sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); - Saig_BmcSetSatNum( p, Aig_ManConst1(p->pFrm), p->nSatVars++ ); - // other data structures - p->vTargets = Vec_PtrAlloc( 0 ); - p->vVisited = Vec_PtrAlloc( 0 ); - p->iOutputFail = -1; - p->iFrameFail = -1; - return p; -} - -/**Function************************************************************* - - Synopsis [Delete manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcManStop( Saig_Bmc_t * p ) -{ -// Aig_Obj_t * pObj; -// int i, f, Counter = 0; -// int i, Counter = 0; -// for ( i = 0; i < p->vAig2Frm2->nSize; i++ ) -// Counter += (p->vAig2Frm2->pArray[i] != 0); -// for ( i = 0; i < p->vAig2Frm->nSize; i++ ) -// Counter += (p->vAig2Frm->pArray[i] != NULL); -// printf( "Objs = %d. Nodes = %d. Frames = %d. Used = %d. Non-empty = %d.\n", -// p->nObjs, Aig_ManNodeNum(p->pAig), p->iFrameLast, p->vAig2Frm->nSize, Counter ); - -/* - Aig_ManForEachObj( p->pAig, pObj, i ) - { - int Last = -1; - for ( f = 0; f <= p->iFrameLast; f++ ) - if ( Saig_BmcObjFrame( p, pObj, f ) ) - Last = f; - if ( i % 50 == 0 ) - printf( "%d ", Last ); - } - printf( "\n" ); -*/ - - Aig_ManStop( p->pFrm ); - Vec_PtrFree( p->vAig2Frm ); -// Vec_StrFree( p->vAig2Frm2 ); - Vec_IntFree( p->vObj2Var ); - sat_solver_delete( p->pSat ); - Vec_PtrFree( p->vTargets ); - Vec_PtrFree( p->vVisited ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Explores the possibility of constructing the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) -{ - Aig_Obj_t * pRes, * p0, * p1, * pConst1 = Aig_ManConst1(p->pAig); - pRes = Saig_BmcObjFrame( p, pObj, i ); - if ( pRes != NULL ) - return pRes; - if ( Saig_ObjIsPi( p->pAig, pObj ) ) - pRes = AIG_VISITED; - else if ( Saig_ObjIsLo( p->pAig, pObj ) ) - pRes = Saig_BmcIntervalExplore_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 ); - else if ( Aig_ObjIsPo( pObj ) ) - { - pRes = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); - if ( pRes != AIG_VISITED ) - pRes = Saig_BmcObjChild0( p, pObj, i ); - } - else + pObj->pData = Aig_ManConst0( pFrames ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) { - p0 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); - if ( p0 != AIG_VISITED ) - p0 = Saig_BmcObjChild0( p, pObj, i ); - p1 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin1(pObj), i ); - if ( p1 != AIG_VISITED ) - p1 = Saig_BmcObjChild1( p, pObj, i ); - - if ( p0 == Aig_Not(p1) ) - pRes = Aig_ManConst0(p->pFrm); - else if ( Aig_Regular(p0) == pConst1 ) - pRes = (p0 == pConst1) ? p1 : Aig_ManConst0(p->pFrm); - else if ( Aig_Regular(p1) == pConst1 ) - pRes = (p1 == pConst1) ? p0 : Aig_ManConst0(p->pFrm); - else - pRes = AIG_VISITED; - - if ( pRes != AIG_VISITED && !Aig_ObjIsConst1(Aig_Regular(pRes)) ) - pRes = AIG_VISITED; + // create PI nodes for this frame + Saig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create POs for this frame + Saig_ManForEachPo( pAig, pObj, i ) + Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); + if ( f == nFrames - 1 ) + break; + // save register inputs + Saig_ManForEachLi( pAig, pObj, i ) + pObj->pData = Aig_ObjChild0Copy(pObj); + // transfer to register outputs + Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) + pObjLo->pData = pObjLi->pData; } - Saig_BmcObjSetFrame( p, pObj, i, pRes ); - return pRes; + Aig_ManCleanup( pFrames ); + return pFrames; } /**Function************************************************************* - Synopsis [Performs the actual construction of the output.] + Synopsis [Returns the number of internal nodes that are not counted yet.] Description [] @@ -396,271 +93,88 @@ Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i SeeAlso [] ***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited ) +int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) { - Aig_Obj_t * pRes; - pRes = Saig_BmcObjFrame( p, pObj, i ); - if ( pRes != NULL ) - return pRes; - if ( Saig_ObjIsPi( p->pAig, pObj ) ) - pRes = Aig_ObjCreatePi(p->pFrm); - else if ( Saig_ObjIsLo( p->pAig, pObj ) ) - pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited ); - else if ( Aig_ObjIsPo( pObj ) ) - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); - pRes = Saig_BmcObjChild0( p, pObj, i ); - } - else - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); - if ( Saig_BmcObjChild0(p, pObj, i) == Aig_ManConst0(p->pFrm) ) - pRes = Aig_ManConst0(p->pFrm); - else - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited ); - pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) ); - } - } - assert( pRes != NULL ); - Saig_BmcObjSetFrame( p, pObj, i, pRes ); - Vec_PtrPush( vVisited, pObj ); - Vec_PtrPush( vVisited, (void *)i ); - return pRes; + if ( !Aig_ObjIsNode(pObj) ) + return 0; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Aig_ObjSetTravIdCurrent(p, pObj); + return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) + + Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Adds new AIG nodes to the frames.] + Synopsis [Create timeframes of the manager for BMC.] - Description [] + Description [The resulting manager is combinational. POs correspond to + the property outputs in each time-frame. + The unrolling is stopped as soon as the number of nodes in the frames + exceeds the given maximum size.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Saig_BmcInterval( Saig_Bmc_t * p ) +Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax ) { - Aig_Obj_t * pTarget; - Aig_Obj_t * pObj, * pRes; - int i, iFrame, Counter; - int nNodes = Aig_ManObjNum( p->pFrm ); - Vec_PtrClear( p->vTargets ); - p->iFramePrev = p->iFrameLast; - for ( ; p->iFrameLast < p->nFramesMax; p->iFrameLast++, p->iOutputLast = 0 ) + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo; + int i, f, Counter = 0; + assert( Saig_ManRegNum(pAig) > 0 ); + pFrames = Aig_ManStart( nSizeMax ); + Aig_ManIncrementTravId( pFrames ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); + // create variables for register outputs + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_ManConst0( pFrames ); + // add timeframes + Counter = 0; + for ( f = 0; f < nFrames; f++ ) { - if ( p->iOutputLast == 0 ) + // create PI nodes for this frame + Saig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create POs for this frame + Saig_ManForEachPo( pAig, pObj, i ) { - Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) ); + pObjPo = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); + Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) ); } - for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ ) - { - if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax ) - return; -// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast ); - Vec_PtrClear( p->vVisited ); - pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited ); - Vec_PtrPush( p->vTargets, pTarget ); - Aig_ObjCreatePo( p->pFrm, pTarget ); - Aig_ManCleanup( p->pFrm ); - // check if the node is gone - Counter = 0; - Vec_PtrForEachEntry( p->vVisited, pObj, i ) - { - iFrame = (int)(ABC_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ ); - pRes = Saig_BmcObjFrame( p, pObj, iFrame ); - if ( Aig_ObjIsNone( Aig_Regular(pRes) ) ) - { - Saig_BmcObjSetFrame( p, pObj, iFrame, NULL ); - Counter++; - } - } -// printf( "%d ", Counter ); - } - } -} - -/**Function************************************************************* - - Synopsis [Performs the actual construction of the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalToAig_rec( Saig_Bmc_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObj ) -{ - if ( pObj->pData ) - return pObj->pData; - Vec_PtrPush( p->vVisited, pObj ); - if ( Saig_BmcSatNum(p, pObj) || Aig_ObjIsPi(pObj) ) - return pObj->pData = Aig_ObjCreatePi(pNew); - Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin0(pObj) ); - Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin1(pObj) ); - assert( pObj->pData == NULL ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Creates AIG of the newly added nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_BmcIntervalToAig( Saig_Bmc_t * p ) -{ - Aig_Man_t * pNew; - Aig_Obj_t * pObj, * pObjNew; - int i; - Aig_ManForEachObj( p->pFrm, pObj, i ) - assert( pObj->pData == NULL ); - - pNew = Aig_ManStart( p->nNodesMax ); - Aig_ManConst1(p->pFrm)->pData = Aig_ManConst1(pNew); - Vec_PtrClear( p->vVisited ); - Vec_PtrPush( p->vVisited, Aig_ManConst1(p->pFrm) ); - Vec_PtrForEachEntry( p->vTargets, pObj, i ) - { -// assert( !Aig_ObjIsConst1(Aig_Regular(pObj)) ); - pObjNew = Saig_BmcIntervalToAig_rec( p, pNew, Aig_Regular(pObj) ); - assert( !Aig_IsComplement(pObjNew) ); - Aig_ObjCreatePo( pNew, pObjNew ); - } - return pNew; -} - -/**Function************************************************************* - - Synopsis [Derives CNF for the newly added nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcLoadCnf( Saig_Bmc_t * p, Cnf_Dat_t * pCnf ) -{ - Aig_Obj_t * pObj, * pObjNew; - int i, Lits[2], VarNumOld, VarNumNew; - Vec_PtrForEachEntry( p->vVisited, pObj, i ) - { - // get the new variable of this node - pObjNew = pObj->pData; - pObj->pData = NULL; - VarNumNew = pCnf->pVarNums[ pObjNew->Id ]; - if ( VarNumNew == -1 ) - continue; - // get the old variable of this node - VarNumOld = Saig_BmcSatNum( p, pObj ); - if ( VarNumOld == 0 ) + if ( Counter >= nSizeMax ) { - Saig_BmcSetSatNum( p, pObj, VarNumNew ); - continue; + Aig_ManCleanup( pFrames ); + return pFrames; } - // add clauses connecting existing variables - Lits[0] = toLitCond( VarNumOld, 0 ); - Lits[1] = toLitCond( VarNumNew, 1 ); - if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( VarNumOld, 1 ); - Lits[1] = toLitCond( VarNumNew, 0 ); - if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - // add CNF to the SAT solver - for ( i = 0; i < pCnf->nClauses; i++ ) - if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + if ( f == nFrames - 1 ) break; - if ( i < pCnf->nClauses ) - printf( "SAT solver became UNSAT after adding clauses.\n" ); -} - -/**Function************************************************************* - - Synopsis [Solves targets with the given resource limit.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcDeriveFailed( Saig_Bmc_t * p, int iTargetFail ) -{ - int k; - p->iOutputFail = p->iOutputLast; - p->iFrameFail = p->iFrameLast; - for ( k = Vec_PtrSize(p->vTargets); k > iTargetFail; k-- ) - { - if ( p->iOutputFail == 0 ) - { - p->iOutputFail = Saig_ManPoNum(p->pAig); - p->iFrameFail--; - } - p->iOutputFail--; + // save register inputs + Saig_ManForEachLi( pAig, pObj, i ) + pObj->pData = Aig_ObjChild0Copy(pObj); + // transfer to register outputs + Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) + pObjLo->pData = pObjLi->pData; } + Aig_ManCleanup( pFrames ); + return pFrames; } -/**Function************************************************************* +ABC_NAMESPACE_IMPL_END - Synopsis [Solves targets with the given resource limit.] +#include "utilMem.h" - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) -{ - Ssw_Cex_t * pCex; - Aig_Obj_t * pObj, * pObjFrm; - int i, f, iVarNum; - // start the counter-example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); - pCex->iFrame = p->iFrameFail; - pCex->iPo = p->iOutputFail; - // copy the bit data - for ( f = 0; f <= p->iFrameFail; f++ ) - { - Saig_ManForEachPi( p->pAig, pObj, i ) - { - pObjFrm = Saig_BmcObjFrame( p, pObj, f ); - if ( pObjFrm == NULL ) - continue; - iVarNum = Saig_BmcSatNum( p, pObjFrm ); - if ( iVarNum == 0 ) - continue; - if ( sat_solver_var_value( p->pSat, iVarNum ) ) - Aig_InfoSetBit( pCex->pData, pCex->nRegs + Saig_ManPiNum(p->pAig) * f + i ); - } - } - // verify the counter example - if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) - { - printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); - pCex = NULL; - } - return pCex; -} +ABC_NAMESPACE_IMPL_START + /**Function************************************************************* - Synopsis [Solves targets with the given resource limit.] + Synopsis [Performs BMC for the given AIG.] Description [] @@ -669,157 +183,156 @@ Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) SeeAlso [] ***********************************************************************/ -int Saig_BmcSolveTargets( Saig_Bmc_t * p, int nStart, int * pnOutsSolved ) +int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ) { + extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ); + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Man_t * pFrames, * pAigTemp; Aig_Obj_t * pObj; - int i, VarNum, Lit, RetValue; - assert( Vec_PtrSize(p->vTargets) > 0 ); - if ( p->pSat->qtail != p->pSat->qhead ) + int status, clk, Lit, i, RetValue = -1; + + // derive the timeframes + clk = clock(); + if ( nCofFanLit ) { - RetValue = sat_solver_simplify(p->pSat); - assert( RetValue != 0 ); + pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit ); + if ( pFrames == NULL ) + return -1; } - Vec_PtrForEachEntry( p->vTargets, pObj, i ) + else if ( nSizeMax > 0 ) { - if ( ((*pnOutsSolved)++ / Saig_ManPoNum(p->pAig)) < nStart ) - continue; - if ( p->pSat->stats.conflicts > p->nConfMaxAll ) - return l_Undef; - VarNum = Saig_BmcSatNum( p, Aig_Regular(pObj) ); - Lit = toLitCond( VarNum, Aig_IsComplement(pObj) ); - RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)p->nConfMaxOne, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( RetValue == l_False ) // unsat - continue; - if ( RetValue == l_Undef ) // undecided - return l_Undef; - // generate counter-example - Saig_BmcDeriveFailed( p, i ); - p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p ); - - { -// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex ); -// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel ); - } - return l_True; + pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax ); + nFrames = Aig_ManPoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManPoNum(pFrames) % Saig_ManPoNum(pAig)) > 0); } - return l_False; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcAddTargetsAsPos( Saig_Bmc_t * p ) -{ - Aig_Obj_t * pObj; - int i; - Vec_PtrForEachEntry( p->vTargets, pObj, i ) - Aig_ObjCreatePo( p->pFrm, pObj ); - Aig_ManPrintStats( p->pFrm ); - Aig_ManCleanup( p->pFrm ); - Aig_ManPrintStats( p->pFrm ); -} - -/**Function************************************************************* - - Synopsis [Performs BMC with the given parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ) -{ - Saig_Bmc_t * p; - Aig_Man_t * pNew; - Cnf_Dat_t * pCnf; - int nOutsSolved = 0; - int Iter, RetValue, clk = clock(), clk2; -/* - Vec_Ptr_t * vSimInfo; - vSimInfo = Abs_ManTernarySimulate( pAig, nFramesMax, fVerbose ); - Abs_ManFreeAray( vSimInfo ); -*/ - p = Saig_BmcManStart( pAig, nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll, fVerbose ); + else + pFrames = Saig_ManFramesBmc( pAig, nFrames ); + if ( piFrame ) + *piFrame = nFrames; if ( fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) ); - printf( "Params: FramesMax = %d. NodesDelta = %d. ConfMaxOne = %d. ConfMaxAll = %d.\n", - nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll ); - } - - for ( Iter = 0; ; Iter++ ) + printf( "Time-frames (%d): PI/PO = %d/%d. Node = %6d. Lev = %5d. ", + nFrames, Aig_ManPiNum(pFrames), Aig_ManPoNum(pFrames), + Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); + } + // rewrite the timeframes + if ( fRewrite ) { - clk2 = clock(); - // add new logic interval to frames - Saig_BmcInterval( p ); -// Saig_BmcAddTargetsAsPos( p ); - if ( Vec_PtrSize(p->vTargets) == 0 ) - break; - // convert logic slice into new AIG - pNew = Saig_BmcIntervalToAig( p ); - // derive CNF for the new AIG - pCnf = Cnf_Derive( pNew, Aig_ManPoNum(pNew) ); - Cnf_DataLift( pCnf, p->nSatVars ); - p->nSatVars += pCnf->nVars; - // add this CNF to the solver - Saig_BmcLoadCnf( p, pCnf ); - Cnf_DataFree( pCnf ); - Aig_ManStop( pNew ); - // solve the targets - RetValue = Saig_BmcSolveTargets( p, nStart, &nOutsSolved ); + clk = clock(); +// pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 ); + pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 ); + Aig_ManStop( pAigTemp ); if ( fVerbose ) { - printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ", - Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts ); - ABC_PRT( "Time", clock() - clk2 ); + printf( "Time-frames after rewriting: Node = %6d. Lev = %5d. ", + Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); } - if ( RetValue != l_False ) - break; } - if ( RetValue == l_True ) + // create the SAT solver + clk = clock(); + pCnf = Cnf_Derive( pFrames, Aig_ManPoNum(pFrames) ); +//if ( s_fInterrupt ) +//return -1; + pSat = sat_solver_new(); + sat_solver_setnvars( pSat, pCnf->nVars ); + for ( i = 0; i < pCnf->nClauses; i++ ) { - assert( p->iFrameFail * Saig_ManPoNum(p->pAig) + p->iOutputFail + 1 == nOutsSolved ); - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", - p->iOutputFail, p->iFrameFail ); + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + assert( 0 ); } - else // if ( RetValue == l_False || RetValue == l_Undef ) - printf( "No output was asserted in %d frames. ", p->iFramePrev-1 ); - if ( fVerbOverwrite ) + if ( fVerbose ) { - ABC_PRTr( "Time", clock() - clk ); + printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); } - else + status = sat_solver_simplify(pSat); + if ( status == 0 ) { - ABC_PRT( "Time", clock() - clk ); + if ( fVerbose ) + { + printf( "The BMC problem is trivially UNSAT\n" ); + fflush( stdout ); + } } - if ( RetValue != l_True ) + else { - if ( p->iFrameLast >= p->nFramesMax ) - printf( "Reached limit on the number of timeframes (%d).\n", p->nFramesMax ); - else if ( p->pSat->stats.conflicts > p->nConfMaxAll ) - printf( "Reached global conflict limit (%d).\n", p->nConfMaxAll ); - else - printf( "Reached local conflict limit (%d).\n", p->nConfMaxOne ); + int clkPart = clock(); + Aig_ManForEachPo( pFrames, pObj, i ) + { +//if ( s_fInterrupt ) +//return -1; + Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); + if ( fVerbose ) + { + printf( "Solving output %2d of frame %3d ... \r", + i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); + } + clk = clock(); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) ) + { + printf( "Solved %2d outputs of frame %3d. ", + Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); + printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations ); + ABC_PRT( "T", clock() - clkPart ); + clkPart = clock(); + fflush( stdout ); + } + if ( status == l_False ) + { +/* + Lit = lit_neg( Lit ); + RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); + assert( RetValue ); + if ( pSat->qtail != pSat->qhead ) + { + RetValue = sat_solver_simplify(pSat); + assert( RetValue ); + } +*/ + } + else if ( status == l_True ) + { +// extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); + Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); + int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); + pModel[Aig_ManPiNum(pFrames)] = pObj->Id; + pAig->pSeqModel = (Abc_Cex_t *)Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); + ABC_FREE( pModel ); + Vec_IntFree( vCiIds ); + + if ( piFrame ) + *piFrame = i / Saig_ManPoNum(pAig); + RetValue = 0; + break; + } + else + { + if ( piFrame ) + *piFrame = i / Saig_ManPoNum(pAig); + RetValue = -1; + break; + } + } } - Saig_BmcManStop( p ); + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pFrames ); + return RetValue; } - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc2.c b/src/aig/saig/saigBmc2.c index 240168e6..c7129c67 100644 --- a/src/aig/saig/saigBmc2.c +++ b/src/aig/saig/saigBmc2.c @@ -21,67 +21,207 @@ #include "saig.h" #include "cnf.h" #include "satStore.h" +#include "ssw.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define AIG_VISITED ((Aig_Obj_t *)(ABC_PTRUINT_T)1) + +typedef struct Saig_Bmc_t_ Saig_Bmc_t; +struct Saig_Bmc_t_ +{ + // parameters + int nFramesMax; // the max number of timeframes to consider + int nNodesMax; // the max number of nodes to add + int nConfMaxOne; // the max number of conflicts at a target + int nConfMaxAll; // the max number of conflicts for all targets + int fVerbose; // enables verbose output + // AIG managers + Aig_Man_t * pAig; // the user's AIG manager + Aig_Man_t * pFrm; // Frames manager + Vec_Ptr_t * vVisited; // nodes visited in Frames + // node mapping + int nObjs; // the largest number of an AIG object + Vec_Ptr_t * vAig2Frm; // mapping of AIG nodees into Frames nodes +// Vec_Str_t * vAig2Frm2; // mapping of AIG nodees into Frames nodes + // SAT solver + sat_solver * pSat; // SAT solver + int nSatVars; // the number of used SAT variables + Vec_Int_t * vObj2Var; // mapping of frames objects in CNF variables + int nStitchVars; + // subproblems + Vec_Ptr_t * vTargets; // targets to be solved in this interval + int iFramePrev; // previous frame + int iFrameLast; // last frame + int iOutputLast; // last output + int iFrameFail; // failed frame + int iOutputFail; // failed output +}; + +static inline int Saig_BmcSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vObj2Var, pObj->Id ); } +static inline void Saig_BmcSetSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vObj2Var, pObj->Id, Num); } + +static inline Aig_Obj_t * Saig_BmcObjFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { return (Aig_Obj_t *)Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } +static inline void Saig_BmcObjSetFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); } + +static inline Aig_Obj_t * Saig_BmcObjChild0( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)); } +static inline Aig_Obj_t * Saig_BmcObjChild1( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +#define ABS_ZER 1 +#define ABS_ONE 2 +#define ABS_UND 3 + +static inline int Abs_ManSimInfoNot( int Value ) +{ + if ( Value == ABS_ZER ) + return ABS_ONE; + if ( Value == ABS_ONE ) + return ABS_ZER; + return ABS_UND; +} + +static inline int Abs_ManSimInfoAnd( int Value0, int Value1 ) +{ + if ( Value0 == ABS_ZER || Value1 == ABS_ZER ) + return ABS_ZER; + if ( Value0 == ABS_ONE && Value1 == ABS_ONE ) + return ABS_ONE; + return ABS_UND; +} + +static inline int Abs_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, iFrame ); + return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); +} + +static inline void Abs_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, iFrame ); + assert( Value >= ABS_ZER && Value <= ABS_UND ); + Value ^= Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); + pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); +} + /**Function************************************************************* - Synopsis [Create timeframes of the manager for BMC.] + Synopsis [Performs ternary simulation for one node.] - Description [The resulting manager is combinational. POs correspond to \ - the property outputs in each time-frame.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) +int Abs_ManExtendOneEval_rec( Vec_Ptr_t * vSimInfo, Aig_Man_t * p, Aig_Obj_t * pObj, int iFrame ) { - Aig_Man_t * pFrames; - Aig_Obj_t * pObj, * pObjLi, * pObjLo; - int i, f; - assert( Saig_ManRegNum(pAig) > 0 ); - pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); - // map the constant node - Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); - // create variables for register outputs - Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_ManConst0( pFrames ); - // add timeframes - for ( f = 0; f < nFrames; f++ ) + int Value0, Value1, Value; + Value = Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); + if ( Value ) + return Value; + if ( Aig_ObjIsPi(pObj) ) { - // create PI nodes for this frame - Saig_ManForEachPi( pAig, pObj, i ) - pObj->pData = Aig_ObjCreatePi( pFrames ); - // add internal nodes of this frame - Aig_ManForEachNode( pAig, pObj, i ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - // create POs for this frame - Saig_ManForEachPo( pAig, pObj, i ) - Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - if ( f == nFrames - 1 ) - break; - // save register inputs - Saig_ManForEachLi( pAig, pObj, i ) - pObj->pData = Aig_ObjChild0Copy(pObj); - // transfer to register outputs - Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - pObjLo->pData = pObjLi->pData; + assert( Saig_ObjIsLo(p, pObj) ); + Value = Abs_ManExtendOneEval_rec( vSimInfo, p, Saig_ObjLoToLi(p, pObj), iFrame-1 ); + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); + return Value; + } + Value0 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin0(pObj), iFrame ); + if ( Aig_ObjFaninC0(pObj) ) + Value0 = Abs_ManSimInfoNot( Value0 ); + if ( Aig_ObjIsPo(pObj) ) + { + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); + return Value0; } - Aig_ManCleanup( pFrames ); - return pFrames; + assert( Aig_ObjIsNode(pObj) ); + if ( Value0 == ABS_ZER ) + Value = ABS_ZER; + else + { + Value1 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin1(pObj), iFrame ); + if ( Aig_ObjFaninC1(pObj) ) + Value1 = Abs_ManSimInfoNot( Value1 ); + Value = Abs_ManSimInfoAnd( Value0, Value1 ); + } + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); + assert( Value ); + return Value; } /**Function************************************************************* - Synopsis [Returns the number of internal nodes that are not counted yet.] + Synopsis [Performs ternary simulation for one design.] + + Description [The returned array contains the result of ternary + simulation for all the frames where the output could be proved 0.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abs_ManTernarySimulate( Aig_Man_t * p, int nFramesMax, int fVerbose ) +{ + Vec_Ptr_t * vSimInfo; + Aig_Obj_t * pObj; + int i, f, nFramesLimit, nFrameWords; + int clk = clock(); + assert( Aig_ManRegNum(p) > 0 ); + // the maximum number of frames will be determined to use at most 200Mb of RAM + nFramesLimit = 1 + (200000000 * 4)/Aig_ManObjNum(p); + nFramesLimit = ABC_MIN( nFramesLimit, nFramesMax ); + nFrameWords = Aig_BitWordNum( 2 * Aig_ManObjNum(p) ); + // allocate simulation info + vSimInfo = Vec_PtrAlloc( nFramesLimit ); + for ( f = 0; f < nFramesLimit; f++ ) + { + Vec_PtrPush( vSimInfo, ABC_CALLOC(unsigned, nFrameWords) ); + if ( f == 0 ) + { + Saig_ManForEachLo( p, pObj, i ) + Abs_ManSimInfoSet( vSimInfo, pObj, 0, ABS_ZER ); + } + Abs_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, ABS_ONE ); + Saig_ManForEachPi( p, pObj, i ) + Abs_ManSimInfoSet( vSimInfo, pObj, f, ABS_UND ); + Saig_ManForEachPo( p, pObj, i ) + Abs_ManExtendOneEval_rec( vSimInfo, p, pObj, f ); + // check if simulation has derived at least one fail or unknown + Saig_ManForEachPo( p, pObj, i ) + if ( Abs_ManSimInfoGet(vSimInfo, pObj, f) != ABS_ZER ) + { + if ( fVerbose ) + { + printf( "Ternary sim found non-zero output in frame %d. Used %5.2f Mb. ", + f, 0.25 * (f+1) * Aig_ManObjNum(p) / (1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + return vSimInfo; + } + } + if ( fVerbose ) + { + printf( "Ternary sim proved all outputs in the first %d frames. Used %5.2f Mb. ", + nFramesLimit, 0.25 * nFramesLimit * Aig_ManObjNum(p) / (1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + return vSimInfo; +} + +/**Function************************************************************* + + Synopsis [Free the array of simulation info.] Description [] @@ -90,83 +230,444 @@ Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) SeeAlso [] ***********************************************************************/ -int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +void Abs_ManFreeAray( Vec_Ptr_t * p ) { - if ( !Aig_ObjIsNode(pObj) ) - return 0; - if ( Aig_ObjIsTravIdCurrent(p, pObj) ) - return 0; - Aig_ObjSetTravIdCurrent(p, pObj); - return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) + - Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) ); + void * pTemp; + int i; + Vec_PtrForEachEntry( void *, p, pTemp, i ) + ABC_FREE( pTemp ); + Vec_PtrFree( p ); } + /**Function************************************************************* - Synopsis [Create timeframes of the manager for BMC.] + Synopsis [Create manager.] - Description [The resulting manager is combinational. POs correspond to - the property outputs in each time-frame. - The unrolling is stopped as soon as the number of nodes in the frames - exceeds the given maximum size.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax ) +Saig_Bmc_t * Saig_BmcManStart( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose ) { - Aig_Man_t * pFrames; - Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo; - int i, f, Counter = 0; - assert( Saig_ManRegNum(pAig) > 0 ); - pFrames = Aig_ManStart( nSizeMax ); - Aig_ManIncrementTravId( pFrames ); - // map the constant node - Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); - // create variables for register outputs + Saig_Bmc_t * p; + Aig_Obj_t * pObj; + int i, Lit; +// assert( Aig_ManRegNum(pAig) > 0 ); + p = (Saig_Bmc_t *)ABC_ALLOC( char, sizeof(Saig_Bmc_t) ); + memset( p, 0, sizeof(Saig_Bmc_t) ); + // set parameters + p->nFramesMax = nFramesMax; + p->nNodesMax = nNodesMax; + p->nConfMaxOne = nConfMaxOne; + p->nConfMaxAll = nConfMaxAll; + p->fVerbose = fVerbose; + p->pAig = pAig; + p->nObjs = Aig_ManObjNumMax(pAig); + // create node and variable mappings + p->vAig2Frm = Vec_PtrAlloc( 0 ); + Vec_PtrFill( p->vAig2Frm, 5 * p->nObjs, NULL ); + p->vObj2Var = Vec_IntAlloc( 0 ); + Vec_IntFill( p->vObj2Var, 5 * p->nObjs, 0 ); + // start the AIG manager and map primary inputs + p->pFrm = Aig_ManStart( 5 * p->nObjs ); Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_ManConst0( pFrames ); - // add timeframes - Counter = 0; - for ( f = 0; f < nFrames; f++ ) + Saig_BmcObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrm) ); + // create SAT solver + p->nSatVars = 1; + p->pSat = sat_solver_new(); + sat_solver_setnvars( p->pSat, 2000 ); + Lit = toLit( p->nSatVars ); + sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + Saig_BmcSetSatNum( p, Aig_ManConst1(p->pFrm), p->nSatVars++ ); + // other data structures + p->vTargets = Vec_PtrAlloc( 0 ); + p->vVisited = Vec_PtrAlloc( 0 ); + p->iOutputFail = -1; + p->iFrameFail = -1; + return p; +} + +/**Function************************************************************* + + Synopsis [Delete manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcManStop( Saig_Bmc_t * p ) +{ +// Aig_Obj_t * pObj; +// int i, f, Counter = 0; +// int i, Counter = 0; +// for ( i = 0; i < p->vAig2Frm2->nSize; i++ ) +// Counter += (p->vAig2Frm2->pArray[i] != 0); +// for ( i = 0; i < p->vAig2Frm->nSize; i++ ) +// Counter += (p->vAig2Frm->pArray[i] != NULL); +// printf( "Objs = %d. Nodes = %d. Frames = %d. Used = %d. Non-empty = %d.\n", +// p->nObjs, Aig_ManNodeNum(p->pAig), p->iFrameLast, p->vAig2Frm->nSize, Counter ); + +/* + Aig_ManForEachObj( p->pAig, pObj, i ) { - // create PI nodes for this frame - Saig_ManForEachPi( pAig, pObj, i ) - pObj->pData = Aig_ObjCreatePi( pFrames ); - // add internal nodes of this frame - Aig_ManForEachNode( pAig, pObj, i ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - // create POs for this frame - Saig_ManForEachPo( pAig, pObj, i ) + int Last = -1; + for ( f = 0; f <= p->iFrameLast; f++ ) + if ( Saig_BmcObjFrame( p, pObj, f ) ) + Last = f; + if ( i % 50 == 0 ) + printf( "%d ", Last ); + } + printf( "\n" ); +*/ + + Aig_ManStop( p->pFrm ); + Vec_PtrFree( p->vAig2Frm ); +// Vec_StrFree( p->vAig2Frm2 ); + Vec_IntFree( p->vObj2Var ); + sat_solver_delete( p->pSat ); + Vec_PtrFree( p->vTargets ); + Vec_PtrFree( p->vVisited ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Explores the possibility of constructing the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) +{ + Aig_Obj_t * pRes, * p0, * p1, * pConst1 = Aig_ManConst1(p->pAig); + pRes = Saig_BmcObjFrame( p, pObj, i ); + if ( pRes != NULL ) + return pRes; + if ( Saig_ObjIsPi( p->pAig, pObj ) ) + pRes = AIG_VISITED; + else if ( Saig_ObjIsLo( p->pAig, pObj ) ) + pRes = Saig_BmcIntervalExplore_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 ); + else if ( Aig_ObjIsPo( pObj ) ) + { + pRes = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); + if ( pRes != AIG_VISITED ) + pRes = Saig_BmcObjChild0( p, pObj, i ); + } + else + { + p0 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); + if ( p0 != AIG_VISITED ) + p0 = Saig_BmcObjChild0( p, pObj, i ); + p1 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin1(pObj), i ); + if ( p1 != AIG_VISITED ) + p1 = Saig_BmcObjChild1( p, pObj, i ); + + if ( p0 == Aig_Not(p1) ) + pRes = Aig_ManConst0(p->pFrm); + else if ( Aig_Regular(p0) == pConst1 ) + pRes = (p0 == pConst1) ? p1 : Aig_ManConst0(p->pFrm); + else if ( Aig_Regular(p1) == pConst1 ) + pRes = (p1 == pConst1) ? p0 : Aig_ManConst0(p->pFrm); + else + pRes = AIG_VISITED; + + if ( pRes != AIG_VISITED && !Aig_ObjIsConst1(Aig_Regular(pRes)) ) + pRes = AIG_VISITED; + } + Saig_BmcObjSetFrame( p, pObj, i, pRes ); + return pRes; +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited ) +{ + Aig_Obj_t * pRes; + pRes = Saig_BmcObjFrame( p, pObj, i ); + if ( pRes != NULL ) + return pRes; + if ( Saig_ObjIsPi( p->pAig, pObj ) ) + pRes = Aig_ObjCreatePi(p->pFrm); + else if ( Saig_ObjIsLo( p->pAig, pObj ) ) + pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited ); + else if ( Aig_ObjIsPo( pObj ) ) + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); + pRes = Saig_BmcObjChild0( p, pObj, i ); + } + else + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); + if ( Saig_BmcObjChild0(p, pObj, i) == Aig_ManConst0(p->pFrm) ) + pRes = Aig_ManConst0(p->pFrm); + else + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited ); + pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) ); + } + } + assert( pRes != NULL ); + Saig_BmcObjSetFrame( p, pObj, i, pRes ); + Vec_PtrPush( vVisited, pObj ); + Vec_PtrPush( vVisited, (void *)(ABC_PTRINT_T)i ); + return pRes; +} + +/**Function************************************************************* + + Synopsis [Adds new AIG nodes to the frames.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcInterval( Saig_Bmc_t * p ) +{ + Aig_Obj_t * pTarget; + Aig_Obj_t * pObj, * pRes; + int i, iFrame, Counter; + int nNodes = Aig_ManObjNum( p->pFrm ); + Vec_PtrClear( p->vTargets ); + p->iFramePrev = p->iFrameLast; + for ( ; p->iFrameLast < p->nFramesMax; p->iFrameLast++, p->iOutputLast = 0 ) + { + if ( p->iOutputLast == 0 ) { - pObjPo = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) ); + Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) ); } - if ( Counter >= nSizeMax ) + for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ ) { - Aig_ManCleanup( pFrames ); - return pFrames; + if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax ) + return; +// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast ); + Vec_PtrClear( p->vVisited ); + pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited ); + Vec_PtrPush( p->vTargets, pTarget ); + Aig_ObjCreatePo( p->pFrm, pTarget ); + Aig_ManCleanup( p->pFrm ); + // check if the node is gone + Counter = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) + { + iFrame = (int)(ABC_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ ); + pRes = Saig_BmcObjFrame( p, pObj, iFrame ); + if ( Aig_ObjIsNone( Aig_Regular(pRes) ) ) + { + Saig_BmcObjSetFrame( p, pObj, iFrame, NULL ); + Counter++; + } + } +// printf( "%d ", Counter ); } - if ( f == nFrames - 1 ) + } +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalToAig_rec( Saig_Bmc_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObj ) +{ + if ( pObj->pData ) + return (Aig_Obj_t *)pObj->pData; + Vec_PtrPush( p->vVisited, pObj ); + if ( Saig_BmcSatNum(p, pObj) || Aig_ObjIsPi(pObj) ) + { + p->nStitchVars += !Aig_ObjIsPi(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjCreatePi(pNew)); + } + Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin0(pObj) ); + Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin1(pObj) ); + assert( pObj->pData == NULL ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); +} + +/**Function************************************************************* + + Synopsis [Creates AIG of the newly added nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_BmcIntervalToAig( Saig_Bmc_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj, * pObjNew; + int i; + Aig_ManForEachObj( p->pFrm, pObj, i ) + assert( pObj->pData == NULL ); + + pNew = Aig_ManStart( p->nNodesMax ); + Aig_ManConst1(p->pFrm)->pData = Aig_ManConst1(pNew); + Vec_PtrClear( p->vVisited ); + Vec_PtrPush( p->vVisited, Aig_ManConst1(p->pFrm) ); + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) + { +// assert( !Aig_ObjIsConst1(Aig_Regular(pObj)) ); + pObjNew = Saig_BmcIntervalToAig_rec( p, pNew, Aig_Regular(pObj) ); + assert( !Aig_IsComplement(pObjNew) ); + Aig_ObjCreatePo( pNew, pObjNew ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Derives CNF for the newly added nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcLoadCnf( Saig_Bmc_t * p, Cnf_Dat_t * pCnf ) +{ + Aig_Obj_t * pObj, * pObjNew; + int i, Lits[2], VarNumOld, VarNumNew; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) + { + // get the new variable of this node + pObjNew = (Aig_Obj_t *)pObj->pData; + pObj->pData = NULL; + VarNumNew = pCnf->pVarNums[ pObjNew->Id ]; + if ( VarNumNew == -1 ) + continue; + // get the old variable of this node + VarNumOld = Saig_BmcSatNum( p, pObj ); + if ( VarNumOld == 0 ) + { + Saig_BmcSetSatNum( p, pObj, VarNumNew ); + continue; + } + // add clauses connecting existing variables + Lits[0] = toLitCond( VarNumOld, 0 ); + Lits[1] = toLitCond( VarNumNew, 1 ); + if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( VarNumOld, 1 ); + Lits[1] = toLitCond( VarNumNew, 0 ); + if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + // add CNF to the SAT solver + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) break; - // save register inputs - Saig_ManForEachLi( pAig, pObj, i ) - pObj->pData = Aig_ObjChild0Copy(pObj); - // transfer to register outputs - Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - pObjLo->pData = pObjLi->pData; + if ( i < pCnf->nClauses ) + printf( "SAT solver became UNSAT after adding clauses.\n" ); +} + +/**Function************************************************************* + + Synopsis [Solves targets with the given resource limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcDeriveFailed( Saig_Bmc_t * p, int iTargetFail ) +{ + int k; + p->iOutputFail = p->iOutputLast; + p->iFrameFail = p->iFrameLast; + for ( k = Vec_PtrSize(p->vTargets); k > iTargetFail; k-- ) + { + if ( p->iOutputFail == 0 ) + { + p->iOutputFail = Saig_ManPoNum(p->pAig); + p->iFrameFail--; + } + p->iOutputFail--; } - Aig_ManCleanup( pFrames ); - return pFrames; } -#include "utilMem.h" +/**Function************************************************************* + + Synopsis [Solves targets with the given resource limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) +{ + Abc_Cex_t * pCex; + Aig_Obj_t * pObj, * pObjFrm; + int i, f, iVarNum; + // start the counter-example + pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); + pCex->iFrame = p->iFrameFail; + pCex->iPo = p->iOutputFail; + // copy the bit data + for ( f = 0; f <= p->iFrameFail; f++ ) + { + Saig_ManForEachPi( p->pAig, pObj, i ) + { + pObjFrm = Saig_BmcObjFrame( p, pObj, f ); + if ( pObjFrm == NULL ) + continue; + iVarNum = Saig_BmcSatNum( p, pObjFrm ); + if ( iVarNum == 0 ) + continue; + if ( sat_solver_var_value( p->pSat, iVarNum ) ) + Aig_InfoSetBit( pCex->pData, pCex->nRegs + Saig_ManPiNum(p->pAig) * f + i ); + } + } + // verify the counter example + if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) + { + printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" ); + Ssw_SmlFreeCounterExample( pCex ); + pCex = NULL; + } + return pCex; +} /**Function************************************************************* - Synopsis [Performs BMC for the given AIG.] + Synopsis [Solves targets with the given resource limit.] Description [] @@ -175,154 +676,178 @@ Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax SeeAlso [] ***********************************************************************/ -int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ) +int Saig_BmcSolveTargets( Saig_Bmc_t * p, int nStart, int * pnOutsSolved ) { - extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ); - sat_solver * pSat; - Cnf_Dat_t * pCnf; - Aig_Man_t * pFrames, * pAigTemp; Aig_Obj_t * pObj; - int status, clk, Lit, i, RetValue = 1; - - // derive the timeframes - clk = clock(); - if ( nCofFanLit ) + int i, VarNum, Lit, RetValue; + assert( Vec_PtrSize(p->vTargets) > 0 ); + if ( p->pSat->qtail != p->pSat->qhead ) { - pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit ); - if ( pFrames == NULL ) - return -1; + RetValue = sat_solver_simplify(p->pSat); + assert( RetValue != 0 ); } - else if ( nSizeMax > 0 ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) { - pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax ); - nFrames = Aig_ManPoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManPoNum(pFrames) % Saig_ManPoNum(pAig)) > 0); + if ( ((*pnOutsSolved)++ / Saig_ManPoNum(p->pAig)) < nStart ) + continue; + if ( p->nConfMaxAll && p->pSat->stats.conflicts > p->nConfMaxAll ) + return l_Undef; + VarNum = Saig_BmcSatNum( p, Aig_Regular(pObj) ); + Lit = toLitCond( VarNum, Aig_IsComplement(pObj) ); + RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)p->nConfMaxOne, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_False ) // unsat + continue; + if ( RetValue == l_Undef ) // undecided + return l_Undef; + // generate counter-example + Saig_BmcDeriveFailed( p, i ); + p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p ); + + { +// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex ); +// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel ); + } + return l_True; } - else - pFrames = Saig_ManFramesBmc( pAig, nFrames ); - if ( piFrame ) - *piFrame = nFrames; + return l_False; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcAddTargetsAsPos( Saig_Bmc_t * p ) +{ + Aig_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) + Aig_ObjCreatePo( p->pFrm, pObj ); + Aig_ManPrintStats( p->pFrm ); + Aig_ManCleanup( p->pFrm ); + Aig_ManPrintStats( p->pFrm ); +} + +/**Function************************************************************* + + Synopsis [Performs BMC with the given parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ) +{ + Saig_Bmc_t * p; + Aig_Man_t * pNew; + Cnf_Dat_t * pCnf; + int nOutsSolved = 0; + int Iter, RetValue, clk = clock(), clk2, clkTotal = clock(); + int Status = -1; +/* + Vec_Ptr_t * vSimInfo; + vSimInfo = Abs_ManTernarySimulate( pAig, nFramesMax, fVerbose ); + Abs_ManFreeAray( vSimInfo ); +*/ + p = Saig_BmcManStart( pAig, nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll, fVerbose ); if ( fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) ); - printf( "Time-frames (%d): PI/PO = %d/%d. Node = %6d. Lev = %5d. ", - nFrames, Aig_ManPiNum(pFrames), Aig_ManPoNum(pFrames), - Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); - } - // rewrite the timeframes - if ( fRewrite ) + printf( "Params: FramesMax = %d. NodesDelta = %d. ConfMaxOne = %d. ConfMaxAll = %d.\n", + nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll ); + } + + for ( Iter = 0; ; Iter++ ) { - clk = clock(); -// pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 ); - pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 ); - Aig_ManStop( pAigTemp ); + clk2 = clock(); + // add new logic interval to frames + Saig_BmcInterval( p ); +// Saig_BmcAddTargetsAsPos( p ); + if ( Vec_PtrSize(p->vTargets) == 0 ) + break; + // convert logic slice into new AIG + pNew = Saig_BmcIntervalToAig( p ); +//printf( "StitchVars = %d.\n", p->nStitchVars ); + // derive CNF for the new AIG + pCnf = Cnf_Derive( pNew, Aig_ManPoNum(pNew) ); + Cnf_DataLift( pCnf, p->nSatVars ); + p->nSatVars += pCnf->nVars; + // add this CNF to the solver + Saig_BmcLoadCnf( p, pCnf ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pNew ); + // solve the targets + RetValue = Saig_BmcSolveTargets( p, nStart, &nOutsSolved ); if ( fVerbose ) { - printf( "Time-frames after rewriting: Node = %6d. Lev = %5d. ", - Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); + printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ", + Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts ); + ABC_PRT( "Time", clock() - clk2 ); + } + if ( RetValue != l_False ) + break; + // check the timeout + if ( nTimeOut && ((float)nTimeOut <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", nTimeOut ); + Saig_BmcManStop( p ); + if ( piFrames ) + *piFrames = p->iFrameLast-1; + return Status; } } - // create the SAT solver - clk = clock(); - pCnf = Cnf_Derive( pFrames, Aig_ManPoNum(pFrames) ); -//if ( s_fInterrupt ) -//return -1; - pSat = sat_solver_new(); - sat_solver_setnvars( pSat, pCnf->nVars ); - for ( i = 0; i < pCnf->nClauses; i++ ) + if ( RetValue == l_True ) { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - assert( 0 ); + assert( p->iFrameFail * Saig_ManPoNum(p->pAig) + p->iOutputFail + 1 == nOutsSolved ); + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", + p->iOutputFail, p->iFrameFail ); + Status = 0; + if ( piFrames ) + *piFrames = p->iFrameFail; } - if ( fVerbose ) + else // if ( RetValue == l_False || RetValue == l_Undef ) { - printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); + printf( "No output was asserted in %d frames. ", p->iFramePrev-1 ); + if ( piFrames ) + *piFrames = p->iFramePrev-1; } - status = sat_solver_simplify(pSat); - if ( status == 0 ) + if ( fVerbOverwrite ) { - if ( fVerbose ) - { - printf( "The BMC problem is trivially UNSAT\n" ); - fflush( stdout ); - } + ABC_PRTr( "Time", clock() - clk ); } else { - int clkPart = clock(); - Aig_ManForEachPo( pFrames, pObj, i ) - { -//if ( s_fInterrupt ) -//return -1; - Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); - if ( fVerbose ) - { - printf( "Solving output %2d of frame %3d ... \r", - i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); - } - clk = clock(); - status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) ) - { - printf( "Solved %2d outputs of frame %3d. ", - Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); - printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations ); - ABC_PRT( "T", clock() - clkPart ); - clkPart = clock(); - fflush( stdout ); - } - if ( status == l_False ) - { -/* - Lit = lit_neg( Lit ); - RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); - assert( RetValue ); - if ( pSat->qtail != pSat->qhead ) - { - RetValue = sat_solver_simplify(pSat); - assert( RetValue ); - } -*/ - } - else if ( status == l_True ) - { - extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); - Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); - int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); - pModel[Aig_ManPiNum(pFrames)] = pObj->Id; - pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); - ABC_FREE( pModel ); - Vec_IntFree( vCiIds ); - -// if ( piFrame ) -// *piFrame = i / Saig_ManPoNum(pAig); - RetValue = 0; - break; - } - else - { - if ( piFrame ) - *piFrame = i / Saig_ManPoNum(pAig); - RetValue = -1; - break; - } - } + ABC_PRT( "Time", clock() - clk ); } - sat_solver_delete( pSat ); - Cnf_DataFree( pCnf ); - Aig_ManStop( pFrames ); - return RetValue; + if ( RetValue != l_True ) + { + if ( p->iFrameLast >= p->nFramesMax ) + printf( "Reached limit on the number of timeframes (%d).\n", p->nFramesMax ); + else if ( p->pSat->stats.conflicts > p->nConfMaxAll ) + printf( "Reached global conflict limit (%d).\n", p->nConfMaxAll ); + else + printf( "Reached local conflict limit (%d).\n", p->nConfMaxOne ); + } + Saig_BmcManStop( p ); + return Status; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc3.c b/src/aig/saig/saigBmc3.c new file mode 100644 index 00000000..a75297f7 --- /dev/null +++ b/src/aig/saig/saigBmc3.c @@ -0,0 +1,1227 @@ +/**CFile**************************************************************** + + FileName [saigBmc3.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Simple BMC package.] + + Author [Alan Mishchenko in collaboration with Niklas Een.] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigBmc3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "fra.h" +#include "cnf.h" +#include "satStore.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_ManBmc_t_ Gia_ManBmc_t; +struct Gia_ManBmc_t_ +{ + // input/output data + Saig_ParBmc_t * pPars; // parameters + Aig_Man_t * pAig; // user AIG + Vec_Ptr_t * vCexes; // counter-examples + // intermediate data + Vec_Int_t * vMapping; // mapping + Vec_Vec_t * vSects; // sections + Vec_Int_t * vId2Num; // number of each node + Vec_Int_t * vVisited; // visited nodes + // SAT variables + Vec_Int_t * vPiVars; // SAT vars for the PIs + Vec_Ptr_t * vId2Var; // SAT vars for each object + // SAT solver + sat_solver * pSat; // SAT solver + int nSatVars; // SAT variables + int nObjNums; // SAT objects + int nBufNum; // the number of simple nodes + int nDupNum; // the number of simple nodes + char * pSopSizes, ** pSops; // CNF representation +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SAIG_TER_ZER 1 +#define SAIG_TER_ONE 2 +#define SAIG_TER_UND 3 + +static inline int Saig_ManBmcSimInfoNot( int Value ) +{ + if ( Value == SAIG_TER_ZER ) + return SAIG_TER_ONE; + if ( Value == SAIG_TER_ONE ) + return SAIG_TER_ZER; + return SAIG_TER_UND; +} + +static inline int Saig_ManBmcSimInfoAnd( int Value0, int Value1 ) +{ + if ( Value0 == SAIG_TER_ZER || Value1 == SAIG_TER_ZER ) + return SAIG_TER_ZER; + if ( Value0 == SAIG_TER_ONE && Value1 == SAIG_TER_ONE ) + return SAIG_TER_ONE; + return SAIG_TER_UND; +} + +static inline int Saig_ManBmcSimInfoGet( unsigned * pInfo, Aig_Obj_t * pObj ) +{ + return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); +} + +static inline void Saig_ManBmcSimInfoSet( unsigned * pInfo, Aig_Obj_t * pObj, int Value ) +{ + assert( Value >= SAIG_TER_ZER && Value <= SAIG_TER_UND ); + Value ^= Saig_ManBmcSimInfoGet( pInfo, pObj ); + pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); +} + +/**Function************************************************************* + + Synopsis [Returns the number of LIs with binary ternary info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcTerSimCount01( Aig_Man_t * p, unsigned * pInfo ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + if ( pInfo == NULL ) + return Saig_ManRegNum(p); + Saig_ManForEachLi( p, pObj, i ) + if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) ) + Counter += (Saig_ManBmcSimInfoGet(pInfo, pObj) != SAIG_TER_UND); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs ternary simulation of one frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Saig_ManBmcTerSimOne( Aig_Man_t * p, unsigned * pPrev ) +{ + Aig_Obj_t * pObj, * pObjLi; + unsigned * pInfo; + int i, Val0, Val1; + pInfo = ABC_CALLOC( unsigned, Aig_BitWordNum(2 * Aig_ManObjNumMax(p)) ); + Saig_ManBmcSimInfoSet( pInfo, Aig_ManConst1(p), SAIG_TER_ONE ); + Saig_ManForEachPi( p, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, SAIG_TER_UND ); + if ( pPrev == NULL ) + { + Saig_ManForEachLo( p, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, SAIG_TER_ZER ); + } + else + { + Saig_ManForEachLiLo( p, pObjLi, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, Saig_ManBmcSimInfoGet(pPrev, pObjLi) ); + } + Aig_ManForEachNode( p, pObj, i ) + { + Val0 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin0(pObj) ); + Val1 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin1(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + Val0 = Saig_ManBmcSimInfoNot( Val0 ); + if ( Aig_ObjFaninC1(pObj) ) + Val1 = Saig_ManBmcSimInfoNot( Val1 ); + Saig_ManBmcSimInfoSet( pInfo, pObj, Saig_ManBmcSimInfoAnd(Val0, Val1) ); + } + Aig_ManForEachPo( p, pObj, i ) + { + Val0 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin0(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + Val0 = Saig_ManBmcSimInfoNot( Val0 ); + Saig_ManBmcSimInfoSet( pInfo, pObj, Val0 ); + } + return pInfo; +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes and PIs in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcTerSim( Aig_Man_t * p ) +{ + Vec_Ptr_t * vInfos; + unsigned * pInfo = NULL; + int i, TerPrev = ABC_INFINITY, TerCur, CountIncrease = 0; + vInfos = Vec_PtrAlloc( 100 ); + for ( i = 0; i < 1000 && CountIncrease < 5 && TerPrev > 0; i++ ) + { + TerCur = Saig_ManBmcTerSimCount01( p, pInfo ); + if ( TerCur >= TerPrev ) + CountIncrease++; + TerPrev = TerCur; + pInfo = Saig_ManBmcTerSimOne( p, pInfo ); + Vec_PtrPush( vInfos, pInfo ); + } + return vInfos; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcTerSimTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vInfos; + unsigned * pInfo; + int i; + vInfos = Saig_ManBmcTerSim( p ); + Vec_PtrForEachEntry( unsigned *, vInfos, pInfo, i ) + printf( "%d=%d ", i, Saig_ManBmcTerSimCount01(p, pInfo) ); + printf( "\n" ); + Vec_PtrFreeFree( vInfos ); +} + + + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcDfs_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Aig_ObjIsNode(pObj) ) + { + Saig_ManBmcDfs_rec( p, Aig_ObjFanin0(pObj), vNodes ); + Saig_ManBmcDfs_rec( p, Aig_ObjFanin1(pObj), vNodes ); + } + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes and PIs in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcDfsNodes( Aig_Man_t * p, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + vNodes = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i ) + Saig_ManBmcDfs_rec( p, Aig_ObjFanin0(pObj), vNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Saig_ManBmcSections( Aig_Man_t * p ) +{ + Vec_Ptr_t * vSects, * vRoots, * vCone; + Aig_Obj_t * pObj, * pObjPo; + int i; + Aig_ManIncrementTravId( p ); + Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) ); + // start the roots + vRoots = Vec_PtrAlloc( 1000 ); + Saig_ManForEachPo( p, pObjPo, i ) + { + Aig_ObjSetTravIdCurrent( p, pObjPo ); + Vec_PtrPush( vRoots, pObjPo ); + } + // compute the cones + vSects = Vec_PtrAlloc( 20 ); + while ( Vec_PtrSize(vRoots) > 0 ) + { + vCone = Saig_ManBmcDfsNodes( p, vRoots ); + Vec_PtrPush( vSects, vCone ); + // get the next set of roots + Vec_PtrClear( vRoots ); + Vec_PtrForEachEntry( Aig_Obj_t *, vCone, pObj, i ) + { + if ( !Saig_ObjIsLo(p, pObj) ) + continue; + pObjPo = Saig_ObjLoToLi( p, pObj ); + if ( Aig_ObjIsTravIdCurrent(p, pObjPo) ) + continue; + Aig_ObjSetTravIdCurrent( p, pObjPo ); + Vec_PtrPush( vRoots, pObjPo ); + } + } + Vec_PtrFree( vRoots ); + return (Vec_Vec_t *)vSects; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSectionsTest( Aig_Man_t * p ) +{ + Vec_Vec_t * vSects; + Vec_Ptr_t * vOne; + int i; + vSects = Saig_ManBmcSections( p ); + Vec_VecForEachLevel( vSects, vOne, i ) + printf( "%d=%d ", i, Vec_PtrSize(vOne) ); + printf( "\n" ); + Vec_VecFree( vSects ); +} + + + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSupergate_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ) // || (Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPushUnique( vSuper, Aig_Regular(pObj) ); + return; + } + // go through the branches + Saig_ManBmcSupergate_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_ManBmcSupergate_rec( Aig_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collect the topmost supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcSupergate( Aig_Man_t * p, int iPo ) +{ + Vec_Ptr_t * vSuper; + Aig_Obj_t * pObj; + vSuper = Vec_PtrAlloc( 10 ); + pObj = Aig_ManPo( p, iPo ); + pObj = Aig_ObjChild0( pObj ); + if ( !Aig_IsComplement(pObj) ) + { + Vec_PtrPush( vSuper, pObj ); + return vSuper; + } + pObj = Aig_Regular( pObj ); + if ( !Aig_ObjIsNode(pObj) ) + { + Vec_PtrPush( vSuper, pObj ); + return vSuper; + } + Saig_ManBmcSupergate_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_ManBmcSupergate_rec( Aig_ObjChild1(pObj), vSuper ); + return vSuper; +} + +/**Function************************************************************* + + Synopsis [Returns the number of nodes with ref counter more than 1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCountRefed( Aig_Man_t * p, Vec_Ptr_t * vSuper ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + { + assert( !Aig_IsComplement(pObj) ); + Counter += (Aig_ObjRefs(pObj) > 1); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSupergateTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vSuper; + Aig_Obj_t * pObj; + int i; + printf( "Supergates: " ); + Saig_ManForEachPo( p, pObj, i ) + { + vSuper = Saig_ManBmcSupergate( p, i ); + printf( "%d=%d(%d) ", i, Vec_PtrSize(vSuper), Saig_ManBmcCountRefed(p, vSuper) ); + Vec_PtrFree( vSuper ); + } + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcWriteBlif( Aig_Man_t * p, Vec_Int_t * vMapping, char * pFileName ) +{ + FILE * pFile; + char * pSopSizes, ** pSops; + Aig_Obj_t * pObj; + char Vals[4]; + int i, k, b, iFan, iTruth, * pData; + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + printf( "Cannot open file %s\n", pFileName ); + return; + } + fprintf( pFile, ".model test\n" ); + fprintf( pFile, ".inputs" ); + Aig_ManForEachPi( p, pObj, i ) + fprintf( pFile, " n%d", Aig_ObjId(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs" ); + Aig_ManForEachPo( p, pObj, i ) + fprintf( pFile, " n%d", Aig_ObjId(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".names" ); + fprintf( pFile, " n%d\n", Aig_ObjId(Aig_ManConst1(p)) ); + fprintf( pFile, " 1\n" ); + + Cnf_ReadMsops( &pSopSizes, &pSops ); + Aig_ManForEachNode( p, pObj, i ) + { + if ( Vec_IntEntry(vMapping, i) == 0 ) + continue; + pData = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, i) ); + fprintf( pFile, ".names" ); + for ( iFan = 0; iFan < 4; iFan++ ) + if ( pData[iFan+1] >= 0 ) + fprintf( pFile, " n%d", pData[iFan+1] ); + else + break; + fprintf( pFile, " n%d\n", i ); + // write SOP + iTruth = pData[0] & 0xffff; + for ( k = 0; k < pSopSizes[iTruth]; k++ ) + { + int Lit = pSops[iTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( Lit % 3 == 0 ) + Vals[b] = '0'; + else if ( Lit % 3 == 1 ) + Vals[b] = '1'; + else + Vals[b] = '-'; + Lit = Lit / 3; + } + for ( b = 0; b < iFan; b++ ) + fprintf( pFile, "%c", Vals[b] ); + fprintf( pFile, " 1\n" ); + } + } + free( pSopSizes ); + free( pSops[1] ); + free( pSops ); + + Aig_ManForEachPo( p, pObj, i ) + { + fprintf( pFile, ".names" ); + fprintf( pFile, " n%d", Aig_ObjId(Aig_ObjFanin0(pObj)) ); + fprintf( pFile, " n%d\n", Aig_ObjId(pObj) ); + fprintf( pFile, "%d 1\n", !Aig_ObjFaninC0(pObj) ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcMappingTest( Aig_Man_t * p ) +{ + Vec_Int_t * vMapping; + vMapping = Cnf_DeriveMappingArray( p ); + Saig_ManBmcWriteBlif( p, vMapping, "test.blif" ); + Vec_IntFree( vMapping ); +} + + + + + + + +/**Function************************************************************* + + Synopsis [Create manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManBmc_t * Saig_Bmc3ManStart( Aig_Man_t * pAig ) +{ + Gia_ManBmc_t * p; + Aig_Obj_t * pObj; + int i; + assert( Aig_ManRegNum(pAig) > 0 ); + p = ABC_CALLOC( Gia_ManBmc_t, 1 ); + p->pAig = pAig; + // create mapping + p->vMapping = Cnf_DeriveMappingArray( pAig ); + // create sections + p->vSects = Saig_ManBmcSections( pAig ); + // map object IDs into their numbers and section numbers + p->nObjNums = 0; + p->vId2Num = Vec_IntStartFull( Aig_ManObjNumMax(pAig) ); + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(Aig_ManConst1(pAig)), p->nObjNums++ ); + Aig_ManForEachPi( pAig, pObj, i ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + Aig_ManForEachNode( pAig, pObj, i ) + if ( Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) > 0 ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + Aig_ManForEachPo( pAig, pObj, i ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + p->vPiVars = Vec_IntAlloc( 1000 ); + p->vId2Var = Vec_PtrAlloc( 100 ); + p->vVisited = Vec_IntAlloc( 1000 ); + // create solver + p->nSatVars = 1; + p->pSat = sat_solver_new(); + sat_solver_setnvars( p->pSat, 1000 ); + Cnf_ReadMsops( &p->pSopSizes, &p->pSops ); + return p; +} + +/**Function************************************************************* + + Synopsis [Delete manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_Bmc3ManStop( Gia_ManBmc_t * p ) +{ + if ( p->vCexes ) + { + assert( p->pAig->pSeqModelVec == NULL ); + p->pAig->pSeqModelVec = p->vCexes; + p->vCexes = NULL; + } +// Vec_PtrFreeFree( p->vCexes ); + Vec_IntFree( p->vMapping ); + Vec_VecFree( p->vSects ); + Vec_IntFree( p->vId2Num ); + Vec_IntFree( p->vPiVars ); + Vec_IntFree( p->vVisited ); + Vec_VecFree( (Vec_Vec_t *)p->vId2Var ); + sat_solver_delete( p->pSat ); + free( p->pSopSizes ); + free( p->pSops[1] ); + free( p->pSops ); + free( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int * Saig_ManBmcMapping( Gia_ManBmc_t * p, Aig_Obj_t * pObj ) +{ + if ( Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) == 0 ) + return NULL; + return Vec_IntEntryP( p->vMapping, Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcLiteral( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame ) +{ + Vec_Int_t * vFrame; + int ObjNum; + assert( !Aig_ObjIsNode(pObj) || Saig_ManBmcMapping(p, pObj) ); + ObjNum = Vec_IntEntry( p->vId2Num, Aig_ObjId(pObj) ); + assert( ObjNum >= 0 ); + vFrame = (Vec_Int_t *)Vec_PtrEntry( p->vId2Var, iFrame ); + assert( vFrame != NULL ); + return Vec_IntEntry( vFrame, ObjNum ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcSetLiteral( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame, int iLit ) +{ + Vec_Int_t * vFrame; + int ObjNum; + assert( !Aig_ObjIsNode(pObj) || Saig_ManBmcMapping(p, pObj) ); + ObjNum = Vec_IntEntry( p->vId2Num, Aig_ObjId(pObj) ); + vFrame = (Vec_Int_t *)Vec_PtrEntry( p->vId2Var, iFrame ); + Vec_IntWriteEntry( vFrame, ObjNum, iLit ); + if ( iLit == ABC_INFINITY || iLit == ABC_INFINITY+1 ) + { + Vec_IntPush( p->vVisited, Aig_ObjId(pObj) ); + Vec_IntPush( p->vVisited, iFrame ); + } + else if ( iLit != ~0 && Saig_ObjIsPi(p->pAig, pObj) ) // save PI SAT var num + Vec_IntWriteEntry( p->vPiVars, iFrame*Saig_ManPiNum(p->pAig)+Aig_ObjPioNum(pObj), lit_var(iLit) ); + return iLit; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcCof0( int t, int v ) +{ + static int s_Truth[4] = { 0xAAAA, 0xCCCC, 0xF0F0, 0xFF00 }; + return 0xffff & ((t & ~s_Truth[v]) | ((t & ~s_Truth[v]) << (1<> (1<nFanins, pVars, pLits ); + } + + +int Cnf_IsopWriteCube( int Cube, int nVars, int * pVars, int * pLiterals ) +{ + int nLits = nVars, b; + for ( b = 0; b < nVars; b++ ) + { + if ( (Cube & 3) == 1 ) // value 0 --> write positive literal + *pLiterals++ = 2 * pVars[b]; + else if ( (Cube & 3) == 2 ) // value 1 --> write negative literal + *pLiterals++ = 2 * pVars[b] + 1; + else + nLits--; + Cube >>= 2; + } + return nLits; +} + + iTruth = pData[0] & 0xffff; + for ( k = 0; k < pSopSizes[iTruth]; k++ ) + { + int Lit = pSops[iTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( Lit % 3 == 0 ) + Vals[b] = '0'; + else if ( Lit % 3 == 1 ) + Vals[b] = '1'; + else + Vals[b] = '-'; + Lit = Lit / 3; + } + for ( b = 0; b < iFan; b++ ) + fprintf( pFile, "%c", Vals[b] ); + fprintf( pFile, " 1\n" ); + } +*/ + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Saig_ManBmcAddClauses( Gia_ManBmc_t * p, int uTruth, int Lits[], int iLitOut ) +{ + int i, k, b, CutLit, nClaLits, ClaLits[5]; + assert( uTruth > 0 && uTruth < 0xffff ); + // write positive/negative polarity + 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; + CutLit = p->pSops[uTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( CutLit % 3 == 0 ) // value 0 --> write positive literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = Lits[b]; + } + else if ( CutLit % 3 == 1 ) // value 1 --> write negative literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = lit_neg(Lits[b]); + } + CutLit = CutLit / 3; + } + +// for ( b = 0; b < nClaLits; b++ ) +// printf( "%d ", ClaLits[b] ); +// printf( "\n" ); + + if ( !sat_solver_addclause( p->pSat, ClaLits, ClaLits+nClaLits ) ) + assert( 0 ); + } + } +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCreateCnf_rec( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame, int fAddClauses ) +{ + int * pMapping, i, iLit, Lits[4], uTruth; + iLit = Saig_ManBmcLiteral( p, pObj, iFrame ); + if ( iLit != ~0 ) + return iLit; + assert( iFrame >= 0 ); + if ( Aig_ObjIsPi(pObj) ) + { + if ( Saig_ObjIsPi(p->pAig, pObj) ) + iLit = fAddClauses ? toLit( p->nSatVars++ ) : ABC_INFINITY; + else + iLit = Saig_ManBmcCreateCnf_rec( p, Saig_ObjLoToLi(p->pAig, pObj), iFrame-1, fAddClauses ); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + if ( Aig_ObjIsPo(pObj) ) + { + iLit = Saig_ManBmcCreateCnf_rec( p, Aig_ObjFanin0(pObj), iFrame, fAddClauses ); + if ( Aig_ObjFaninC0(pObj) ) + iLit = lit_neg(iLit); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + assert( Aig_ObjIsNode(pObj) ); + pMapping = Saig_ManBmcMapping( p, pObj ); + for ( i = 0; i < 4; i++ ) + if ( pMapping[i+1] == -1 ) + Lits[i] = -1; + else + Lits[i] = Saig_ManBmcCreateCnf_rec( p, Aig_ManObj(p->pAig, pMapping[i+1]), iFrame, fAddClauses ); + // derive new truth table +//uTruth = 0xffff & (unsigned)pMapping[0]; +//printf( "Truth : " ); +//Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); + uTruth = Saig_ManBmcDeriveTruth( 0xffff & (unsigned)pMapping[0], Lits ); + if ( uTruth == 0 || uTruth == 0xffff ) + { + iLit = (uTruth == 0xffff); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + // create CNF + if ( fAddClauses ) + { + iLit = toLit( p->nSatVars++ ); + Saig_ManBmcAddClauses( p, uTruth, Lits, iLit ); + + if ( uTruth == 0xAAAA || (0xffff & ~uTruth) == 0xAAAA || + uTruth == 0xCCCC || (0xffff & ~uTruth) == 0xCCCC || + uTruth == 0xF0F0 || (0xffff & ~uTruth) == 0xF0F0 || + uTruth == 0xFF00 || (0xffff & ~uTruth) == 0xFF00 ) + p->nBufNum++; + + if ( (Lits[0] > 1 && (Lits[0] == Lits[1] || Lits[0] == Lits[2] || Lits[0] == Lits[3])) || + (Lits[1] > 1 && (Lits[1] == Lits[2] || Lits[1] == Lits[2])) || + (Lits[2] > 1 && (Lits[2] == Lits[3])) ) + p->nDupNum++; + + } + else + { + iLit = ABC_INFINITY; + } + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCreateCnf( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame ) +{ + int i, iLit, Entry, iFrameOld, Value; + Vec_IntClear( p->vVisited ); + iLit = Saig_ManBmcCreateCnf_rec( p, pObj, iFrame, 0 ); + Vec_IntForEachEntry( p->vVisited, Entry, i ) + { + iFrameOld = Vec_IntEntry( p->vVisited, ++i ); + Value = Saig_ManBmcLiteral( p, Aig_ManObj(p->pAig, Entry), iFrameOld ); +// assert( Value == 0 || Value == 1 || Value == ABC_INFINITY || Value == ABC_INFINITY+1 ); + assert( Value == ABC_INFINITY || Value == ABC_INFINITY+1 ); + if ( !(Value == ABC_INFINITY || Value == ABC_INFINITY+1) ) + printf( "Internal error!\n" ); +// if ( Value == 0 || Value == 1 ) +// continue; + Saig_ManBmcSetLiteral( p, Aig_ManObj(p->pAig, Entry), iFrameOld, ~0 ); + } + if ( iLit < 2 ) + return iLit; + return Saig_ManBmcCreateCnf_rec( p, pObj, iFrame, 1 ); +} + + + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ParBmcSetDefaultParams( Saig_ParBmc_t * p ) +{ + memset( p, 0, sizeof(Saig_ParBmc_t) ); + p->nStart = 0; // maximum number of timeframes + p->nFramesMax = 2000; // maximum number of timeframes + p->nConfLimit = 2000; // maximum number of conflicts at a node + p->nTimeOut = 0; // approximate timeout in seconds + p->fSolveAll = 0; // stops on the first SAT instance + p->fDropSatOuts = 0; // replace sat outputs by constant 0 + p->fVerbose = 0; // verbose + p->iFrame = -1; // explored up to this frame + p->nFailOuts = 0; // the number of failed outputs +} + +/**Function************************************************************* + + Synopsis [Bounded model checking engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * pPars ) +{ + Gia_ManBmc_t * p; + Aig_Obj_t * pObj; + int RetValue = -1, fFirst = 1; + int i, f, Lit, status, clk, clk2, clkOther = 0, clkTotal = clock(); + if ( pPars->fVerbose && Aig_ManConstrNum(pAig) > 0 ) + printf( "Performing BMC with constraints...\n" ); + p = Saig_Bmc3ManStart( pAig ); + p->pPars = pPars; + if ( pPars->fVerbose ) + { + printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d. Map = %6d. Sect =%3d.\n", + Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), + Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig), (Vec_IntSize(p->vMapping)-Aig_ManObjNumMax(pAig))/5, Vec_VecSize(p->vSects) ); + printf( "Params: Start = %d. FramesMax = %d. ConfLimit = %d. TimeOut = %d. SolveAll = %d.\n", + pPars->nStart, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->fSolveAll ); + } + for ( f = 0; f < pPars->nFramesMax; f++ ) + { + pPars->iFrame = f; + // resize the array + Vec_IntFillExtra( p->vPiVars, (f+1)*Saig_ManPiNum(p->pAig), 0 ); + // map nodes of this section + Vec_PtrPush( p->vId2Var, Vec_IntStartFull(p->nObjNums) ); +/* + if ( f > 2*Vec_VecSize(p->vSects) ) + { + int iFrameOld = f - 2*Vec_VecSize( p->vSects ); + void * pMemory = Vec_IntReleaseArray( Vec_PtrEntry(p->vId2Var, iFrameOld) ); + ABC_FREE( pMemory ); + } +*/ + // prepare some nodes + Saig_ManBmcSetLiteral( p, Aig_ManConst1(pAig), f, 1 ); + if ( f == 0 ) + Saig_ManForEachLo( p->pAig, pObj, i ) + Saig_ManBmcSetLiteral( p, pObj, 0, 0 ); + // add the constraints for this frame + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig) ) + continue; +clk2 = clock(); + Lit = Saig_ManBmcCreateCnf( p, pObj, f ); + Lit = lit_neg( Lit ); +clkOther += clock() - clk2; + status = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + if ( status == 0 ) + { + printf( "SAT problem became UNSAT after adding constraints in frame %d.\n", f ); + Saig_Bmc3ManStop( p ); + return 1; + } + } + // solve SAT + clk = clock(); + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i >= Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig) ) + break; + // skip solved outputs + if ( p->vCexes && Vec_PtrEntry(p->vCexes, i) ) + continue; + // add constraints for this output +clk2 = clock(); + Lit = Saig_ManBmcCreateCnf( p, pObj, f ); +clkOther += clock() - clk2; + if ( Lit == 0 ) + continue; + if ( Lit == 1 ) + { + extern Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); + Abc_Cex_t * pCex = Fra_SmlTrivCounterExample( pAig, f*Saig_ManPoNum(pAig)+i ); + printf( "Output %d is trivially SAT in frame %d.\n", i, f ); + if ( !pPars->fSolveAll ) + { + ABC_FREE( pAig->pSeqModel ); + pAig->pSeqModel = pCex; + Saig_Bmc3ManStop( p ); + return 0; + } + pPars->nFailOuts++; + if ( p->vCexes == NULL ) + p->vCexes = Vec_PtrStart( Saig_ManPoNum(pAig) ); + Vec_PtrWriteEntry( p->vCexes, i, pCex ); + continue; + } + // solve this output + sat_solver_compress( p->pSat ); + status = sat_solver_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_False ) + {/* + Lit = lit_neg( Lit ); + status = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + assert( status ); + sat_solver_compress( p->pSat ); + */ + } + else if ( status == l_True ) + { +// extern void * Fra_SmlSimpleCounterExample( Aig_Man_t * p, int * pModel, int iFrame, int iPo ); + int * pModel = Sat_SolverGetModel( p->pSat, Vec_IntArray(p->vPiVars), Vec_IntSize(p->vPiVars) ); + Abc_Cex_t * pCex = Fra_SmlSimpleCounterExample( pAig, pModel, f, i ); + ABC_FREE( pModel ); + fFirst = 0; + if ( !pPars->fSolveAll ) + { +//ABC_PRT( "CNF generation runtime", clkOther ); + if ( pPars->fVerbose ) + { + printf( "%3d : ", f ); + printf( "Var =%8.0f. ", (double)p->nSatVars ); + printf( "Cla =%9.0f. ", (double)p->pSat->stats.clauses ); + printf( "Conf =%7.0f. ",(double)p->pSat->stats.conflicts ); + printf( "Imp =%10.0f. ", (double)p->pSat->stats.propagations ); + ABC_PRT( "Time", clock() - clk ); + ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); + ABC_PRM( "SAT", 42 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); + printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); + printf( "\n" ); + fflush( stdout ); + } + ABC_FREE( pAig->pSeqModel ); + pAig->pSeqModel = pCex; + Saig_Bmc3ManStop( p ); + return 0; + } + pPars->nFailOuts++; + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", i, f ); + if ( p->vCexes == NULL ) + p->vCexes = Vec_PtrStart( Saig_ManPoNum(pAig) ); + Vec_PtrWriteEntry( p->vCexes, i, pCex ); + } + else + { + assert( status == l_Undef ); + Saig_Bmc3ManStop( p ); + return RetValue; + } + if ( pPars->nTimeOut && ((float)pPars->nTimeOut <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", pPars->nTimeOut ); + Saig_Bmc3ManStop( p ); + return RetValue; + } + } + if ( pPars->fVerbose ) + { + if ( fFirst == 1 && f > 0 && p->pSat->stats.conflicts > 1 ) + { + fFirst = 0; +// printf( "Outputs of frames up to %d are trivially UNSAT.\n", f ); + } + printf( "%3d : ", f ); + printf( "Var =%8.0f. ", (double)p->nSatVars ); + printf( "Cla =%9.0f. ", (double)p->pSat->stats.clauses ); + printf( "Conf =%7.0f. ",(double)p->pSat->stats.conflicts ); + printf( "Imp =%10.0f. ", (double)p->pSat->stats.propagations ); + ABC_PRT( "Time", clock() - clk ); +// ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); +// ABC_PRM( "SAT", 42 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); +// printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); +// printf( "\n" ); + fflush( stdout ); + } + } +//ABC_PRT( "CNF generation runtime", clkOther ); + if ( pPars->fVerbose ) + { + ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); + ABC_PRM( "SAT", 48 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); + printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); + printf( "\n" ); + } + Saig_Bmc3ManStop( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigCone.c b/src/aig/saig/saigCone.c index 7ca077c8..2b0da5c9 100644 --- a/src/aig/saig/saigCone.c +++ b/src/aig/saig/saigCone.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -78,7 +81,7 @@ Vec_Ptr_t * Saig_ManSupport( Aig_Man_t * p, Vec_Ptr_t * vNodes ) int i; vSupp = Vec_PtrAlloc( 100 ); Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { assert( Aig_ObjIsPo(pObj) ); Saig_ManSupport_rec( p, Aig_ObjFanin0(pObj), vSupp ); @@ -115,7 +118,7 @@ void Saig_ManPrintConeOne( Aig_Man_t * p, Aig_Obj_t * pObj ) { // classify current into those new, prev, and older nCurNew = nCurPrev = nCurOld = 0; - Vec_PtrForEachEntry( vCur, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCur, pObj, i ) { if ( Vec_PtrFind(vTotal, pObj) == -1 ) { @@ -174,3 +177,5 @@ void Saig_ManPrintCones( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigConstr.c b/src/aig/saig/saigConstr.c new file mode 100644 index 00000000..b4024634 --- /dev/null +++ b/src/aig/saig/saigConstr.c @@ -0,0 +1,384 @@ +/**CFile**************************************************************** + + FileName [saigConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Structural constraint detection.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigConstr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "cnf.h" +#include "satSolver.h" +#include "kit.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Saig_ManDetectConstr( Aig_Man_t * p, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvCons ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig ) +{ + Vec_Ptr_t * vOuts, * vCons; + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pObj; + int i, RetValue; + RetValue = Saig_ManDetectConstr( pAig, &vOuts, &vCons ); + if ( RetValue == 0 ) + return Aig_ManDupDfs( pAig ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // AND the outputs + pMiter = Aig_ManConst1( pAigNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, i ) + pMiter = Aig_And( pAigNew, pMiter, Aig_Not(Aig_ObjRealCopy(pObj)) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + // add constraints + pAigNew->nConstrs = Vec_PtrSize(vCons); + Vec_PtrForEachEntry( Aig_Obj_t *, vCons, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjRealCopy(pObj) ); + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + Vec_PtrFreeP( &vOuts ); + Vec_PtrFreeP( &vCons ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while folding in the constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupFoldConstrs( Aig_Man_t * pAig, Vec_Int_t * vConstrs ) +{ + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj; + int Entry, i; + assert( Saig_ManRegNum(pAig) > 0 ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // OR the constraint outputs + pMiter = Aig_ManConst0( pAigNew ); + Vec_IntForEachEntry( vConstrs, Entry, i ) + { + assert( Entry > 0 && Entry < Saig_ManPoNum(pAig) ); + pObj = Aig_ManPo( pAig, Entry ); + pMiter = Aig_Or( pAigNew, pMiter, Aig_ObjChild0Copy(pObj) ); + } + // create additional flop + pFlopOut = Aig_ObjCreatePi( pAigNew ); + pFlopIn = Aig_Or( pAigNew, pMiter, pFlopOut ); + + // create primary output + Saig_ManForEachPo( pAig, pObj, i ) + { + pMiter = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_Not(pFlopIn) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + } + + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + // create additional flop + Aig_ObjCreatePo( pAigNew, pFlopIn ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig)+1 ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + + +/**Function************************************************************* + + Synopsis [Tests the above two procedures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManFoldConstrTest( Aig_Man_t * pAig ) +{ + Aig_Man_t * pAig1, * pAig2; + Vec_Int_t * vConstrs; + // unfold constraints + pAig1 = Saig_ManDupUnfoldConstrs( pAig ); + // create the constraint list + vConstrs = Vec_IntStartNatural( Saig_ManPoNum(pAig1) ); + Vec_IntRemove( vConstrs, 0 ); + // fold constraints back + pAig2 = Saig_ManDupFoldConstrs( pAig1, vConstrs ); + Vec_IntFree( vConstrs ); + // compare the two AIGs + Ioa_WriteAiger( pAig2, "test.aig", 0, 0 ); + Aig_ManStop( pAig1 ); + Aig_ManStop( pAig2 ); +} + + + + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_DetectConstrCollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Aig_IsComplement(pObj) || !Aig_ObjIsNode(pObj) )//|| (Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPushUnique( vSuper, Aig_Not(pObj) ); + return; + } + // go through the branches + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_DetectConstrCollectSuper( Aig_Obj_t * pObj ) +{ + Vec_Ptr_t * vSuper; + assert( !Aig_IsComplement(pObj) ); + assert( Aig_ObjIsAnd(pObj) ); + vSuper = Vec_PtrAlloc( 4 ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); + return vSuper; +} + +/**Function************************************************************* + + Synopsis [Returns NULL if not contained, or array with unique entries.] + + Description [Returns NULL if vSuper2 is not contained in vSuper. Otherwise + returns the array of entries in vSuper that are not found in vSuper2.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManDetectConstrCheckCont( Vec_Ptr_t * vSuper, Vec_Ptr_t * vSuper2 ) +{ + Vec_Ptr_t * vUnique; + Aig_Obj_t * pObj, * pObj2; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper2, pObj2, i ) + if ( Vec_PtrFind( vSuper, pObj2 ) == -1 ) + return 0; + vUnique = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + if ( Vec_PtrFind( vSuper2, pObj ) == -1 ) + Vec_PtrPush( vUnique, pObj ); + return vUnique; +} + +/**Function************************************************************* + + Synopsis [Detects constraints using structural methods.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManDetectConstr( Aig_Man_t * p, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvCons ) +{ + Vec_Ptr_t * vSuper, * vSuper2, * vUnique; + Aig_Obj_t * pObj, * pObj2, * pFlop; + int i, nFlops, RetValue; + *pvOuts = NULL; + *pvCons = NULL; + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "The number of POs is other than 1.\n" ); + return 0; + } + pObj = Aig_ObjChild0( Aig_ManPo(p, 0) ); + if ( Aig_IsComplement(pObj) || !Aig_ObjIsNode(pObj) ) + { + printf( "The output is not an AND.\n" ); + return 0; + } + vSuper = Saig_DetectConstrCollectSuper( pObj ); + assert( Vec_PtrSize(vSuper) >= 2 ); + nFlops = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + nFlops += Saig_ObjIsLo( p, Aig_Regular(pObj) ); + if ( nFlops == 0 ) + { + printf( "There is no flop outputs.\n" ); + Vec_PtrFree( vSuper ); + return 0; + } + // try flops + vUnique = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + { + pFlop = Aig_Regular( pObj ); + if ( !Saig_ObjIsLo(p, pFlop) ) + continue; + pFlop = Saig_ObjLoToLi( p, pFlop ); + pObj2 = Aig_ObjChild0( pFlop ); + if ( !Aig_IsComplement(pObj2) || !Aig_ObjIsNode(Aig_Regular(pObj2)) ) + continue; + vSuper2 = Saig_DetectConstrCollectSuper( Aig_Regular(pObj2) ); + // every node in vSuper2 should appear in vSuper + vUnique = Saig_ManDetectConstrCheckCont( vSuper, vSuper2 ); + if ( vUnique != NULL ) + { +/// assert( !Aig_IsComplement(pObj) ); + // assert( Vec_PtrFind( vSuper2, pObj ) >= 0 ); + if ( Aig_IsComplement(pObj) ) + { + printf( "Special flop input is complemented.\n" ); + Vec_PtrFreeP( &vUnique ); + Vec_PtrFree( vSuper2 ); + break; + } + if ( Vec_PtrFind( vSuper2, pObj ) == -1 ) + { + printf( "Cannot find special flop about the inputs of OR gate.\n" ); + Vec_PtrFreeP( &vUnique ); + Vec_PtrFree( vSuper2 ); + break; + } + // remove the flop output + Vec_PtrRemove( vSuper2, pObj ); + break; + } + Vec_PtrFree( vSuper2 ); + } + Vec_PtrFree( vSuper ); + if ( vUnique == NULL ) + { + printf( "There is no structural constraints.\n" ); + return 0; + } + // vUnique contains unique entries + // vSuper2 contains the supergate + printf( "Structural analysis found %d original properties and %d constraints.\n", + Vec_PtrSize(vUnique), Vec_PtrSize(vSuper2) ); + // remember the number of constraints + RetValue = Vec_PtrSize(vSuper2); + // make the AND of properties +// Vec_PtrFree( vUnique ); +// Vec_PtrFree( vSuper2 ); + *pvOuts = vUnique; + *pvCons = vSuper2; + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Experiment with the above procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManDetectConstrTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vOuts, * vCons; + int RetValue = Saig_ManDetectConstr( p, &vOuts, &vCons ); + Vec_PtrFreeP( &vOuts ); + Vec_PtrFreeP( &vCons ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigConstr2.c b/src/aig/saig/saigConstr2.c new file mode 100644 index 00000000..a5a575fd --- /dev/null +++ b/src/aig/saig/saigConstr2.c @@ -0,0 +1,1001 @@ +/**CFile**************************************************************** + + FileName [saigConstr2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Functional constraint detection.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigConstr2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "cnf.h" +#include "satSolver.h" +#include "kit.h" +#include "bar.h" + +ABC_NAMESPACE_IMPL_START + + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline Aig_Obj_t * Aig_ObjFrames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return pObjMap[nFs*pObj->Id + i]; } +static inline void Aig_ObjSetFrames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { pObjMap[nFs*pObj->Id + i] = pNode; } + +static inline Aig_Obj_t * Aig_ObjChild0Frames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return Aig_ObjFanin0(pObj)? Aig_NotCond(Aig_ObjFrames(pObjMap,nFs,Aig_ObjFanin0(pObj),i), Aig_ObjFaninC0(pObj)) : NULL; } +static inline Aig_Obj_t * Aig_ObjChild1Frames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return Aig_ObjFanin1(pObj)? Aig_NotCond(Aig_ObjFrames(pObjMap,nFs,Aig_ObjFanin1(pObj),i), Aig_ObjFaninC1(pObj)) : NULL; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the probability of POs being 1 under rand seq sim.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManProfileConstraints( Aig_Man_t * p, int nWords, int nFrames, int fVerbose ) +{ + Vec_Ptr_t * vInfo; + Vec_Int_t * vProbs, * vProbs2; + Aig_Obj_t * pObj, * pObjLi; + unsigned * pInfo, * pInfo0, * pInfo1, * pInfoMask, * pInfoMask2; + int i, w, f, RetValue = 1, clk = clock(); + if ( fVerbose ) + printf( "Simulating %d nodes and %d flops for %d frames with %d words... ", + Aig_ManNodeNum(p), Aig_ManRegNum(p), nFrames, nWords ); + Aig_ManRandom( 1 ); + vInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p)+2, nWords ); + Vec_PtrCleanSimInfo( vInfo, 0, nWords ); + vProbs = Vec_IntStart( Saig_ManPoNum(p) ); + vProbs2 = Vec_IntStart( Saig_ManPoNum(p) ); + // start the constant + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(Aig_ManConst1(p)) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~0; + // start the flop inputs + Saig_ManForEachLi( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + // get the info mask + pInfoMask = (unsigned *)Vec_PtrEntry( vInfo, Aig_ManObjNumMax(p) ); // PO failed + pInfoMask2 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ManObjNumMax(p)+1 ); // constr failed + for ( f = 0; f < nFrames; f++ ) + { + // assign primary inputs + Saig_ManForEachPi( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Aig_ManRandom( 0 ); + } + // move the flop values + Saig_ManForEachLiLo( p, pObjLi, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObjLi) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w]; + } + // simulate the nodes + Aig_ManForEachNode( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId0(pObj) ); + pInfo1 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId1(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + { + if ( Aig_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Aig_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } + } + // clean the mask + for ( w = 0; w < nWords; w++ ) + pInfoMask[w] = pInfoMask2[w] = 0; + // simulate the primary outputs + Aig_ManForEachPo( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId0(pObj) ); + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) || i >= Saig_ManPoNum(p) ) + { + if ( Aig_ObjFaninC0(pObj) ) + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w]; + } + else + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w]; + } + } + else + { + if ( Aig_ObjFaninC0(pObj) ) + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] |= ~pInfo0[w]; + } + else + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] |= pInfo0[w]; + } + } + // collect patterns when one of the outputs fails + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + { + for ( w = 0; w < nWords; w++ ) + pInfoMask[w] |= pInfo[w]; + } + else if ( i < Saig_ManPoNum(p) ) + { + for ( w = 0; w < nWords; w++ ) + pInfoMask2[w] |= pInfo[w]; + } + } + // compare the PO values (mask=1 => out=0) or UNSAT(mask=1 & out=1) + Saig_ManForEachPo( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + Vec_IntAddToEntry( vProbs, i, Aig_WordCountOnes(pInfo[w]) ); + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + { + // chek the output + for ( w = 0; w < nWords; w++ ) + if ( pInfo[w] & ~pInfoMask2[w] ) + break; + if ( w == nWords ) + continue; + printf( "Primary output %d fails on some input patterns.\n", i ); + } + else + { + // collect patterns that block the POs + for ( w = 0; w < nWords; w++ ) + Vec_IntAddToEntry( vProbs2, i, Aig_WordCountOnes(pInfo[w] & pInfoMask[w]) ); + } + } + } + if ( fVerbose ) + Abc_PrintTime( 1, "T", clock() - clk ); + // print the state + if ( fVerbose ) + { + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) ) + printf( "Primary output : ", i ); + else + printf( "Constraint %3d : ", i-(Saig_ManPoNum(p) - Saig_ManConstrNum(p)) ); + printf( "ProbOne = %f ", (float)Vec_IntEntry(vProbs, i)/(32*nWords*nFrames) ); + printf( "ProbOneC = %f ", (float)Vec_IntEntry(vProbs2, i)/(32*nWords*nFrames) ); + printf( "AllZeroValue = %d ", Aig_ObjPhase(pObj) ); + printf( "\n" ); + } + } + + // print the states + Vec_PtrFree( vInfo ); + Vec_IntFree( vProbs ); + Vec_IntFree( vProbs2 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManCreateIndMiter( Aig_Man_t * pAig, Vec_Vec_t * vCands ) +{ + int nFrames = 2; + Vec_Ptr_t * vNodes; + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; + Aig_Obj_t ** pObjMap; + int i, f, k; + + // create mapping for the frames nodes + pObjMap = ABC_CALLOC( Aig_Obj_t *, nFrames * Aig_ManObjNumMax(pAig) ); + + // start the fraig package + pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + pFrames->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map constant nodes + for ( f = 0; f < nFrames; f++ ) + Aig_ObjSetFrames( pObjMap, nFrames, Aig_ManConst1(pAig), f, Aig_ManConst1(pFrames) ); + // create PI nodes for the frames + for ( f = 0; f < nFrames; f++ ) + Aig_ManForEachPiSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, Aig_ObjCreatePi(pFrames) ); + // set initial state for the latches + Aig_ManForEachLoSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, 0, Aig_ObjCreatePi(pFrames) ); + + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + { + pObjNew = Aig_And( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f), Aig_ObjChild1Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + // set the latch inputs and copy them into the latch outputs of the next frame + Aig_ManForEachLiLoSeq( pAig, pObjLi, pObjLo, i ) + { + pObjNew = Aig_ObjChild0Frames(pObjMap,nFrames,pObjLi,f); + if ( f < nFrames - 1 ) + Aig_ObjSetFrames( pObjMap, nFrames, pObjLo, f+1, pObjNew ); + } + } + + // go through the candidates + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + Aig_Obj_t * pObjR = Aig_Regular(pObj); + Aig_Obj_t * pNode0 = pObjMap[nFrames*Aig_ObjId(pObjR)+0]; + Aig_Obj_t * pNode1 = pObjMap[nFrames*Aig_ObjId(pObjR)+1]; + Aig_Obj_t * pFan0 = Aig_NotCond( pNode0, Aig_IsComplement(pObj) ); + Aig_Obj_t * pFan1 = Aig_NotCond( pNode1, !Aig_IsComplement(pObj) ); + Aig_Obj_t * pMiter = Aig_And( pFrames, pFan0, pFan1 ); + Aig_ObjCreatePo( pFrames, pMiter ); + } + } + Aig_ManCleanup( pFrames ); + ABC_FREE( pObjMap ); + +//Aig_ManShow( pAig, 0, NULL ); +//Aig_ManShow( pFrames, 0, NULL ); + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Performs inductive check for one of the constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManFilterUsingIndOne_new( Aig_Man_t * p, Aig_Man_t * pFrame, sat_solver * pSat, Cnf_Dat_t * pCnf, int nConfs, int nProps, int Counter ) +{ + Aig_Obj_t * pObj; + int Lit, status; + pObj = Aig_ManPo( pFrame, Counter ); + Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 0 ); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); + if ( status == l_False ) + return 1; + if ( status == l_Undef ) + { +// printf( "Solver returned undecided.\n" ); + return 0; + } + assert( status == l_True ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Detects constraints functionally.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManFilterUsingInd( Aig_Man_t * p, Vec_Vec_t * vCands, int nConfs, int nProps, int fVerbose ) +{ + Vec_Ptr_t * vNodes; + Aig_Man_t * pFrames; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Obj_t * pObj; + int i, k, k2, Counter; +/* + Vec_VecForEachLevel( vCands, vNodes, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + printf( "%d ", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); +*/ + // create timeframes +// pFrames = Saig_ManUnrollInd( p ); + pFrames = Saig_ManCreateIndMiter( p, vCands ); + assert( Aig_ManPoNum(pFrames) == Vec_VecSizeSize(vCands) ); + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, Aig_ManPoNum(pFrames) ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + // check candidates + if ( fVerbose ) + printf( "Filtered cands: " ); + Counter = 0; + Vec_VecForEachLevel( vCands, vNodes, i ) + { + k2 = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + if ( Saig_ManFilterUsingIndOne_new( p, pFrames, pSat, pCnf, nConfs, nProps, Counter++ ) ) +// if ( Saig_ManFilterUsingIndOne_old( p, pSat, pCnf, nConfs, pObj ) ) + { + Vec_PtrWriteEntry( vNodes, k2++, pObj ); + if ( fVerbose ) + printf( "%d:%s%d ", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + } + } + Vec_PtrShrink( vNodes, k2 ); + } + if ( fVerbose ) + printf( "\n" ); + // clean up + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + if ( fVerbose ) + Aig_ManPrintStats( pFrames ); + Aig_ManStop( pFrames ); +} + + + + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollCOI_( Aig_Man_t * p, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t ** pObjMap; + int i; +//Aig_Man_t * Aig_ManFrames( Aig_Man_t * pAig, int nFrames, int fInit, int fOuts, int fRegs, int fEnlarge, Aig_Obj_t *** ppObjMap ) + pFrames = Aig_ManFrames( p, nFrames, 0, 1, 1, 0, &pObjMap ); + for ( i = 0; i < nFrames * Aig_ManObjNumMax(p); i++ ) + if ( pObjMap[i] && Aig_ObjIsNone( Aig_Regular(pObjMap[i]) ) ) + pObjMap[i] = NULL; + assert( p->pObjCopies == NULL ); + p->pObjCopies = pObjMap; + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollCOI( Aig_Man_t * pAig, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; + Aig_Obj_t ** pObjMap; + int i, f; + // create mapping for the frames nodes + pObjMap = ABC_CALLOC( Aig_Obj_t *, nFrames * Aig_ManObjNumMax(pAig) ); + // start the fraig package + pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + pFrames->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map constant nodes + for ( f = 0; f < nFrames; f++ ) + Aig_ObjSetFrames( pObjMap, nFrames, Aig_ManConst1(pAig), f, Aig_ManConst1(pFrames) ); + // create PI nodes for the frames + for ( f = 0; f < nFrames; f++ ) + Aig_ManForEachPiSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, Aig_ObjCreatePi(pFrames) ); + // set initial state for the latches + Aig_ManForEachLoSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, 0, Aig_ObjCreatePi(pFrames) ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + Aig_ManForEachNode( pAig, pObj, i ) + { + pObjNew = Aig_And( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f), Aig_ObjChild1Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + // set the latch inputs and copy them into the latch outputs of the next frame + Aig_ManForEachLiLoSeq( pAig, pObjLi, pObjLo, i ) + { + pObjNew = Aig_ObjChild0Frames(pObjMap,nFrames,pObjLi,f); + if ( f < nFrames - 1 ) + Aig_ObjSetFrames( pObjMap, nFrames, pObjLo, f+1, pObjNew ); + } + } + // create the only output + for ( f = nFrames-1; f < nFrames; f++ ) + { + Aig_ManForEachPoSeq( pAig, pObj, i ) + { + pObjNew = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + } + // created lots of dangling nodes - no sweeping! + //Aig_ManCleanup( pFrames ); + assert( pAig->pObjCopies == NULL ); + pAig->pObjCopies = pObjMap; + return pFrames; +} + + +/**Function************************************************************* + + Synopsis [Collects and saves values of the SAT variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_CollectSatValues( sat_solver * pSat, Cnf_Dat_t * pCnf, Vec_Ptr_t * vInfo, int * piPat ) +{ + Aig_Obj_t * pObj; + unsigned * pInfo; + int i; + Aig_ManForEachObj( pCnf->pMan, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + assert( pCnf->pVarNums[i] > 0 ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + if ( Aig_InfoHasBit(pInfo, *piPat) != sat_solver_var_value(pSat, pCnf->pVarNums[i]) ) + Aig_InfoXorBit(pInfo, *piPat); + } +} + +/**Function************************************************************* + + Synopsis [Runs the SAT test for the node in one polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_DetectTryPolarity( sat_solver * pSat, int nConfs, int nProps, Cnf_Dat_t * pCnf, Aig_Obj_t * pObj, int iPol, Vec_Ptr_t * vInfo, int * piPat, int fVerbose ) +{ + Aig_Obj_t * pOut = Aig_ManPo( pCnf->pMan, 0 ); + int status, Lits[2]; +// ABC_INT64_T nOldConfs = pSat->stats.conflicts; +// ABC_INT64_T nOldImps = pSat->stats.propagations; + Lits[0] = toLitCond( pCnf->pVarNums[Aig_ObjId(pOut)], 0 ); + Lits[1] = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !iPol ); + status = sat_solver_solve( pSat, Lits, Lits + 2, (ABC_INT64_T)nConfs, (ABC_INT64_T)nProps, 0, 0 ); + if ( status == l_False ) + { +// printf( "u%d(%d) ", (int)(pSat->stats.conflicts-nOldConfs), (int)(pSat->stats.propagations-nOldImps) ); + return 1; + } + if ( status == l_Undef ) + { +// printf( "Solver returned undecided.\n" ); + return 0; + } +// printf( "s%d(%d) ", (int)(pSat->stats.conflicts-nOldConfs), (int)(pSat->stats.propagations-nOldImps) ); + assert( status == l_True ); + Saig_CollectSatValues( pSat, pCnf, vInfo, piPat ); + (*piPat)++; + if ( *piPat == Vec_PtrReadWordsSimInfo(vInfo) * 32 ) + { + if ( fVerbose ) + printf( "Warning: Reached the limit on the number of patterns.\n" ); + *piPat = 0; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns the number of variables implied by the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Ssw_ManFindDirectImplications( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fVerbose ) +{ + Vec_Vec_t * vCands = NULL; + Vec_Ptr_t * vNodes; + Cnf_Dat_t * pCnf; + sat_solver * pSat; + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pRepr, * pReprR; + int i, f, k, value; + vCands = Vec_VecAlloc( nFrames ); + + // perform unrolling + pFrames = Saig_ManUnrollCOI( p, nFrames ); + assert( Aig_ManPoNum(pFrames) == 1 ); + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( pSat != NULL ) + { + Aig_ManIncrementTravId( p ); + for ( f = 0; f < nFrames; f++ ) + { + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsCand(pObj) ) + continue; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + continue; + // get the node from timeframes + pRepr = p->pObjCopies[nFrames*i + nFrames-1-f]; + pReprR = Aig_Regular(pRepr); + if ( pCnf->pVarNums[Aig_ObjId(pReprR)] < 0 ) + continue; + value = pSat->assigns[ pCnf->pVarNums[Aig_ObjId(pReprR)] ]; + if ( value == l_Undef ) + continue; + // label this node as taken + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Saig_ObjIsLo(p, pObj) ) + Aig_ObjSetTravIdCurrent( p, Aig_ObjFanin0(Saig_ObjLoToLi(p, pObj)) ); + // remember the node + Vec_VecPush( vCands, f, Aig_NotCond( pObj, (value == l_True) ^ Aig_IsComplement(pRepr) ) ); + // printf( "%s%d ", (value == l_False)? "":"!", i ); + } + } + // printf( "\n" ); + sat_solver_delete( pSat ); + } + Aig_ManStop( pFrames ); + Cnf_DataFree( pCnf ); + + if ( fVerbose ) + { + printf( "Found %3d candidates.\n", Vec_VecSizeSize(vCands) ); + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Cands =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + ABC_FREE( p->pObjCopies ); + Saig_ManFilterUsingInd( p, vCands, nConfs, nProps, fVerbose ); + if ( Vec_VecSizeSize(vCands) ) + printf( "Found %3d constraints after filtering.\n", Vec_VecSizeSize(vCands) ); + if ( fVerbose ) + { + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Constr =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + return vCands; +} + + +/**Function************************************************************* + + Synopsis [Detects constraints functionally.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Saig_ManDetectConstrFunc( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fVerbose ) +{ + int iPat = 0, nWordsAlloc = 16; + Bar_Progress_t * pProgress = NULL; + Vec_Vec_t * vCands = NULL; + Vec_Ptr_t * vInfo, * vNodes; + Aig_Obj_t * pObj, * pRepr, * pObjNew; + Aig_Man_t * pFrames; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + unsigned * pInfo; + int i, j, k, Lit, status, nCands = 0; + assert( Saig_ManPoNum(p) == 1 ); + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "The number of outputs is different from 1.\n" ); + return NULL; + } +//printf( "Implications = %d.\n", Ssw_ManCountImplications(p, nFrames) ); + + // perform unrolling + pFrames = Saig_ManUnrollCOI( p, nFrames ); + assert( Aig_ManPoNum(pFrames) == 1 ); + if ( fVerbose ) + { + printf( "Detecting constraints with %d frames, %d conflicts, and %d propagations.\n", nFrames, nConfs, nProps ); + printf( "Frames: " ); + Aig_ManPrintStats( pFrames ); + } +// Aig_ManShow( pFrames, 0, NULL ); + + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, Aig_ManPoNum(pFrames) ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); +//printf( "Implications = %d.\n", pSat->qhead ); + + // solve the original problem + Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(Aig_ManPo(pFrames,0))], 0 ); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); + if ( status == l_False ) + { + printf( "The problem is trivially UNSAT (inductive with k=%d).\n", nFrames-1 ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManStop( pFrames ); + return NULL; + } + if ( status == l_Undef ) + { + printf( "Solver could not solve the original problem.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManStop( pFrames ); + return NULL; + } + assert( status == l_True ); + + // create simulation info + vInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(pFrames), nWordsAlloc ); + Vec_PtrCleanSimInfo( vInfo, 0, nWordsAlloc ); + Saig_CollectSatValues( pSat, pCnf, vInfo, &iPat ); + Aig_ManForEachObj( pFrames, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + if ( pInfo[0] & 1 ) + memset( (char*)pInfo, 0xff, 4*nWordsAlloc ); + } +// Aig_ManShow( pFrames, 0, NULL ); +// Aig_ManShow( p, 0, NULL ); + + // consider the nodes for ci=>!Out and label when it holds + pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(pFrames) ); + Aig_ManCleanMarkAB( pFrames ); + Aig_ManForEachObj( pFrames, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + Bar_ProgressUpdate( pProgress, i, NULL ); + // check if the node is available in both polarities + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + for ( k = 0; k < nWordsAlloc; k++ ) + if ( pInfo[k] != ~0 ) + break; + if ( k == nWordsAlloc ) + { + if ( Saig_DetectTryPolarity(pSat, nConfs, nProps, pCnf, pObj, 0, vInfo, &iPat, fVerbose) ) // !pObj is a constr + { + pObj->fMarkA = 1, nCands++; +// printf( "!%d ", Aig_ObjId(pObj) ); + } + continue; + } + for ( k = 0; k < nWordsAlloc; k++ ) + if ( pInfo[k] != 0 ) + break; + if ( k == nWordsAlloc ) + { + if ( Saig_DetectTryPolarity(pSat, nConfs, nProps, pCnf, pObj, 1, vInfo, &iPat, fVerbose) ) // pObj is a constr + { + pObj->fMarkB = 1, nCands++; +// printf( "%d ", Aig_ObjId(pObj) ); + } + continue; + } + } + Bar_ProgressStop( pProgress ); + if ( nCands ) + { + +// printf( "\n" ); + if ( fVerbose ) + printf( "Found %3d classes of candidates.\n", nCands ); + vCands = Vec_VecAlloc( nFrames ); + for ( k = 0; k < nFrames; k++ ) + { + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + pRepr = p->pObjCopies[nFrames*i + nFrames-1-k]; +// pRepr = p->pObjCopies[nFrames*i + k]; + if ( pRepr == NULL ) + continue; + if ( Aig_Regular(pRepr)->fMarkA ) // !pObj is a constr + { + pObjNew = Aig_NotCond(pObj, !Aig_IsComplement(pRepr)); + + for ( j = 0; j < k; j++ ) + if ( Vec_PtrFind( (Vec_Ptr_t *)Vec_VecEntry(vCands, j), pObjNew ) >= 0 ) + break; + if ( j == k ) + Vec_VecPush( vCands, k, pObjNew ); +// printf( "%d->!%d ", Aig_ObjId(Aig_Regular(pRepr)), Aig_ObjId(pObj) ); + } + else if ( Aig_Regular(pRepr)->fMarkB ) // pObj is a constr + { + pObjNew = Aig_NotCond(pObj, Aig_IsComplement(pRepr)); + + for ( j = 0; j < k; j++ ) + if ( Vec_PtrFind( (Vec_Ptr_t *)Vec_VecEntry(vCands, j), pObjNew ) >= 0 ) + break; + if ( j == k ) + Vec_VecPush( vCands, k, pObjNew ); +// printf( "%d->%d ", Aig_ObjId(Aig_Regular(pRepr)), Aig_ObjId(pObj) ); + } + } + } + +// printf( "\n" ); + if ( fVerbose ) + { + printf( "Found %3d candidates.\n", Vec_VecSizeSize(vCands) ); + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Cands =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + ABC_FREE( p->pObjCopies ); + Saig_ManFilterUsingInd( p, vCands, nConfs, nProps, fVerbose ); + if ( Vec_VecSizeSize(vCands) ) + printf( "Found %3d constraints after filtering.\n", Vec_VecSizeSize(vCands) ); + if ( fVerbose ) + { + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Constr =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + } + Vec_PtrFree( vInfo ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManCleanMarkAB( pFrames ); + Aig_ManStop( pFrames ); + return vCands; +} + +/**Function************************************************************* + + Synopsis [Experimental procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManDetectConstrFuncTest( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ) +{ + Vec_Vec_t * vCands; + if ( fOldAlgo ) + vCands = Saig_ManDetectConstrFunc( p, nFrames, nConfs, nProps, fVerbose ); + else + vCands = Ssw_ManFindDirectImplications( p, nFrames, nConfs, nProps, fVerbose ); + Vec_VecFreeP( &vCands ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ) +{ + Aig_Man_t * pNew; + Vec_Vec_t * vCands; + Vec_Ptr_t * vNodes, * vNewFlops; + Aig_Obj_t * pObj; + int i, j, k, nNewFlops; + if ( fOldAlgo ) + vCands = Saig_ManDetectConstrFunc( pAig, nFrames, nConfs, nProps, fVerbose ); + else + vCands = Ssw_ManFindDirectImplications( pAig, nFrames, nConfs, nProps, fVerbose ); + if ( vCands == NULL || Vec_VecSizeSize(vCands) == 0 ) + { + Vec_VecFreeP( &vCands ); + return Aig_ManDupDfs( pAig ); + } + // create new manager + pNew = Aig_ManDupWithoutPos( pAig ); + pNew->nConstrs = pAig->nConstrs + Vec_VecSizeSize(vCands); + // add normal POs + Saig_ManForEachPo( pAig, pObj, i ) + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // create constraint outputs + vNewFlops = Vec_PtrAlloc( 100 ); + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + Vec_PtrPush( vNewFlops, Aig_ObjRealCopy(pObj) ); + for ( j = 0; j < i; j++ ) + Vec_PtrPush( vNewFlops, Aig_ObjCreatePi(pNew) ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrPop(vNewFlops) ); + } + } + // add latch outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // add new latch outputs + nNewFlops = 0; + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + for ( j = 0; j < i; j++ ) + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vNewFlops, nNewFlops++) ); + } + } + assert( nNewFlops == Vec_PtrSize(vNewFlops) ); + Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) + nNewFlops ); + Vec_VecFreeP( &vCands ); + Vec_PtrFree( vNewFlops ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose ) +{ + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj; + int i; + assert( Saig_ManRegNum(pAig) > 0 ); + if ( Aig_ManConstrNum(pAig) == 0 ) + return Aig_ManDupDfs( pAig ); + assert( Aig_ManConstrNum(pAig) < Saig_ManPoNum(pAig) ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + pAigNew->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // OR the constraint outputs + pMiter = Aig_ManConst0( pAigNew ); + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) + continue; + pMiter = Aig_Or( pAigNew, pMiter, Aig_NotCond( Aig_ObjChild0Copy(pObj), fCompl ) ); + } + // create additional flop + pFlopOut = Aig_ObjCreatePi( pAigNew ); + pFlopIn = Aig_Or( pAigNew, pMiter, pFlopOut ); + + // create primary output + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i >= Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) + continue; + pMiter = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_Not(pFlopIn) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + } + + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + // create additional flop + Aig_ObjCreatePo( pAigNew, pFlopIn ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig)+1 ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigDup.c b/src/aig/saig/saigDup.c index e261fca1..268540da 100644 --- a/src/aig/saig/saigDup.c +++ b/src/aig/saig/saigDup.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,9 +47,15 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig ) Aig_Man_t * pAigNew; Aig_Obj_t * pObj, * pMiter; int i; + if ( pAig->nConstrs > 0 ) + { + printf( "The AIG manager should have no constraints.\n" ); + return NULL; + } // start the new manager pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + pAigNew->nConstrs = pAig->nConstrs; // map the constant node Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); // create variables for PIs @@ -82,10 +91,10 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig ) Aig_Obj_t * Saig_ManAbstractionDfs_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj ) { if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin0(pObj) ); Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); } /**Function************************************************************* @@ -112,6 +121,7 @@ Aig_Man_t * Saig_ManTrimPis( Aig_Man_t * p ) // start the new manager pNew = Aig_ManStart( Aig_ManObjNum(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // start mapping of the CI numbers pNew->vCiNumsOrig = Vec_IntAlloc( Aig_ManPiNum(p) ); // map const and primary inputs @@ -142,9 +152,9 @@ Aig_Man_t * Saig_ManTrimPis( Aig_Man_t * p ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) +Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) { - Aig_Man_t * pNew, * pTemp; + Aig_Man_t * pNew;//, * pTemp; Aig_Obj_t * pObj, * pObjLi, * pObjLo; int i, Entry; Aig_ManCleanData( p ); @@ -200,8 +210,8 @@ Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) Aig_ManSetRegNum( pNew, Vec_IntSize(vFlops) ); Aig_ManSeqCleanup( pNew ); // remove PIs without fanout - pNew = Saig_ManTrimPis( pTemp = pNew ); - Aig_ManStop( pTemp ); +// pNew = Saig_ManTrimPis( pTemp = pNew ); +// Aig_ManStop( pTemp ); return pNew; } @@ -210,3 +220,5 @@ Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigHaig.c b/src/aig/saig/saigHaig.c index 1c7aa025..3ea0a2c6 100644 --- a/src/aig/saig/saigHaig.c +++ b/src/aig/saig/saigHaig.c @@ -22,6 +22,9 @@ #include "satSolver.h" #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,9 +54,9 @@ void Aig_ManHaigSpeculate( Aig_Man_t * pFrames, Aig_Obj_t * pObj ) return; // assert( pObjRepr->Id < pObj->Id ); // get the new node - pObjNew = pObj->pData; + pObjNew = (Aig_Obj_t *)pObj->pData; // get the new node of the representative - pObjReprNew = pObjRepr->pData; + pObjReprNew = (Aig_Obj_t *)pObjRepr->pData; // if this is the same node, no need to add constraints assert( pObjNew != NULL && pObjReprNew != NULL ); if ( Aig_Regular(pObjNew) == Aig_Regular(pObjReprNew) ) @@ -233,7 +236,7 @@ clk = clock(); // Saig_ManDumpBlif( pHaig, "haig_temp.blif" ); // Saig_ManDumpBlif( pFrames, "haig_temp_frames.blif" ); // create the SAT solver to be used for this problem - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { printf( "Aig_ManHaigVerify(): Computed CNF is not valid.\n" ); @@ -422,7 +425,7 @@ clk = clock(); // printf( "\n" ); // create the SAT solver to be used for this problem - pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); //Sat_SolverWriteDimacs( pSat, "1.cnf", NULL, NULL, 0 ); if ( pSat == NULL ) { @@ -586,7 +589,7 @@ Aig_Man_t * Saig_ManHaigDump( Aig_Man_t * pHaig ) } printf( "Added %d property outputs.\n", Vec_IntSize(pHaig->vEquPairs)/2 ); // add the registers - Vec_PtrForEachEntry( vTemp, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vTemp, pObj, i ) Vec_PtrPush( pHaig->vPos, pObj ); Vec_PtrFree( vTemp ); assert( pHaig->nObjs[AIG_OBJ_PO] == Vec_PtrSize(pHaig->vPos) ); @@ -630,7 +633,7 @@ clk = clock(); // create its history AIG pNew->pManHaig = Aig_ManDupSimple( pNew ); Aig_ManForEachObj( pNew, pObj, i ) - pObj->pHaig = pObj->pData; + pObj->pHaig = (Aig_Obj_t *)pObj->pData; // remove structural hashing table Aig_TableClear( pNew->pManHaig ); pNew->pManHaig->vEquPairs = Vec_IntAlloc( 10000 ); @@ -725,3 +728,5 @@ clkSynth = clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigInd.c b/src/aig/saig/saigInd.c index 1c26e5df..e22adba2 100644 --- a/src/aig/saig/saigInd.c +++ b/src/aig/saig/saigInd.c @@ -22,6 +22,9 @@ #include "cnf.h" #include "satSolver.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -32,7 +35,51 @@ /**Function************************************************************* - Synopsis [Performs localization by unrolling timeframes backward.] + Synopsis [Returns 1 if two state are equal.] + + Description [Array vState contains indexes of CNF variables for each + flop in the first N time frames (0 < i < k, i < N, k < N).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManStatesAreEqual( sat_solver * pSat, Vec_Int_t * vState, int nRegs, int i, int k ) +{ + int * pStateI = (int *)Vec_IntArray(vState) + nRegs * i; + int * pStateK = (int *)Vec_IntArray(vState) + nRegs * k; + int v; + assert( i && k && i < k ); + assert( nRegs * k <= Vec_IntSize(vState) ); + // check if the states are available + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 && pStateK[v] == -1 ) + return 0; +/* + printf( "\nchecking uniqueness\n" ); + printf( "%3d : ", i ); + for ( v = 0; v < nRegs; v++ ) + printf( "%d", sat_solver_var_value(pSat, pStateI[v]) ); + printf( "\n" ); + + printf( "%3d : ", k ); + for ( v = 0; v < nRegs; v++ ) + printf( "%d", sat_solver_var_value(pSat, pStateK[v]) ); + printf( "\n" ); +*/ + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 ) + { + if ( sat_solver_var_value(pSat, pStateI[v]) != sat_solver_var_value(pSat, pStateK[v]) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Add uniqueness constraint.] Description [] @@ -41,21 +88,78 @@ SeeAlso [] ***********************************************************************/ -int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ) +void Saig_ManAddUniqueness( sat_solver * pSat, Vec_Int_t * vState, int nRegs, int i, int k, int * pnSatVarNum, int * pnClauses ) +{ + int * pStateI = (int *)Vec_IntArray(vState) + nRegs * i; + int * pStateK = (int *)Vec_IntArray(vState) + nRegs * k; + int v, iVars, nSatVarsOld, RetValue, * pClause; + assert( i && k && i < k ); + assert( nRegs * k <= Vec_IntSize(vState) ); + // check if the states are available + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 && pStateK[v] == -1 ) + { +// printf( "Cannot constrain an incomplete state.\n" ); + return; + } + // add XORs + nSatVarsOld = *pnSatVarNum; + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 ) + { + *pnClauses += 4; + RetValue = Cnf_DataAddXorClause( pSat, pStateI[v], pStateK[v], (*pnSatVarNum)++ ); + if ( RetValue == 0 ) + { + printf( "SAT solver became UNSAT.\n" ); + return; + } + } + // add OR clause + (*pnClauses)++; + iVars = 0; + pClause = ABC_ALLOC( int, nRegs ); + for ( v = nSatVarsOld; v < *pnSatVarNum; v++ ) + pClause[iVars++] = toLitCond( v, 0 ); + assert( iVars <= nRegs ); + RetValue = sat_solver_addclause( pSat, pClause, pClause + iVars ); + ABC_FREE( pClause ); + if ( RetValue == 0 ) + { + printf( "SAT solver became UNSAT.\n" ); + return; + } +} + +/**Function************************************************************* + + Synopsis [Performs induction by unrolling timeframes backward.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; Aig_Man_t * pAigPart; Cnf_Dat_t * pCnfPart; - Vec_Int_t * vTopVarNums; + Vec_Int_t * vTopVarNums, * vState; Vec_Ptr_t * vTop, * vBot; Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo; - int i, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; + int i, k, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; + int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0; + assert( fUnique == 0 || fUniqueAll == 0 ); assert( Saig_ManPoNum(p) == 1 ); Aig_ManSetPioNumbers( p ); // start the top by including the PO vBot = Vec_PtrAlloc( 100 ); vTop = Vec_PtrAlloc( 100 ); + vState = Vec_IntAlloc( 1000 ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); // start the array of CNF variables vTopVarNums = Vec_IntAlloc( 100 ); @@ -67,7 +171,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose RetValue = -1; nSatVarNum = 0; if ( fVerbose ) - printf( "Localization parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); + printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); for ( f = 0; ; f++ ) { if ( f > 0 ) @@ -84,6 +188,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) ); Cnf_DataLift( pCnfPart, nSatVarNum ); nSatVarNum += pCnfPart->nVars; + nClauses += pCnfPart->nClauses; // stitch variables of top and bot assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) ); @@ -98,6 +203,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) ) assert( 0 ); + nClauses++; continue; } Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 ); @@ -108,6 +214,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); + nClauses += 2; } // add CNF to the SAT solver for ( i = 0; i < pCnfPart->nClauses; i++ ) @@ -119,14 +226,50 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose RetValue = 1; break; } + + // create new set of POs to derive new top + Vec_PtrClear( vTop ); + Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); + Vec_IntClear( vTopVarNums ); + nOldSize = Vec_IntSize(vState); + Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i ) + { + assert( Aig_ObjIsPi(pObjPi) ); + if ( Saig_ObjIsLo(p, pObjPi) ) + { + pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; + assert( pObjPiCopy != NULL ); + Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); + Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); + + iReg = pObjPi->PioNum - Saig_ManPiNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] ); + } + } + iLast = Vec_IntSize(vState)/Aig_ManRegNum(p); + if ( fUniqueAll ) + { + for ( i = 1; i < iLast-1; i++ ) + { + nConstrs++; + Saig_ManAddUniqueness( pSat, vState, Aig_ManRegNum(p), i, iLast-1, &nSatVarNum, &nClauses ); + if ( fVeryVerbose ) + printf( "added constaint for %3d and %3d\n", i, iLast-1 ); + } + } + +nextrun: + fAdded = 0; // run the SAT solver nConfPrev = pSat->stats.conflicts; status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, 0, 0, 0 ); if ( fVerbose ) { - printf( "%3d : PI = %5d. PO = %5d. AIG = %5d. Var = %6d. Conf = %6d. ", - f+1, Aig_ManPiNum(pAigPart), Aig_ManPoNum(pAigPart), Aig_ManNodeNum(pAigPart), - nSatVarNum, pSat->stats.conflicts-nConfPrev ); + printf( "%4d : PI =%5d. PO =%5d. AIG =%5d. Var =%7d. Clau =%7d. Conf =%7d. ", + f, Aig_ManPiNum(pAigPart), Aig_ManPoNum(pAigPart), Aig_ManNodeNum(pAigPart), + nSatVarNum, nClauses, pSat->stats.conflicts-nConfPrev ); ABC_PRT( "Time", clock() - clk ); } if ( status == l_Undef ) @@ -137,26 +280,49 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose break; } assert( status == l_True ); + // the problem is SAT - add more clauses + if ( fVeryVerbose ) + { + Vec_IntForEachEntry( vState, iReg, i ) + { + if ( i && (i % Aig_ManRegNum(p)) == 0 ) + printf( "\n" ); + if ( (i % Aig_ManRegNum(p)) == 0 ) + printf( "%3d : ", i/Aig_ManRegNum(p) ); + printf( "%c", (iReg >= 0) ? ('0' + sat_solver_var_value(pSat, iReg)) : 'x' ); + } + printf( "\n" ); + } if ( f == nFramesMax - 1 ) break; - // the problem is SAT - add more clauses - // create new set of POs to derive new top - Vec_PtrClear( vTop ); - Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); - Vec_IntClear( vTopVarNums ); - Vec_PtrForEachEntry( vBot, pObjPi, i ) + if ( fUnique ) { - assert( Aig_ObjIsPi(pObjPi) ); - if ( Saig_ObjIsLo(p, pObjPi) ) + for ( i = 1; i < iLast; i++ ) + for ( k = i+1; k < iLast; k++ ) { - pObjPiCopy = pObjPi->pData; - assert( pObjPiCopy != NULL ); - Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); - Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); + if ( !Saig_ManStatesAreEqual( pSat, vState, Aig_ManRegNum(p), i, k ) ) + continue; + nConstrs++; + fAdded = 1; + Saig_ManAddUniqueness( pSat, vState, Aig_ManRegNum(p), i, k, &nSatVarNum, &nClauses ); + if ( fVeryVerbose ) + printf( "added constaint for %3d and %3d\n", i, k ); } } + if ( fAdded ) + { +// if ( fVeryVerbose ) +// printf( "Trying a new run.\n" ); + goto nextrun; + } + } + if ( fVerbose ) + { + if ( fUnique || fUniqueAll ) + printf( "Completed %d interations and added %d uniqueness constraints.\n", f+1, nConstrs ); + else + printf( "Completed %d interations.\n", f+1 ); } -// printf( "Completed %d interations.\n", f+1 ); // cleanup sat_solver_delete( pSat ); Aig_ManStop( pAigPart ); @@ -164,11 +330,15 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Vec_IntFree( vTopVarNums ); Vec_PtrFree( vTop ); Vec_PtrFree( vBot ); + Vec_IntFree( vState ); return RetValue; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigIoa.c b/src/aig/saig/saigIoa.c index d049489e..c84c37f3 100644 --- a/src/aig/saig/saigIoa.c +++ b/src/aig/saig/saigIoa.c @@ -18,8 +18,12 @@ ***********************************************************************/ +#include #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -346,7 +350,7 @@ Aig_Man_t * Saig_ManReadBlif( char * pFileName ) // allocate mapping if ( pNum2Id == NULL ) { - extern double pow( double x, double y ); +// extern double pow( double x, double y ); int Size = (int)pow(10.0, (double)(strlen(pToken) - 1)); pNum2Id = ABC_CALLOC( int, Size ); } @@ -397,3 +401,5 @@ Aig_Man_t * Saig_ManReadBlif( char * pFileName ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 0a9f230b..b470333d 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -210,10 +214,10 @@ void Saig_AndDualRail( Aig_Man_t * pNew, Aig_Obj_t * pObj, Aig_Obj_t ** ppData, { Aig_Obj_t * pFanin0 = Aig_ObjFanin0(pObj); Aig_Obj_t * pFanin1 = Aig_ObjFanin1(pObj); - Aig_Obj_t * p0Data = Aig_ObjFaninC0(pObj)? pFanin0->pNext : pFanin0->pData; - Aig_Obj_t * p0Next = Aig_ObjFaninC0(pObj)? pFanin0->pData : pFanin0->pNext; - Aig_Obj_t * p1Data = Aig_ObjFaninC1(pObj)? pFanin1->pNext : pFanin1->pData; - Aig_Obj_t * p1Next = Aig_ObjFaninC1(pObj)? pFanin1->pData : pFanin1->pNext; + Aig_Obj_t * p0Data = Aig_ObjFaninC0(pObj)? pFanin0->pNext : (Aig_Obj_t *)pFanin0->pData; + Aig_Obj_t * p0Next = Aig_ObjFaninC0(pObj)? (Aig_Obj_t *)pFanin0->pData : pFanin0->pNext; + Aig_Obj_t * p1Data = Aig_ObjFaninC1(pObj)? pFanin1->pNext : (Aig_Obj_t *)pFanin1->pData; + Aig_Obj_t * p1Next = Aig_ObjFaninC1(pObj)? (Aig_Obj_t *)pFanin1->pData : pFanin1->pNext; *ppData = Aig_Or( pNew, Aig_And(pNew, p0Data, Aig_Not(p0Next)), Aig_And(pNew, p1Data, Aig_Not(p1Next)) ); @@ -262,20 +266,20 @@ Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ) Saig_ManForEachLo( p, pObj, i ) { pMiter = Aig_And( pNew, pMiter, - Aig_Or(pNew, pObj->pData, pObj->pNext) ); + Aig_Or(pNew, (Aig_Obj_t *)pObj->pData, pObj->pNext) ); } Aig_ObjCreatePo( pNew, pMiter ); Saig_ManForEachLi( p, pObj, i ) { if ( !Aig_ObjFaninC0(pObj) ) { - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); } else { Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); } } } @@ -285,13 +289,13 @@ Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ) { if ( !Aig_ObjFaninC0(pObj) ) { - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); } else { Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); } } } @@ -396,7 +400,7 @@ Aig_Man_t * Aig_ManDupNodesAll( Aig_Man_t * p, Vec_Ptr_t * vSet ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // Saig_ManForEachPo( p, pObj, i ) // pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); - Vec_PtrForEachEntry( vSet, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSet, pObj, i ) Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) ); Saig_ManForEachLi( p, pObj, i ) pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); @@ -447,7 +451,7 @@ Aig_Man_t * Aig_ManDupNodesHalf( Aig_Man_t * p, Vec_Ptr_t * vSet, int iPart ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // Saig_ManForEachPo( p, pObj, i ) // pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); - Vec_PtrForEachEntry( vSet, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSet, pObj, i ) Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) ); if ( iPart == 0 ) { @@ -712,8 +716,8 @@ int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) ); vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) ); // get the first pair of outputs - pObj0 = Vec_PtrEntry( vPairs, 0 ); - pObj1 = Vec_PtrEntry( vPairs, 1 ); + pObj0 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, 0 ); + pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, 1 ); // label registers reachable from the outputs Aig_ManIncrementTravId( p ); Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj0), 0 ); @@ -724,8 +728,8 @@ int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) // find where each output belongs for ( i = 2; i < Vec_PtrSize(vPairs); i += 2 ) { - pObj0 = Vec_PtrEntry( vPairs, i ); - pObj1 = Vec_PtrEntry( vPairs, i+1 ); + pObj0 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, i ); + pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, i+1 ); Aig_ManIncrementTravId( p ); pFlop0 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj0) ); @@ -862,7 +866,7 @@ int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ) ***********************************************************************/ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVerbose ) { - extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); +// extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); int iOut, nOuts; Aig_Man_t * pMiterCec; int RetValue, clkTotal = clock(); @@ -905,7 +909,7 @@ ABC_PRT( "Time", clock() - clkTotal ); printf( "Counter-example is not available.\n" ); else { - iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts ); + iOut = Ssw_SecCexResimulate( pMiterCec, (int *)pMiterCec->pData, &nOuts ); if ( iOut == -1 ) printf( "Counter-example verification has failed.\n" ); else @@ -993,3 +997,5 @@ int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigPba.c b/src/aig/saig/saigPba.c new file mode 100644 index 00000000..65b39fc0 --- /dev/null +++ b/src/aig/saig/saigPba.c @@ -0,0 +1,752 @@ +/**CFile**************************************************************** + + FileName [saigPba.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: saigPba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" + +#include "cnf.h" +#include "satSolver.h" +#include "satStore.h" +#include "ssw.h" +#include "ioa.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline char Saig_AbsVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { return Vec_StrGetEntry( p, nObjs*i+pObj->Id ); } +static inline void Saig_AbsSetVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { Vec_StrSetEntry( p, nObjs*i+pObj->Id, (char)1 ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Finds the set of clauses involved in the UNSAT core.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsSolverUnsatCore( sat_solver * pSat, int nConfMax, int fVerbose, int * piRetValue ) +{ + Vec_Int_t * vCore; + void * pSatCnf; + Intp_Man_t * pManProof; + int RetValue, clk = clock(); + *piRetValue = -1; + // solve the problem + RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_Undef ) + { + printf( "Conflict limit is reached.\n" ); + return NULL; + } + if ( RetValue == l_True ) + { + printf( "The BMC problem is SAT.\n" ); + *piRetValue = 0; + return NULL; + } + if ( fVerbose ) + { + printf( "SAT solver returned UNSAT after %d conflicts. ", pSat->stats.conflicts ); + ABC_PRT( "Time", clock() - clk ); + } + assert( RetValue == l_False ); + pSatCnf = sat_solver_store_release( pSat ); + // derive the UNSAT core + clk = clock(); + pManProof = Intp_ManAlloc(); + vCore = (Vec_Int_t *)Intp_ManUnsatCore( pManProof, (Sto_Man_t *)pSatCnf, 0 ); + Intp_ManFree( pManProof ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); + if ( fVerbose ) + { + printf( "SAT core contains %d clauses (out of %d). ", Vec_IntSize(vCore), pSat->stats.clauses ); + ABC_PRT( "Time", clock() - clk ); + } + return vCore; +} + + +/**Function************************************************************* + + Synopsis [Mark visited nodes recursively.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * pObj, int i ) +{ + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ) ) + return 1; + Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ); + if ( Saig_ObjIsPi( p, pObj ) ) + return 1; + if ( Saig_ObjIsLo( p, pObj ) ) + { + if ( i == 0 ) + return 1; + return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 ); + } + if ( Aig_ObjIsPo( pObj ) ) + return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); + Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); + Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin1(pObj), i ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Mark visited nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Saig_AbsMarkVisited( Aig_Man_t * p, int nFramesMax ) +{ + Vec_Str_t * vObj2Visit; + Aig_Obj_t * pObj; + int i, f; + vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax ); +// Saig_ManForEachLo( p, pObj, i ) +// Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 ); + for ( f = 0; f < nFramesMax; f++ ) + { + Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f ); + Saig_ManForEachPo( p, pObj, i ) + Saig_AbsMarkVisited_rec( p, vObj2Visit, pObj, f ); + } + return vObj2Visit; +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) +{ + if ( pObj->pData ) + return (Aig_Obj_t *)pObj->pData; + assert( Aig_ObjIsNode(pObj) ); + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin1(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pFrame, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); +} + +/**Function************************************************************* + + Synopsis [Derives a vector of AIG managers, one for each frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose ) +{ + Vec_Ptr_t * vFrames, * vLoObjs, * vLiObjs; + Vec_Str_t * vObj2Visit; + Aig_Man_t * pFrame; + Aig_Obj_t * pObj; + int f, i; + vObj2Visit = Saig_AbsMarkVisited( p, nFramesMax ); + vFrames = Vec_PtrAlloc( nFramesMax ); + vLoObjs = Vec_PtrAlloc( 100 ); + vLiObjs = Vec_PtrAlloc( 100 ); + for ( f = 0; f < nFramesMax; f++ ) + { + Aig_ManCleanData( p ); + pFrame = Aig_ManStart( 1000 ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pFrame); + // create PIs + Vec_PtrClear( vLoObjs ); + Vec_PtrClear( vLiObjs ); + Aig_ManForEachPi( p, pObj, i ) + { + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) + { + pObj->pData = Aig_ObjCreatePi(pFrame); + if ( i >= Saig_ManPiNum(p) ) + Vec_PtrPush( vLoObjs, pObj ); + } + } + // remember the number of (implicit) registers in this frame + pFrame->nAsserts = Vec_PtrSize(vLoObjs); + // create POs + Aig_ManForEachPo( p, pObj, i ) + { + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) + { + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); + pObj->pData = Aig_ObjCreatePo( pFrame, Aig_ObjChild0Copy(pObj) ); + if ( i >= Saig_ManPoNum(p) ) + Vec_PtrPush( vLiObjs, pObj ); + } + } +// Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) ); + Vec_PtrPush( vFrames, Cnf_DeriveSimple(pFrame, Aig_ManPoNum(pFrame)) ); + // set the new PIs to point to the corresponding registers + Aig_ManCleanData( pFrame ); + Vec_PtrForEachEntry( Aig_Obj_t *, vLoObjs, pObj, i ) + ((Aig_Obj_t *)pObj->pData)->pData = pObj; + Vec_PtrForEachEntry( Aig_Obj_t *, vLiObjs, pObj, i ) + ((Aig_Obj_t *)pObj->pData)->pData = pObj; + if ( fVerbose ) + printf( "%3d : PI =%8d. PO =%8d. Flop =%8d. Node =%8d.\n", + f, Aig_ManPiNum(pFrame), Aig_ManPoNum(pFrame), pFrame->nAsserts, Aig_ManNodeNum(pFrame) ); + } + Vec_PtrFree( vLoObjs ); + Vec_PtrFree( vLiObjs ); + Vec_StrFree( vObj2Visit ); + return vFrames; +} + +/**Function************************************************************* + + Synopsis [Derives a vector of AIG managers, one for each frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * Saig_AbsCreateSolverDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames ) +{ + sat_solver * pSat; + Cnf_Dat_t * pCnf, * pCnfPrev; + Vec_Int_t * vPoLits; + Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; + int f, i, Lit, Lits[2], iVarOld, iVarNew, nSatVars, nRegisters; + // start array of output literals + vPoLits = Vec_IntAlloc( 100 ); + // count the number of CNF variables + nSatVars = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + nSatVars += pCnf->nVars; + + // create the SAT solver + pSat = sat_solver_new(); + sat_solver_store_alloc( pSat ); + sat_solver_setnvars( pSat, nSatVars ); + + // add clauses for the timeframes + nSatVars = 0; +// Vec_PtrForEachEntryReverse( Cnf_Dat_t *, vFrames, pCnf, f ) + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + // lift clauses of this CNF + Cnf_DataLift( pCnf, nSatVars ); + nSatVars += pCnf->nVars; + // copy clauses into the manager + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + { + printf( "The BMC problem is trivially UNSAT.\n" ); + sat_solver_delete( pSat ); + Vec_IntFree( vPoLits ); + return NULL; + } + } + // remember output literal + Aig_ManForEachPo( pCnf->pMan, pObjPo, i ) + { + if ( i == Saig_ManPoNum(p) ) + break; + Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); + } + } + + // add auxiliary clauses (output, connectors, initial) + // add output clause + if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) + { + printf( "SAT solver is not created correctly.\n" ); + assert( 0 ); + } + Vec_IntFree( vPoLits ); + + // add connecting clauses + pCnfPrev = (Cnf_Dat_t *)Vec_PtrEntry( vFrames, 0 ); + Vec_PtrForEachEntryStart( Cnf_Dat_t *, vFrames, pCnf, f, 1 ) + { + nRegisters = pCnf->pMan->nAsserts; + assert( nRegisters <= Aig_ManPoNum(pCnfPrev->pMan) ); + assert( nRegisters <= Aig_ManPiNum(pCnf->pMan) ); + for ( i = 0; i < nRegisters; i++ ) + { + pObjLi = Aig_ManPo( pCnfPrev->pMan, Aig_ManPoNum(pCnfPrev->pMan) - nRegisters + i ); + pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); + // get variable numbers + iVarOld = pCnfPrev->pVarNums[pObjLi->Id]; + iVarNew = pCnf->pVarNums[pObjLo->Id]; + // add clauses connecting existing variables + Lits[0] = toLitCond( iVarOld, 0 ); + Lits[1] = toLitCond( iVarNew, 1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( iVarOld, 1 ); + Lits[1] = toLitCond( iVarNew, 0 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + pCnfPrev = pCnf; + } + // add unit clauses + pCnf = (Cnf_Dat_t *)Vec_PtrEntry( vFrames, 0 ); + nRegisters = pCnf->pMan->nAsserts; + for ( i = 0; i < nRegisters; i++ ) + { + pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); + assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); + Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); + if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) + assert( 0 ); + } + sat_solver_store_mark_roots( pSat ); + return pSat; +} + + +/**Function************************************************************* + + Synopsis [Creates SAT solver for BMC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * Saig_AbsCreateSolver( Cnf_Dat_t * pCnf, int nFrames ) +{ + sat_solver * pSat; + Vec_Int_t * vPoLits; + Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; + int f, i, Lit, Lits[2], iVarOld, iVarNew; + // start array of output literals + vPoLits = Vec_IntAlloc( nFrames * Saig_ManPoNum(pCnf->pMan) ); + // create the SAT solver + pSat = sat_solver_new(); + sat_solver_store_alloc( pSat ); + sat_solver_setnvars( pSat, pCnf->nVars * nFrames ); + + // add clauses for the timeframes + for ( f = 0; f < nFrames; f++ ) + { + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + { + printf( "The BMC problem is trivially UNSAT.\n" ); + sat_solver_delete( pSat ); + Vec_IntFree( vPoLits ); + return NULL; + } + } + // remember output literal + Saig_ManForEachPo( pCnf->pMan, pObjPo, i ) + Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); + // lift CNF to the next frame + Cnf_DataLift( pCnf, pCnf->nVars ); + } + // put CNF back to the original level + Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); + + // add auxiliary clauses (output, connectors, initial) + // add output clause + if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) + assert( 0 ); + Vec_IntFree( vPoLits ); + // add connecting clauses + for ( f = 0; f < nFrames; f++ ) + { + // connect to the previous timeframe + if ( f > 0 ) + { + Saig_ManForEachLiLo( pCnf->pMan, pObjLi, pObjLo, i ) + { + iVarOld = pCnf->pVarNums[pObjLi->Id] - pCnf->nVars; + iVarNew = pCnf->pVarNums[pObjLo->Id]; + // add clauses connecting existing variables + Lits[0] = toLitCond( iVarOld, 0 ); + Lits[1] = toLitCond( iVarNew, 1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( iVarOld, 1 ); + Lits[1] = toLitCond( iVarNew, 0 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + } + // lift CNF to the next frame + Cnf_DataLift( pCnf, pCnf->nVars ); + } + // put CNF back to the original level + Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); + // add unit clauses + Saig_ManForEachLo( pCnf->pMan, pObjLo, i ) + { + assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); + Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); + if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) + assert( 0 ); + } + sat_solver_store_mark_roots( pSat ); + return pSat; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsCollectRegistersDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames, Vec_Int_t * vCore ) +{ + Aig_Obj_t * pObj; + Cnf_Dat_t * pCnf; + Vec_Int_t * vFlops; + int * pVars, * pFlops; + int i, f, iClause, iReg, * piLit, nSatVars, nSatClauses; + // count the number of CNF variables + nSatVars = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + nSatVars += pCnf->nVars; + // mark register variables + pVars = ABC_ALLOC( int, nSatVars ); + for ( i = 0; i < nSatVars; i++ ) + pVars[i] = -1; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + Aig_ManForEachPi( pCnf->pMan, pObj, i ) + { + assert( pCnf->pVarNums[pObj->Id] >= 0 ); + assert( pCnf->pVarNums[pObj->Id] < nSatVars ); + if ( pObj->pData == NULL ) + continue; + iReg = Aig_ObjPioNum((Aig_Obj_t *)pObj->pData) - Saig_ManPiNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; + } + Aig_ManForEachPo( pCnf->pMan, pObj, i ) + { + assert( pCnf->pVarNums[pObj->Id] >= 0 ); + assert( pCnf->pVarNums[pObj->Id] < nSatVars ); + if ( pObj->pData == NULL ) + continue; + iReg = Aig_ObjPioNum((Aig_Obj_t *)pObj->pData) - Saig_ManPoNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; + } + } + // mark used registers + pFlops = ABC_CALLOC( int, Aig_ManRegNum(p) ); + Vec_IntForEachEntry( vCore, iClause, i ) + { + nSatClauses = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + if ( iClause < nSatClauses + pCnf->nClauses ) + break; + nSatClauses += pCnf->nClauses; + } + if ( f == Vec_PtrSize(vFrames) ) + continue; + iClause = iClause - nSatClauses; + assert( iClause >= 0 ); + assert( iClause < pCnf->nClauses ); + // consider the clause + for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) + { + iReg = pVars[ lit_var(*piLit) ]; + if ( iReg >= 0 ) + pFlops[iReg] = 1; + } + } + // collect registers + vFlops = Vec_IntAlloc( Aig_ManRegNum(p) ); + for ( i = 0; i < Aig_ManRegNum(p); i++ ) + if ( pFlops[i] ) + Vec_IntPush( vFlops, i ); + ABC_FREE( pFlops ); + ABC_FREE( pVars ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsCollectRegisters( Cnf_Dat_t * pCnf, int nFrames, Vec_Int_t * vCore ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vFlops; + int * pVars, * pFlops; + int i, iClause, iReg, * piLit; + // mark register variables + pVars = ABC_ALLOC( int, pCnf->nVars ); + for ( i = 0; i < pCnf->nVars; i++ ) + pVars[i] = -1; + Saig_ManForEachLi( pCnf->pMan, pObj, i ) + pVars[ pCnf->pVarNums[pObj->Id] ] = i; + Saig_ManForEachLo( pCnf->pMan, pObj, i ) + pVars[ pCnf->pVarNums[pObj->Id] ] = i; + // mark used registers + pFlops = ABC_CALLOC( int, Aig_ManRegNum(pCnf->pMan) ); + Vec_IntForEachEntry( vCore, iClause, i ) + { + // skip auxiliary clauses + if ( iClause >= pCnf->nClauses * nFrames ) + continue; + // consider the clause + iClause = iClause % pCnf->nClauses; + for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) + { + iReg = pVars[ lit_var(*piLit) ]; + if ( iReg >= 0 ) + pFlops[iReg] = 1; + } + } + // collect registers + vFlops = Vec_IntAlloc( Aig_ManRegNum(pCnf->pMan) ); + for ( i = 0; i < Aig_ManRegNum(pCnf->pMan); i++ ) + if ( pFlops[i] ) + Vec_IntPush( vFlops, i ); + ABC_FREE( pFlops ); + ABC_FREE( pVars ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_AbsFreeCnfs( Vec_Ptr_t * vFrames ) +{ + Cnf_Dat_t * pCnf; + int i; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, i ) + { + Aig_ManStop( pCnf->pMan ); + Cnf_DataFree( pCnf ); + } + Vec_PtrFree( vFrames ); +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) +{ + Vec_Ptr_t * vFlopPtrs, * vSupp; + Aig_Obj_t * pObj; + int i, Entry; + // collect latch inputs + vFlopPtrs = Vec_PtrAlloc( 1000 ); + Vec_IntForEachEntry( vFlops, Entry, i ) + { + Vec_PtrPush( vFlopPtrs, Saig_ManLi(p, Entry) ); + pObj = Saig_ManLo(p, Entry); + pObj->fMarkA = 1; + } + // collect latch outputs + vSupp = Vec_PtrAlloc( 1000 ); + Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vFlopPtrs), Vec_PtrSize(vFlopPtrs), vSupp ); + Vec_PtrFree( vFlopPtrs ); + // mark influencing flops + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + pObj->fMarkA = 1; + Vec_PtrFree( vSupp ); + // reload flops + Vec_IntClear( vFlops ); + Aig_ManForEachPi( p, pObj, i ) + { + if ( pObj->fMarkA == 0 ) + continue; + pObj->fMarkA = 0; + if ( Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) >= 0 ) + Vec_IntPush( vFlops, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); + } +} + + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + sat_solver * pSat; + Vec_Ptr_t * vFrames = NULL; + Vec_Int_t * vCore; + Cnf_Dat_t * pCnf = NULL; + int clk = clock(), clk2 = clock(); + if ( pPars->fVerbose ) + printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", pPars->nFramesMax, pPars->nConfMax ); + assert( Aig_ManRegNum(p) > 0 ); + Aig_ManSetPioNumbers( p ); + if ( pPars->fDynamic ) + { + // create CNF for the frames + vFrames = Saig_AbsCreateFrames( p, pPars->nFramesMax, pPars->fVerbose ); + // create dynamic solver + pSat = Saig_AbsCreateSolverDyn( p, vFrames ); + } + else + { + // create CNF for the AIG + pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) ); + // create SAT solver for the unrolled AIG + pSat = Saig_AbsCreateSolver( pCnf, pPars->nFramesMax ); + } + if ( pPars->fVerbose ) + { + printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses ); + ABC_PRT( "Time", clock() - clk2 ); + } + // compute UNSAT core + vCore = Saig_AbsSolverUnsatCore( pSat, pPars->nConfMax, pPars->fVerbose, &pPars->Status ); + sat_solver_delete( pSat ); + if ( vCore == NULL ) + { + if ( vFrames ) + Saig_AbsFreeCnfs( vFrames ); + return NULL; + } + pPars->nFramesDone = pPars->nFramesMax; + // collect registers + if ( pPars->fDynamic ) + { + vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore ); + Saig_AbsFreeCnfs( vFrames ); + } + else + { + vFlops = Saig_AbsCollectRegisters( pCnf, pPars->nFramesMax, vCore ); + Cnf_DataFree( pCnf ); + } + Vec_IntFree( vCore ); + if ( pPars->fVerbose ) + { + printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) ); + ABC_PRT( "Time", clock() - clk ); + } + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pAbs = NULL; + vFlops = Saig_ManProofAbstractionFlops( p, pPars ); + // write the final result + if ( vFlops ) + { + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); + printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); + Vec_IntFree( vFlops ); + } + return pAbs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigPhase.c b/src/aig/saig/saigPhase.c index c67949b5..340910d0 100644 --- a/src/aig/saig/saigPhase.c +++ b/src/aig/saig/saigPhase.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + /* The algorithm is described in the paper: Per Bjesse and Jim Kukula, "Automatic Phase Abstraction for Formal Verification", ICCAD 2005 @@ -228,7 +231,7 @@ int Saig_TsiCountNonXValuedRegisters( Saig_Tsim_t * p, int nWords, int nPref ) p->vNonXRegs = Vec_IntAlloc( 10 ); for ( i = 0; i < nRegs; i++ ) { - Vec_PtrForEachEntryStart( p->vStates, pState, k, nPref ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, k, nPref ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); assert( Value != 0 ); @@ -261,7 +264,7 @@ void Saig_TsiPrintTraces( Saig_Tsim_t * p, int nWords, int nPrefix ) return; for ( i = 0; i < nRegs; i++ ) { - Vec_PtrForEachEntry( p->vStates, pState, k ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); if ( Value == SAIG_XVSX ) @@ -273,7 +276,7 @@ void Saig_TsiPrintTraces( Saig_Tsim_t * p, int nWords, int nPrefix ) continue; // print trace printf( "%5d : %5d %5d ", Counter, i, Saig_ManLo(p->pAig, i)->Id ); - Vec_PtrForEachEntryStop( p->vStates, pState, k, Vec_PtrSize(p->vStates)-1 ) + Vec_PtrForEachEntryStop( unsigned *, p->vStates, pState, k, Vec_PtrSize(p->vStates)-1 ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); if ( Value == SAIG_XVS0 ) @@ -310,7 +313,7 @@ int Saig_TsiComputePrefix( Saig_Tsim_t * p, unsigned * pState, int nWords ) for ( pEntry = p->pBins[Hash]; pEntry; pEntry = Saig_TsiNext(pEntry, nWords) ) if ( !memcmp( pEntry, pState, sizeof(unsigned) * nWords ) ) { - Vec_PtrForEachEntry( p->vStates, pPrev, i ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pPrev, i ) { if ( pPrev == pEntry ) return i; @@ -449,7 +452,7 @@ void Saig_TsiStateOrAll( Saig_Tsim_t * pTsi, unsigned * pState ) { unsigned * pPrev; int i, k; - Vec_PtrForEachEntry( pTsi->vStates, pPrev, i ) + Vec_PtrForEachEntry( unsigned *, pTsi->vStates, pPrev, i ) { for ( k = 0; k < pTsi->nWords; k++ ) pState[k] |= pPrev[k]; @@ -616,9 +619,9 @@ int Saig_ManFindRegisters( Saig_Tsim_t * pTsi, int nFrames, int fIgnore, int fVe for ( k = 0; k < nTests; k++ ) { if ( k < pTsi->nPrefix + pTsi->nCycle ) - pState = Vec_PtrEntry( pTsi->vStates, k ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, k ); else - pState = Vec_PtrEntry( pTsi->vStates, k - pTsi->nCycle ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, k - pTsi->nCycle ); Value = (Aig_InfoHasBit( pState, 2 * Reg + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * Reg ); assert( Value == SAIG_XVS0 || Value == SAIG_XVS1 ); if ( k < nFrames || (fIgnore && k == nFrames) ) @@ -721,7 +724,7 @@ Aig_Man_t * Saig_ManPerformAbstraction( Saig_Tsim_t * pTsi, int nFrames, int fVe Vec_IntForEachEntry( pTsi->vNonXRegs, Reg, i ) { pObj = Saig_ManLo( pAig, Reg ); - pState = Vec_PtrEntry( pTsi->vStates, f ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, f ); Value = (Aig_InfoHasBit( pState, 2 * Reg + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * Reg ); assert( Value == SAIG_XVS0 || Value == SAIG_XVS1 ); pObjNew = (Value == SAIG_XVS1)? Aig_ManConst1(pFrames) : Aig_ManConst0(pFrames); @@ -766,6 +769,37 @@ Aig_Man_t * Saig_ManPerformAbstraction( Saig_Tsim_t * pTsi, int nFrames, int fVe return pFrames; } + +/**Function************************************************************* + + Synopsis [Performs automated phase abstraction.] + + Description [Takes the AIG manager and the array of initial states.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManPhaseFrameNum( Aig_Man_t * p, Vec_Int_t * vInits ) +{ + Saig_Tsim_t * pTsi; + int nFrames, nPrefix; + assert( Saig_ManRegNum(p) ); + assert( Saig_ManPiNum(p) ); + assert( Saig_ManPoNum(p) ); + // perform terminary simulation + pTsi = Saig_ManReachableTernary( p, vInits, 0 ); + if ( pTsi == NULL ) + return 1; + // derive information + nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + nFrames = Vec_PtrSize(pTsi->vStates) - 1 - nPrefix; + Saig_TsiStop( pTsi ); + // potentially, may need to reduce nFrames if nPrefix is less than nFrames + return nFrames; +} + /**Function************************************************************* Synopsis [Performs automated phase abstraction.] @@ -789,7 +823,7 @@ Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrame if ( pTsi == NULL ) return NULL; // derive information - pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix; pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, ABC_MIN(pTsi->nPrefix,nPref)); // print statistics @@ -845,7 +879,7 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose ) if ( pTsi == NULL ) return NULL; // derive information - pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix; pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, 0); // print statistics @@ -903,3 +937,5 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetFwd.c b/src/aig/saig/saigRetFwd.c index 8178d26e..94d08aaf 100644 --- a/src/aig/saig/saigRetFwd.c +++ b/src/aig/saig/saigRetFwd.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -240,3 +243,5 @@ Aig_Man_t * Saig_ManRetimeForward( Aig_Man_t * p, int nMaxIters, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetMin.c b/src/aig/saig/saigRetMin.c index b9204f44..cce7dcc6 100644 --- a/src/aig/saig/saigRetMin.c +++ b/src/aig/saig/saigRetMin.c @@ -20,16 +20,18 @@ #include "saig.h" +#include "nwk.h" #include "cnf.h" #include "satSolver.h" #include "satStore.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -55,7 +57,7 @@ Vec_Int_t * Saig_ManRetimeInitState( Aig_Man_t * p ) int i, RetValue, * pModel; // solve the SAT problem pCnf = Cnf_DeriveSimpleForRetiming( p ); - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { Cnf_DataFree( pCnf ); @@ -126,9 +128,9 @@ int Saig_ManRetimeUnsatCore( Aig_Man_t * p, int fVerbose ) sat_solver_delete( pSat ); // derive the UNSAT core pManProof = Intp_ManAlloc(); - vCore = Intp_ManUnsatCore( pManProof, pSatCnf, fVeryVerbose ); + vCore = (Vec_Int_t *)Intp_ManUnsatCore( pManProof, (Sto_Man_t *)pSatCnf, fVeryVerbose ); Intp_ManFree( pManProof ); - Sto_ManFree( pSatCnf ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); // derive the set of variables on which the core depends // collect the variable numbers nVars = 0; @@ -216,7 +218,7 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut ) int i, RetValue; // mark the cones Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) Saig_ManMarkCone_rec( p, pObj ); // collect the new cut vNodes = Vec_PtrAlloc( 1000 ); @@ -237,7 +239,7 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut ) pFanin->fMarkA = 1; } } - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) pObj->fMarkA = 0; RetValue = Vec_PtrSize( vNodes ); Vec_PtrFree( vNodes ); @@ -296,7 +298,7 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut ) Saig_ManForEachPi( p, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), pObj->fPhase ); // duplicate logic above the cut Aig_ManForEachPo( p, pObj, i ) @@ -311,14 +313,14 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut ) Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) pObjLo->pData = pObjLi->pData; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) if ( Aig_ObjIsNode(pObj) ) pObj->pData = NULL; // duplicate logic below the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) { Saig_ManRetimeDup_rec( pNew, pObj ); - Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, pObj->fPhase) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)pObj->pData, pObj->fPhase) ); } Aig_ManCleanup( pNew ); return pNew; @@ -355,7 +357,7 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManForEachPi( p, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), vInit?Vec_IntEntry(vInit,i):0 ); // duplicate logic above the cut and remember values Saig_ManForEachLi( p, pObj, i ) @@ -367,7 +369,7 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) pObjLo->pData = pObjLi->pData; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) if ( Aig_ObjIsNode(pObj) ) pObj->pData = NULL; // replicate the data on the constant node and the PIs @@ -381,10 +383,10 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) ); Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); } - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) { Saig_ManRetimeDup_rec( pNew, pObj ); - Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, vInit?Vec_IntEntry(vInit,i):0) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)pObj->pData, vInit?Vec_IntEntry(vInit,i):0) ); } Aig_ManCleanup( pNew ); return pNew; @@ -414,7 +416,7 @@ Aig_Man_t * Saig_ManRetimeDupInitState( Aig_Man_t * p, Vec_Ptr_t * vCut ) Aig_ManCleanData( p ); Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_ObjCreatePi(pNew); // duplicate logic above the cut and create POs Saig_ManForEachLi( p, pObj, i ) @@ -503,7 +505,7 @@ int Saig_ManHideBadRegs( Aig_Man_t * p, Vec_Ptr_t * vBadRegs ) nTruePo = Aig_ManPoNum(p) - Aig_ManRegNum(p); assert( nTruePi == p->nTruePis ); assert( nTruePo == p->nTruePos ); - Vec_PtrForEachEntry( vBadRegs, pObjLi, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vBadRegs, pObjLi, i ) { Vec_PtrWriteEntry( vPisNew, nTruePi++, pObjLi->pData ); Vec_PtrWriteEntry( vPosNew, nTruePo++, pObjLi ); @@ -699,3 +701,5 @@ Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnl //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetStep.c b/src/aig/saig/saigRetStep.c index e2502761..aa1ae8a4 100644 --- a/src/aig/saig/saigRetStep.c +++ b/src/aig/saig/saigRetStep.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -229,3 +232,5 @@ int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigScl.c b/src/aig/saig/saigScl.c index 6d55943a..4b0a3102 100644 --- a/src/aig/saig/saigScl.c +++ b/src/aig/saig/saigScl.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -108,3 +111,5 @@ int Saig_ManReportComplements( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimExt.c b/src/aig/saig/saigSimExt.c index 22d5d6b8..9828d17e 100644 --- a/src/aig/saig/saigSimExt.c +++ b/src/aig/saig/saigSimExt.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -49,13 +52,13 @@ static inline int Saig_ManSimInfoAnd( int Value0, int Value1 ) static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) { - unsigned * pInfo = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + 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 = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + 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)); @@ -107,7 +110,7 @@ int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) SeeAlso [] ***********************************************************************/ -int Saig_ManSimDataInit( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ) +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; @@ -146,7 +149,7 @@ int Saig_ManSimDataInit( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, SeeAlso [] ***********************************************************************/ -int Saig_ManExtendOne( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, +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_ManPi(p, iPi); @@ -247,7 +250,7 @@ void Saig_ManExtendUndo( Aig_Man_t * p, Vec_Ptr_t * vSimInfo, Vec_Int_t * vUndo SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +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; @@ -297,14 +300,244 @@ Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Ssw_C SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Ssw_Cex_t * pCex, int fVerbose ) +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) >= Aig_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) >= Aig_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) >= Aig_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 fVerbose ) { Vec_Int_t * vRes; Vec_Ptr_t * vSimInfo; int 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_ManPiNum(p), pCex->nPis ); + return NULL; + } Aig_ManFanoutStart( p ); vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Aig_BitWordNum(2*(pCex->iFrame+1)) ); + Vec_PtrCleanSimInfo( vSimInfo, 0, Aig_BitWordNum(2*(pCex->iFrame+1)) ); + clk = clock(); +// vRes = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); vRes = Saig_ManExtendCounterExample( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); if ( fVerbose ) { @@ -314,8 +547,6 @@ ABC_PRT( "Time", clock() - clk ); Vec_PtrFree( vSimInfo ); Aig_ManFanoutStop( p ); return vRes; -// Vec_IntFree( vRes ); -// return NULL; } //////////////////////////////////////////////////////////////////////// @@ -323,3 +554,5 @@ ABC_PRT( "Time", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimFast.c b/src/aig/saig/saigSimFast.c index 05f77f8a..1840eaa7 100644 --- a/src/aig/saig/saigSimFast.c +++ b/src/aig/saig/saigSimFast.c @@ -20,6 +20,11 @@ #include "saig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -247,7 +252,7 @@ static inline unsigned Faig_SimulateTransferShift( unsigned uOld, unsigned uNew ***********************************************************************/ int * Faig_ManSimulateFrames( Faig_Man_t * p, int nFrames, int nPref, int fTrans ) { - int * pNumOnes = ABC_CALLOC( unsigned, p->nObjs ); + int * pNumOnes = ABC_CALLOC( int, p->nObjs ); unsigned * pSimInfo = ABC_ALLOC( unsigned, p->nObjs ); int f, i; //printf( "Allocating %7.2f Mb.\n", 1.0 * 4 * p->nObjs/(1<<20) ); @@ -338,7 +343,6 @@ float Faig_ManComputeProbOne( int nOnes, int nSimWords ) ***********************************************************************/ Vec_Int_t * Faig_ManComputeSwitchProbs4( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); int fTrans = 1; Faig_Man_t * pAig; Vec_Int_t * vSwitching; @@ -442,3 +446,5 @@ Vec_Int_t * Saig_ManComputeSwitchProb3s( Aig_Man_t * p, int nFrames, int nPref, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimMv.c b/src/aig/saig/saigSimMv.c index a3fdaf93..90c6cb33 100644 --- a/src/aig/saig/saigSimMv.c +++ b/src/aig/saig/saigSimMv.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -61,7 +64,7 @@ struct Saig_MvMan_t_ Saig_MvObj_t * pAigOld; // AIG objects Vec_Ptr_t * vFlops; // collected flops Vec_Ptr_t * vTired; // collected flops - int * pTStates; // hash table for states + unsigned * pTStates; // hash table for states int nTStatesSize; // hash table size Aig_MmFixed_t * pMemStates; // memory for states Vec_Ptr_t * vStates; // reached states @@ -213,7 +216,7 @@ Saig_MvMan_t * Saig_MvManStart( Aig_Man_t * pAig ) // compacted AIG p->pAigOld = Saig_ManCreateReducedAig( pAig, &p->vFlops ); p->nTStatesSize = Aig_PrimeCudd( p->nStatesMax ); - p->pTStates = ABC_CALLOC( int, p->nTStatesSize ); + p->pTStates = ABC_CALLOC( unsigned, p->nTStatesSize ); p->pMemStates = Aig_MmFixedStart( sizeof(int) * (p->nFlops+1), p->nStatesMax ); p->vStates = Vec_PtrAlloc( p->nStatesMax ); Vec_PtrPush( p->vStates, NULL ); @@ -422,7 +425,7 @@ printf( "%d = %d%s * %d%s --> %d\n", pEntry - p->pAigOld, assert( 0 ); } Vec_PtrClear( p->vTired ); - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { NewValue = Saig_MvSimulateValue0(p->pAigOld, pEntry); if ( NewValue != (int)pEntry->Value ) @@ -451,7 +454,7 @@ printf( "\n" ); SeeAlso [] ***********************************************************************/ -int Saig_MvSimHash( int * pState, int nFlops, int TableSize ) +int Saig_MvSimHash( unsigned * pState, int nFlops, int TableSize ) { static int s_SPrimes[128] = { 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, @@ -486,12 +489,12 @@ int Saig_MvSimHash( int * pState, int nFlops, int TableSize ) SeeAlso [] ***********************************************************************/ -static inline int * Saig_MvSimTableFind( Saig_MvMan_t * p, int * pState ) +static inline unsigned * Saig_MvSimTableFind( Saig_MvMan_t * p, unsigned * pState ) { - int * pEntry; - int * pPlace = p->pTStates + Saig_MvSimHash( pState+1, p->nFlops, p->nTStatesSize ); - for ( pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL; pEntry; - pPlace = pEntry, pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL ) + unsigned * pEntry; + unsigned * pPlace = p->pTStates + Saig_MvSimHash( pState+1, p->nFlops, p->nTStatesSize ); + for ( pEntry = (*pPlace)? (unsigned *)Vec_PtrEntry(p->vStates, *pPlace) : NULL; pEntry; + pPlace = pEntry, pEntry = (*pPlace)? (unsigned *)Vec_PtrEntry(p->vStates, *pPlace) : NULL ) if ( memcmp( pEntry+1, pState+1, sizeof(int)*p->nFlops ) == 0 ) break; return pPlace; @@ -511,12 +514,13 @@ static inline int * Saig_MvSimTableFind( Saig_MvMan_t * p, int * pState ) int Saig_MvSaveState( Saig_MvMan_t * p, int * piReg ) { Saig_MvObj_t * pEntry; - int i, k, * pState, * pPlace, nMaxUndefs = 0; + unsigned * pState, * pPlace; + int i, k, nMaxUndefs = 0; int iTimesOld, iTimesNew; *piReg = -1; - pState = (int *)Aig_MmFixedEntryFetch( p->pMemStates ); + pState = (unsigned *)Aig_MmFixedEntryFetch( p->pMemStates ); pState[0] = 0; - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { iTimesOld = p->nRegsValues[i]; // count the number of different def values @@ -585,21 +589,22 @@ int Saig_MvSaveState( Saig_MvMan_t * p, int * piReg ) void Saig_MvManPostProcess( Saig_MvMan_t * p, int iState ) { Saig_MvObj_t * pEntry; - int i, k, j, nTotal = 0, * pState, Counter = 0, iFlop; + unsigned * pState; + int i, k, j, nTotal = 0, Counter = 0, iFlop; Vec_Int_t * vUniques = Vec_IntAlloc( 100 ); Vec_Int_t * vCounter = Vec_IntAlloc( 100 ); // count registers that never became undef - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) if ( p->pRegsUndef[i] == 0 ) nTotal++; printf( "The number of registers that never became undef = %d. (Total = %d.)\n", nTotal, p->nFlops ); - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { if ( p->pRegsUndef[i] ) continue; Vec_IntForEachEntry( vUniques, iFlop, k ) { - Vec_PtrForEachEntryStart( p->vStates, pState, j, 1 ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, j, 1 ) if ( pState[iFlop+1] != pState[i+1] ) break; if ( j == Vec_PtrSize(p->vStates) ) @@ -625,7 +630,7 @@ void Saig_MvManPostProcess( Saig_MvMan_t * p, int iState ) printf( "%d ", p->pRegsValues[iFlop][k] ); printf( "\n" ); */ - Vec_PtrForEachEntryStart( p->vStates, pState, k, 1 ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, k, 1 ) { if ( k == iState+1 ) printf( " # " ); @@ -664,7 +669,7 @@ int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose ) ABC_PRT( "Constructing the problem", clock() - clk ); clk = clock(); // initiliaze registers - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { pEntry->Value = Saig_MvConst0(); if ( pEntry->iFan0 == 1 ) @@ -706,7 +711,7 @@ ABC_PRT( "Constructing the problem", clock() - clk ); printf( "Retiring flop %d.\n", iRegMax ); */ // printf( "Retiring %d flops.\n", Vec_PtrSize(p->vTired) ); - Vec_PtrForEachEntry( p->vTired, pEntry, k ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vTired, pEntry, k ) pEntry->Value = Saig_MvUndef(); } } @@ -724,3 +729,5 @@ ABC_PRT( "Multi-value simulation", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimSeq.c b/src/aig/saig/saigSimSeq.c index c527b152..37bb12b5 100644 --- a/src/aig/saig/saigSimSeq.c +++ b/src/aig/saig/saigSimSeq.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -52,7 +55,7 @@ struct Raig_Man_t_ int nWordsAlloc; // the number of allocated entries int nMems; // the number of used entries int nMemsMax; // the max number of used entries - int MemFree; // next ABC_FREE entry + int MemFree; // next free entry }; static inline int Raig_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } @@ -228,7 +231,7 @@ unsigned * Raig_ManSimRef( Raig_Man_t * p, int i ) assert( p->pSims[i] == 0 ); if ( p->MemFree == 0 ) { - int * pPlace, Ent; + unsigned * pPlace, Ent; if ( p->nWordsAlloc == 0 ) { assert( p->pMems == NULL ); @@ -238,9 +241,9 @@ unsigned * Raig_ManSimRef( Raig_Man_t * p, int i ) p->nWordsAlloc *= 2; p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc ); memset( p->pMems, 0xff, sizeof(unsigned) * (p->nWords + 1) ); - pPlace = &p->MemFree; + pPlace = (unsigned *)&p->MemFree; for ( Ent = p->nMems * (p->nWords + 1); - Ent + p->nWords + 1 < p->nWordsAlloc; + Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc; Ent += p->nWords + 1 ) { *pPlace = Ent; @@ -410,9 +413,9 @@ int Raig_ManSimulateRound( Raig_Man_t * p, int fMiter, int fFirst, int * piPat ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) +Abc_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) { - Ssw_Cex_t * p; + Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); @@ -511,3 +514,5 @@ int Raig_ManSimulate( Aig_Man_t * pAig, int nWords, int nIters, int TimeLimit, i //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigStrSim.c b/src/aig/saig/saigStrSim.c index 9e50c9b6..1d69630f 100644 --- a/src/aig/saig/saigStrSim.c +++ b/src/aig/saig/saigStrSim.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,7 +69,7 @@ unsigned Saig_StrSimHash( Aig_Obj_t * pObj ) unsigned uHash = 0; int i; assert( SAIG_WORDS <= 128 ); - pSims = pObj->pData; + pSims = (unsigned *)pObj->pData; for ( i = 0; i < SAIG_WORDS; i++ ) uHash ^= pSims[i] * s_SPrimes[i & 0x7F]; return uHash; @@ -85,8 +88,8 @@ unsigned Saig_StrSimHash( Aig_Obj_t * pObj ) ***********************************************************************/ int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims0[i] != pSims1[i] ) @@ -107,7 +110,7 @@ int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ int Saig_StrSimIsZero( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims[i] != 0 ) @@ -128,7 +131,7 @@ int Saig_StrSimIsZero( Aig_Obj_t * pObj ) ***********************************************************************/ int Saig_StrSimIsOne( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims[i] != ~0 ) @@ -149,7 +152,7 @@ int Saig_StrSimIsOne( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignRandom( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims[i] = Aig_ManRandom(0); @@ -168,7 +171,7 @@ void Saig_StrSimAssignRandom( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignOne( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims[i] = ~0; @@ -187,7 +190,7 @@ void Saig_StrSimAssignOne( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; pSims[0] = 0; } @@ -204,9 +207,9 @@ void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i ) { - unsigned * pSims = pObj->pData; - unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; - unsigned * pSims1 = Aig_ObjFanin1(pObj)->pData; + unsigned * pSims = (unsigned *)pObj->pData; + unsigned * pSims0 = (unsigned *)Aig_ObjFanin0(pObj)->pData; + unsigned * pSims1 = (unsigned *)Aig_ObjFanin1(pObj)->pData; if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) pSims[i] = ~(pSims0[i] | pSims1[i]); else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) ) @@ -230,8 +233,8 @@ void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i ) ***********************************************************************/ void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i ) { - unsigned * pSims = pObj->pData; - unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; + unsigned * pSims = (unsigned *)pObj->pData; + unsigned * pSims0 = (unsigned *)Aig_ObjFanin0(pObj)->pData; if ( Aig_ObjFaninC0(pObj) ) pSims[i] = ~pSims0[i]; else @@ -251,8 +254,8 @@ void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i ) ***********************************************************************/ void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims1[i] = pSims0[i]; @@ -271,8 +274,8 @@ void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ void Saig_StrSimTransferNext( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int i ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; assert( i < SAIG_WORDS - 1 ); pSims1[i+1] = pSims0[i]; } @@ -520,7 +523,7 @@ void Saig_StrSimPrepareAig( Aig_Man_t * p ) // allocate simulation info p->pData2 = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), SAIG_WORDS ); Aig_ManForEachObj( p, pObj, i ) - pObj->pData = Vec_PtrEntry( p->pData2, i ); + pObj->pData = Vec_PtrEntry( (Vec_Ptr_t *)p->pData2, i ); // set simulation info for constant1 and register outputs Saig_StrSimAssignOne( Aig_ManConst1(p) ); Saig_ManForEachLo( p, pObj, i ) @@ -821,7 +824,7 @@ void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fV { Ssw_StrSimMatchingExtendOne( p0, vNodes0 ); Ssw_StrSimMatchingExtendOne( p1, vNodes1 ); - Vec_PtrForEachEntry( vNodes0, pNext0, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pNext0, k ) { pNext1 = Aig_ObjRepr( p0, pNext0 ); if ( pNext1 == NULL ) @@ -832,7 +835,7 @@ void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fV Aig_ObjSetRepr( p0, pNext0, NULL ); Aig_ObjSetRepr( p1, pNext1, NULL ); } - Vec_PtrForEachEntry( vNodes1, pNext1, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pNext1, k ) { pNext0 = Aig_ObjRepr( p1, pNext1 ); if ( pNext0 == NULL ) @@ -932,8 +935,8 @@ Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDis break; } // cleanup - Vec_PtrFree( pPart0->pData2 ); pPart0->pData2 = NULL; - Vec_PtrFree( pPart1->pData2 ); pPart1->pData2 = NULL; + Vec_PtrFree( (Vec_Ptr_t *)pPart0->pData2 ); pPart0->pData2 = NULL; + Vec_PtrFree( (Vec_Ptr_t *)pPart1->pData2 ); pPart1->pData2 = NULL; // extend the islands Aig_ManFanoutStart( pPart0 ); Aig_ManFanoutStart( pPart1 ); @@ -969,3 +972,5 @@ Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDis //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSwitch.c b/src/aig/saig/saigSwitch.c index 122483d2..bbad9be4 100644 --- a/src/aig/saig/saigSwitch.c +++ b/src/aig/saig/saigSwitch.c @@ -20,6 +20,11 @@ #include "saig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -260,7 +265,6 @@ float Saig_ManComputeProbOnePlus( int nOnes, int nSimWords, int fCompl ) ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProb4s( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); Saig_SimObj_t * pAig, * pEntry; Vec_Int_t * vSwitching; float * pSwitching; @@ -564,3 +568,5 @@ Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSynch.c b/src/aig/saig/saigSynch.c index b29fcb9b..00f7517e 100644 --- a/src/aig/saig/saigSynch.c +++ b/src/aig/saig/saigSynch.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -75,7 +78,7 @@ void Saig_SynchSetConstant1( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords unsigned * pSim; int w; pObj = Aig_ManConst1( pAig ); - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = 0x55555555; } @@ -98,7 +101,7 @@ void Saig_SynchInitRegsTernary( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor int i, w; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = 0xffffffff; } @@ -122,7 +125,7 @@ void Saig_SynchInitRegsBinary( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWord int i, w; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( pObj->fMarkA ); } @@ -146,7 +149,7 @@ void Saig_SynchInitPisRandom( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords int i, w; Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchRandomBinary(); } @@ -170,7 +173,7 @@ void Saig_SynchInitPisGiven( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, int i, w; Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( pValues[i] ); } @@ -195,9 +198,9 @@ void Saig_SynchTernarySimulate( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor // simulate nodes Aig_ManForEachNode( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); - pSim0 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); - pSim1 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId1(pObj) ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId1(pObj) ); if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) { for ( w = 0; w < nWords; w++ ) @@ -222,8 +225,8 @@ void Saig_SynchTernarySimulate( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor // transfer values to register inputs Saig_ManForEachLi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); - pSim0 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); if ( Aig_ObjFaninC0(pObj) ) { for ( w = 0; w < nWords; w++ ) @@ -255,8 +258,8 @@ void Saig_SynchTernaryTransferState( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int int i, w; Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { - pSim0 = Vec_PtrEntry( vSimInfo, pObjLi->Id ); - pSim1 = Vec_PtrEntry( vSimInfo, pObjLo->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLi->Id ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLo->Id ); for ( w = 0; w < nWords; w++ ) pSim1[w] = pSim0[w]; } @@ -283,7 +286,7 @@ int Saig_SynchCountX( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, int * pCounters = ABC_CALLOC( int, nWords * 16 ); Saig_ManForEachLi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) for ( b = 0; b < 16; b++ ) if ( ((pSim[w] >> (b << 1)) & 3) == 3 ) @@ -324,7 +327,7 @@ int Saig_SynchSavePattern( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, i assert( iPat < 16 * nWords ); Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); Value = (pSim[iPat>>4] >> ((iPat&0xf) << 1)) & 3; Vec_StrPush( vSequence, (char)Value ); // printf( "%d ", Value ); @@ -333,11 +336,11 @@ int Saig_SynchSavePattern( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, i Counter = 0; Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObjLi->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLi->Id ); Value = (pSim[iPat>>4] >> ((iPat&0xf) << 1)) & 3; Counter += (Value == 3); // save patern in the same register - pSim = Vec_PtrEntry( vSimInfo, pObjLo->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLo->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( Value ); } @@ -377,7 +380,7 @@ int Saig_SynchSequenceRun( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, Vec_Str_t * v Counter = 0; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); Value = pSim[0] & 3; assert( Value != 2 ); Counter += (Value == 3); @@ -656,3 +659,5 @@ Aig_Man_t * Saig_Synchronize( Aig_Man_t * pAig1, Aig_Man_t * pAig2, int nWords, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigTrans.c b/src/aig/saig/saigTrans.c index a92d9369..09639e27 100644 --- a/src/aig/saig/saigTrans.c +++ b/src/aig/saig/saigTrans.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + /* A similar approach is presented in the his paper: @@ -59,7 +63,7 @@ static inline void Saig_ManStartMap1( Aig_Man_t * p, int nFrames ) static inline void Saig_ManStopMap1( Aig_Man_t * p ) { assert( p->pData != NULL ); - Vec_IntFree( p->pData ); + Vec_IntFree( (Vec_Int_t *)p->pData ); p->pData = NULL; } static inline int Saig_ManHasMap1( Aig_Man_t * p ) @@ -68,7 +72,7 @@ static inline int Saig_ManHasMap1( Aig_Man_t * p ) } static inline void Saig_ManSetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew ) { - Vec_Int_t * vMap = p->pData; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); @@ -76,7 +80,7 @@ static inline void Saig_ManSetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig } static inline int Saig_ManGetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1 ) { - Vec_Int_t * vMap = p->pData; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; return Vec_IntEntry( vMap, nOffset ); } @@ -106,7 +110,7 @@ static inline void Saig_ManStartMap2( Aig_Man_t * p, int nFrames ) static inline void Saig_ManStopMap2( Aig_Man_t * p ) { assert( p->pData2 != NULL ); - Vec_IntFree( p->pData2 ); + Vec_IntFree( (Vec_Int_t *)p->pData2 ); p->pData2 = NULL; } static inline int Saig_ManHasMap2( Aig_Man_t * p ) @@ -115,7 +119,7 @@ static inline int Saig_ManHasMap2( Aig_Man_t * p ) } static inline void Saig_ManSetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew, int f2 ) { - Vec_Int_t * vMap = p->pData2; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); @@ -124,7 +128,7 @@ static inline void Saig_ManSetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig } static inline int Saig_ManGetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, int * pf2 ) { - Vec_Int_t * vMap = p->pData2; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; *pf2 = Vec_IntEntry( vMap, 2*nOffset + 1 ); return Vec_IntEntry( vMap, 2*nOffset ); @@ -222,7 +226,7 @@ Aig_Man_t * Saig_ManFramesNonInitial( Aig_Man_t * pAig, int nFrames ) Aig_ManForEachObj( pAig, pObj, i ) { assert( pObj->pData != NULL ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFrames - 1 ) @@ -233,7 +237,7 @@ Aig_Man_t * Saig_ManFramesNonInitial( Aig_Man_t * pAig, int nFrames ) } // remember register outputs Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - Aig_ObjCreatePo( pFrames, pObjLi->pData ); + Aig_ObjCreatePo( pFrames, (Aig_Obj_t *)pObjLi->pData ); Aig_ManCleanup( pFrames ); return pFrames; } @@ -266,7 +270,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ManConst0( pFrames ); - Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } else @@ -279,7 +283,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreatePi( pFrames ); - Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } // add timeframes @@ -288,7 +292,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra // map the constant node pObj = Aig_ManConst1(pAig); pObj->pData = Aig_ManConst1( pFrames ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); // create PI nodes for this frame Saig_ManForEachPi( pAig, pObj, i ) { @@ -296,13 +300,13 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra pObj->pData = Aig_ObjCreatePi( pFrames ); else pObj->pData = Aig_ManPi( pFrames, f * Saig_ManPiNum(pAig) + i ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // add internal nodes of this frame Aig_ManForEachNode( pAig, pObj, i ) { pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); if ( !Saig_ManHasMap2(pAig) ) continue; if ( f < nFrames ) @@ -322,19 +326,19 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra iNum1 = Saig_ManGetMap1( pAig, Aig_ManObj(pAig, iNum2), iFrame2 ); pRepr = Aig_ManObj( pFrames, iNum1 ); // compare the phases of these nodes - pObj->pData = Aig_NotCond( pRepr, pRepr->fPhase ^ Aig_ObjPhaseReal(pObj->pData) ); + pObj->pData = Aig_NotCond( pRepr, pRepr->fPhase ^ Aig_ObjPhaseReal((Aig_Obj_t *)pObj->pData) ); } // create POs for this frame Saig_ManForEachPo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // save register inputs Saig_ManForEachLi( pAig, pObj, i ) { pObj->pData = Aig_ObjChild0Copy(pObj); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFramesMax - 1 ) @@ -344,14 +348,14 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra { pObjLo->pData = pObjLi->pData; if ( !fInit ) - Saig_ManSetMap1( pAig, pObjLo, f+1, Aig_Regular(pObjLo->pData) ); + Saig_ManSetMap1( pAig, pObjLo, f+1, Aig_Regular((Aig_Obj_t *)pObjLo->pData) ); } } if ( !fInit ) { // create registers Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - Aig_ObjCreatePo( pFrames, pObjLi->pData ); + Aig_ObjCreatePo( pFrames, (Aig_Obj_t *)pObjLi->pData ); // set register number Aig_ManSetRegNum( pFrames, pAig->nRegs ); } @@ -373,7 +377,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra ***********************************************************************/ Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose ) { - extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); +// extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); Aig_Man_t * pFrames, * pFraig, * pRes1, * pRes2; int clk; // create uninitialized timeframes with map1 @@ -420,3 +424,5 @@ ABC_PRT( "Normal", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigWnd.c b/src/aig/saig/saigWnd.c index 10202f1b..eeacb44e 100644 --- a/src/aig/saig/saigWnd.c +++ b/src/aig/saig/saigWnd.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -103,7 +106,7 @@ Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist ) vNodes = Vec_PtrAlloc( 1000 ); Aig_ManIncrementTravId( p ); Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists ); - Vec_PtrSort( vNodes, Aig_ObjCompareIdIncrease ); + Vec_PtrSort( vNodes, (int (*)(void))Aig_ObjCompareIdIncrease ); // make sure LI/LO are labeled/unlabeled mutually Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) assert( Aig_ObjIsTravIdCurrent(p, pObjLi) == @@ -150,7 +153,7 @@ Vec_Ptr_t * Saig_ManWindowCollectPis( Aig_Man_t * p, Vec_Ptr_t * vNodes ) Aig_Obj_t * pObj, * pMatch, * pFanin; int i; vNodesPi = Vec_PtrAlloc( 1000 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsPi(p, pObj) ) { @@ -197,7 +200,7 @@ Vec_Ptr_t * Saig_ManWindowCollectPos( Aig_Man_t * p, Vec_Ptr_t * vNodes, Vec_Ptr vNodesPo = Vec_PtrAlloc( 1000 ); if ( pvPointers ) *pvPointers = Vec_PtrAlloc( 1000 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( (pPointer = Saig_ObjHasUnlabeledFanout(p, pObj)) ) { @@ -236,29 +239,29 @@ Aig_Man_t * Saig_ManWindowExtractNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes ) pObj->pData = Aig_ManConst1( pNew ); // create real PIs vNodesPi = Saig_ManWindowCollectPis( p, vNodes ); - Vec_PtrForEachEntry( vNodesPi, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPi, pObj, i ) pObj->pData = Aig_ObjCreatePi(pNew); Vec_PtrFree( vNodesPi ); // create register outputs - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsLo(p, pObj) ) pObj->pData = Aig_ObjCreatePi(pNew); } // create internal nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Aig_ObjIsNode(pObj) ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); } // create POs vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL ); - Vec_PtrForEachEntry( vNodesPo, pObj, i ) - Aig_ObjCreatePo( pNew, pObj->pData ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPo, pObj, i ) + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)pObj->pData ); Vec_PtrFree( vNodesPo ); // create register inputs nRegCount = 0; - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsLo(p, pObj) ) { @@ -292,7 +295,7 @@ void Saig_ManWindowInsertBig_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjBig, Aig_Obj_t * pMatch; if ( pObjBig->pData ) return; - if ( (pMatch = Vec_PtrEntry( vBigNode2SmallPo, pObjBig->Id )) ) + if ( (pMatch = (Aig_Obj_t *)Vec_PtrEntry( vBigNode2SmallPo, pObjBig->Id )) ) { Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin0(pMatch), vBigNode2SmallPo, vSmallPi2BigNode ); pObjBig->pData = Aig_ObjChild0Copy(pMatch); @@ -321,7 +324,7 @@ void Saig_ManWindowInsertSmall_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjSmall, Aig_Obj_t * pMatch; if ( pObjSmall->pData ) return; - if ( (pMatch = Vec_PtrEntry( vSmallPi2BigNode, pObjSmall->Id )) ) + if ( (pMatch = (Aig_Obj_t *)Vec_PtrEntry( vSmallPi2BigNode, pObjSmall->Id )) ) { Saig_ManWindowInsertBig_rec( pNew, pMatch, vBigNode2SmallPo, vSmallPi2BigNode ); pObjSmall->pData = pMatch->pData; @@ -355,7 +358,7 @@ Aig_Man_t * Saig_ManWindowInsertNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes, Aig_Ma // set mapping of small PIs into big nodes vSmallPi2BigNode = Vec_PtrStart( Aig_ManObjNumMax(pWnd) ); vNodesPi = Saig_ManWindowCollectPis( p, vNodes ); - Vec_PtrForEachEntry( vNodesPi, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPi, pObj, i ) Vec_PtrWriteEntry( vSmallPi2BigNode, Aig_ManPi(pWnd, i)->Id, pObj ); assert( i == Saig_ManPiNum(pWnd) ); Vec_PtrFree( vNodesPi ); @@ -363,7 +366,7 @@ Aig_Man_t * Saig_ManWindowInsertNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes, Aig_Ma // set mapping of big nodes into small POs vBigNode2SmallPo = Vec_PtrStart( Aig_ManObjNumMax(p) ); vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL ); - Vec_PtrForEachEntry( vNodesPo, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPo, pObj, i ) Vec_PtrWriteEntry( vBigNode2SmallPo, pObj->Id, Aig_ManPo(pWnd, i) ); assert( i == Saig_ManPoNum(pWnd) ); Vec_PtrFree( vNodesPo ); @@ -589,7 +592,7 @@ void Saig_ManWindowCreatePis( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1, { Aig_Obj_t * pObj, * pMatch, * pFanin; int i, Counter = 0; - Vec_PtrForEachEntry( vNodes0, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj, i ) { if ( Saig_ObjIsLo(p0, pObj) ) { @@ -667,7 +670,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } } @@ -681,7 +684,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } @@ -691,7 +694,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } } @@ -753,23 +756,23 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) Saig_ManWindowCreatePis( pNew, p0, p1, vNodes0 ); Saig_ManWindowCreatePis( pNew, p1, p0, vNodes1 ); // create register outputs - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Saig_ObjIsLo(p0, pObj0) ) pObj0->pData = Aig_ObjCreatePi(pNew); } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Saig_ObjIsLo(p1, pObj1) ) pObj1->pData = Aig_ObjCreatePi(pNew); } // create internal nodes - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Aig_ObjIsNode(pObj0) ) pObj0->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj0), Aig_ObjChild1Copy(pObj0) ); } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Aig_ObjIsNode(pObj1) ) pObj1->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj1), Aig_ObjChild1Copy(pObj1) ); @@ -779,7 +782,7 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) // Saig_ManWindowCreatePos( pNew, p1, p0 ); // create register inputs nRegCount = 0; - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Saig_ObjIsLo(p0, pObj0) ) { @@ -788,7 +791,7 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) nRegCount++; } } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Saig_ObjIsLo(p1, pObj1) ) { @@ -807,3 +810,5 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saig_.c b/src/aig/saig/saig_.c index 255639e6..f0f293fd 100644 --- a/src/aig/saig/saig_.c +++ b/src/aig/saig/saig_.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3