/**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