/**CFile**************************************************************** FileName [bmcMulti.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based bounded model checking.] Synopsis [Proving multi-output properties.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: bmcMulti.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "bmc.h" #include "proof/ssw/ssw.h" #include "misc/extra/extra.h" #include "aig/gia/giaAig.h" #include "aig/ioa/ioa.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Divides outputs into solved and unsolved.] Description [Return array of unsolved outputs to extract into a new AIG. Updates the resulting CEXes (vCexesOut) and current output map (vOutMap).] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Gia_ManProcessOutputs( Vec_Ptr_t * vCexesIn, Vec_Ptr_t * vCexesOut, Vec_Int_t * vOutMap ) { Abc_Cex_t * pCex; Vec_Int_t * vLeftOver; int i, iOut; assert( Vec_PtrSize(vCexesIn) == Vec_IntSize(vOutMap) ); vLeftOver = Vec_IntAlloc( Vec_PtrSize(vCexesIn) ); Vec_IntForEachEntry( vOutMap, iOut, i ) { assert( Vec_PtrEntry(vCexesOut, iOut) == NULL ); pCex = (Abc_Cex_t *)Vec_PtrEntry( vCexesIn, i ); if ( pCex ) // found a CEX for output iOut { Vec_PtrWriteEntry( vCexesIn, i, NULL ); Vec_PtrWriteEntry( vCexesOut, iOut, pCex ); } else // still unsolved { Vec_IntWriteEntry( vOutMap, Vec_IntSize(vLeftOver), iOut ); Vec_IntPush( vLeftOver, i ); } } Vec_IntShrink( vOutMap, Vec_IntSize(vLeftOver) ); return vLeftOver; } /**Function************************************************************* Synopsis [Counts the number of constant 0 POs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManCountConst0PosGia( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i, Counter = 0; Gia_ManForEachPo( p, pObj, i ) Counter += (Gia_ObjFaninLit0p(p, pObj) == 0); return Counter; } int Gia_ManCountConst0Pos( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i, Counter = 0; Saig_ManForEachPo( p, pObj, i ) Counter += (Aig_ObjChild0(pObj) == Aig_ManConst0(p)); return Counter; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManMultiReport( Aig_Man_t * p, char * pStr, int nTotalPo, int nTotalSize, abctime clkStart ) { printf( "%3s : ", pStr ); printf( "PI =%6d ", Saig_ManPiNum(p) ); printf( "PO =%6d ", Saig_ManPoNum(p) ); printf( "FF =%7d ", Saig_ManRegNum(p) ); printf( "ND =%7d ", Aig_ManNodeNum(p) ); printf( "Solved =%7d (%5.1f %%) ", nTotalPo-Saig_ManPoNum(p), 100.0*(nTotalPo-Saig_ManPoNum(p))/Abc_MaxInt(1, nTotalPo) ); printf( "Size =%7d (%5.1f %%) ", Aig_ManObjNum(p), 100.0*Aig_ManObjNum(p)/Abc_MaxInt(1, nTotalSize) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Gia_ManMultiProveSyn( Aig_Man_t * p, int fVerbose, int fVeryVerbose ) { Aig_Man_t * pAig; Gia_Man_t * pGia, * pTemp; pGia = Gia_ManFromAig( p ); pGia = Gia_ManAigSyn2( pTemp = pGia, 1, 0, 0, 0, 0, 0, 0 ); Gia_ManStop( pTemp ); pAig = Gia_ManToAig( pGia, 0 ); Gia_ManStop( pGia ); return pAig; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Gia_ManMultiProveAig( Aig_Man_t * p, Bmc_MulPar_t * pPars ) { Ssw_RarPars_t ParsSim, * pParsSim = &ParsSim; Saig_ParBmc_t ParsBmc, * pParsBmc = &ParsBmc; Vec_Int_t * vOutMap, * vLeftOver; Vec_Ptr_t * vCexes; Aig_Man_t * pTemp; abctime clkStart = Abc_Clock(); abctime nTimeToStop = pPars->TimeOutGlo ? Abc_Clock() + pPars->TimeOutGlo * CLOCKS_PER_SEC : 0; int nTotalPo = Saig_ManPoNum(p); int nTotalSize = Aig_ManObjNum(p); int TimeOutLoc = pPars->TimeOutLoc; int i, RetValue = -1; if ( pPars->fVerbose ) printf( "MultiProve parameters: Global timeout = %d sec. Local timeout = %d sec. Time increase = %d %%.\n", pPars->TimeOutGlo, pPars->TimeOutLoc, pPars->TimeOutInc ); if ( pPars->fVerbose ) printf( "Gap timout = %d sec. Per-output timeout = %d msec. Use synthesis = %d. Dump final = %d. Verbose = %d.\n", pPars->TimeOutGap, pPars->TimePerOut, pPars->fUseSyn, pPars->fDumpFinal, pPars->fVerbose ); // create output map vOutMap = Vec_IntStartNatural( Saig_ManPoNum(p) ); // maps current outputs into their original IDs vCexes = Vec_PtrStart( Saig_ManPoNum(p) ); // maps solved outputs into their CEXes (or markers) for ( i = 0; i < 1000; i++ ) { int nSolved = Vec_PtrCountZero(vCexes); // perform SIM3 Ssw_RarSetDefaultParams( pParsSim ); pParsSim->fSolveAll = 1; pParsSim->fNotVerbose = 1; pParsSim->fSilent = !pPars->fVeryVerbose; pParsSim->TimeOut = TimeOutLoc; pParsSim->nRandSeed = (i * 17) % 500; pParsSim->nWords = 5; RetValue *= Ssw_RarSimulate( p, pParsSim ); // sort outputs if ( p->vSeqModelVec ) { vLeftOver = Gia_ManProcessOutputs( p->vSeqModelVec, vCexes, vOutMap ); if ( Vec_IntSize(vLeftOver) == 0 ) break; // remove solved p = Saig_ManDupCones( pTemp = p, Vec_IntArray(vLeftOver), Vec_IntSize(vLeftOver) ); Vec_IntFree( vLeftOver ); Aig_ManStop( pTemp ); } if ( pPars->fVerbose ) Gia_ManMultiReport( p, "SIM", nTotalPo, nTotalSize, clkStart ); // check timeout if ( nTimeToStop && Abc_Clock() + TimeOutLoc * CLOCKS_PER_SEC > nTimeToStop ) { printf( "Global timeout (%d sec) is reached.\n", pPars->TimeOutGlo ); break; } // perform BMC Saig_ParBmcSetDefaultParams( pParsBmc ); pParsBmc->fSolveAll = 1; pParsBmc->fNotVerbose = 1; pParsBmc->fSilent = !pPars->fVeryVerbose; pParsBmc->nTimeOut = TimeOutLoc; pParsBmc->nTimeOutOne = pPars->TimePerOut; RetValue *= Saig_ManBmcScalable( p, pParsBmc ); if ( pPars->fVeryVerbose ) Abc_Print( 1, "Some outputs are SAT (%d out of %d) after %d frames.\n", Saig_ManPoNum(p) - Vec_PtrCountZero(p->vSeqModelVec), Saig_ManPoNum(p), pParsBmc->iFrame ); // sort outputs if ( p->vSeqModelVec ) { vLeftOver = Gia_ManProcessOutputs( p->vSeqModelVec, vCexes, vOutMap ); if ( Vec_IntSize(vLeftOver) == 0 ) break; // remove solved p = Saig_ManDupCones( pTemp = p, Vec_IntArray(vLeftOver), Vec_IntSize(vLeftOver) ); Vec_IntFree( vLeftOver ); Aig_ManStop( pTemp ); } if ( pPars->fVerbose ) Gia_ManMultiReport( p, "BMC", nTotalPo, nTotalSize, clkStart ); // check timeout if ( nTimeToStop && Abc_Clock() + TimeOutLoc * CLOCKS_PER_SEC > nTimeToStop ) { printf( "Global timeout (%d sec) is reached.\n", pPars->TimeOutGlo ); break; } // check gap timeout if ( pPars->TimeOutGap && pPars->TimeOutGap <= TimeOutLoc && nSolved == Vec_PtrCountZero(vCexes) ) { printf( "Gap timeout (%d sec) is reached.\n", pPars->TimeOutGap ); break; } // synthesize if ( pPars->fUseSyn ) { p = Gia_ManMultiProveSyn( pTemp = p, pPars->fVerbose, pPars->fVeryVerbose ); Aig_ManStop( pTemp ); if ( pPars->fVerbose ) Gia_ManMultiReport( p, "SYN", nTotalPo, nTotalSize, clkStart ); } // increase timeout TimeOutLoc += TimeOutLoc * pPars->TimeOutInc / 100; } Vec_IntFree( vOutMap ); if ( pPars->fVerbose ) printf( "The number of POs proved UNSAT by synthesis = %d.\n", Gia_ManCountConst0Pos(p) ); if ( pPars->fDumpFinal ) { char * pFileName = Extra_FileNameGenericAppend( p->pName, "_out.aig" ); Ioa_WriteAiger( p, pFileName, 0, 0 ); printf( "Final AIG was dumped into file \"%s\".\n", pFileName ); } Aig_ManStop( p ); return vCexes; } int Gia_ManMultiProve( Gia_Man_t * p, Bmc_MulPar_t * pPars ) { Aig_Man_t * pAig; if ( p->vSeqModelVec ) Vec_PtrFreeFree( p->vSeqModelVec ), p->vSeqModelVec = NULL; pAig = Gia_ManToAig( p, 0 ); p->vSeqModelVec = Gia_ManMultiProveAig( pAig, pPars ); // deletes pAig assert( Vec_PtrSize(p->vSeqModelVec) == Gia_ManPoNum(p) ); return Vec_PtrCountZero(p->vSeqModelVec) == Vec_PtrSize(p->vSeqModelVec) ? -1 : 0; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END