summaryrefslogtreecommitdiffstats
path: root/src/proof/pdr/pdrMan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/proof/pdr/pdrMan.c')
-rw-r--r--src/proof/pdr/pdrMan.c341
1 files changed, 333 insertions, 8 deletions
diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c
index b58c479b..a076223b 100644
--- a/src/proof/pdr/pdrMan.c
+++ b/src/proof/pdr/pdrMan.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "pdrInt.h"
+#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@@ -33,6 +34,208 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Wec_t * vLevels;
+ Vec_Int_t * vRes, * vLevel, * vCosts;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int i, k, Entry, MaxEntry = 0;
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ // create flop costs
+ vCosts = Vec_IntAlloc( Gia_ManRegNum(p) );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntPush( vCosts, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ //printf( "%d(%d) ", i, Gia_ObjRefNum(p, pObj) );
+ }
+ //printf( "\n" );
+ MaxEntry++;
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ MaxEntry = 2*MaxEntry + 1;
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create levelized structure
+ vLevels = Vec_WecStart( MaxEntry );
+ Vec_IntForEachEntry( vCosts, Entry, i )
+ Vec_WecPush( vLevels, Entry, i );
+ // collect in this order
+ MaxEntry = 0;
+ vRes = Vec_IntStart( Gia_ManRegNum(p) );
+ Vec_WecForEachLevel( vLevels, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ Vec_IntWriteEntry( vRes, Entry, MaxEntry++ );
+ //printf( "%d ", Gia_ObjRefNum(p, Gia_ManCi(p, Gia_ManPiNum(p)+Entry)) );
+ //printf( "\n" );
+ assert( MaxEntry == Gia_ManRegNum(p) );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vCosts );
+ ABC_FREE( p->pRefs );
+//Vec_IntPrint( vRes );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Int_t * vRes = NULL;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int MaxEntry = 0;
+ int i, * pPerm;
+ // create flop costs
+ Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) );
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ }
+ MaxEntry++;
+ ABC_FREE( p->pRefs );
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create ordering based on costs
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) );
+ vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) );
+ Vec_IntFree( vCosts );
+ vCosts = Vec_IntInvert( vRes, -1 );
+ Vec_IntFree( vRes );
+//Vec_IntPrint( vCosts );
+ return vCosts;
+}
+
+/**Function*************************************************************
+
Synopsis [Creates manager.]
Description []
@@ -48,6 +251,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p = ABC_CALLOC( Pdr_Man_t, 1 );
p->pPars = pPars;
p->pAig = pAig;
+ p->pGia = (pPars->fFlopPrio || p->pPars->fNewXSim || p->pPars->fUseAbs) ? Gia_ManFromAigSimple(pAig) : NULL;
p->vSolvers = Vec_PtrAlloc( 0 );
p->vClauses = Vec_VecAlloc( 0 );
p->pQueue = NULL;
@@ -56,7 +260,15 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
if ( !p->pPars->fMonoCnf )
p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) );
// internal use
- p->vPrio = vPrioInit ? vPrioInit : Vec_IntStart( Aig_ManRegNum(pAig) ); // priority flops
+ p->nPrioShift = Abc_Base2Log(Aig_ManRegNum(pAig));
+ if ( vPrioInit )
+ p->vPrio = vPrioInit;
+ else if ( pPars->fFlopPrio )
+ p->vPrio = Pdr_ManDeriveFlopPriorities2(p->pGia, 1);
+ else if ( p->pPars->fNewXSim )
+ p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) );
+ else
+ p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) );
p->vLits = Vec_IntAlloc( 100 ); // array of literals
p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves
p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots
@@ -67,9 +279,9 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p->vVisits = Vec_IntAlloc( 100 ); // intermediate
p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed
p->vRes = Vec_IntAlloc( 100 ); // final result
- p->vSuppLits= Vec_IntAlloc( 100 ); // support literals
- p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) );
p->pCnfMan = Cnf_ManStart();
+ // ternary simulation
+ p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL;
// additional AIG data-members
if ( pAig->pFanData == NULL )
Aig_ManFanoutStart( pAig );
@@ -108,11 +320,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Pdr_Set_t * pCla;
sat_solver * pSat;
int i, k;
+ Gia_ManStopP( &p->pGia );
Aig_ManCleanMarkAB( p->pAig );
if ( p->pPars->fVerbose )
{
- Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Start =%4d\n",
- p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nStarts );
+ Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Cex =%4d Start =%4d\n",
+ p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nCexesTotal, p->nStarts );
ABC_PRTP( "SAT solving", p->tSat, p->tTotal );
ABC_PRTP( " unsat ", p->tSatUnsat, p->tTotal );
ABC_PRTP( " sat ", p->tSatSat, p->tTotal );
@@ -121,6 +334,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
ABC_PRTP( "Ternary sim", p->tTsim, p->tTotal );
ABC_PRTP( "Containment", p->tContain, p->tTotal );
ABC_PRTP( "CNF compute", p->tCnf, p->tTotal );
+ ABC_PRTP( "Refinement ", p->tAbs, p->tTotal );
ABC_PRTP( "TOTAL ", p->tTotal, p->tTotal );
fflush( stdout );
}
@@ -150,6 +364,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_WecFreeP( &p->vVLits );
// CNF manager
Cnf_ManStop( p->pCnfMan );
+ Vec_IntFreeP( &p->vAbsFlops );
+ Vec_IntFreeP( &p->vMapFf2Ppi );
+ Vec_IntFreeP( &p->vMapPpi2Ff );
+ // terminary simulation
+ if ( p->pPars->fNewXSim )
+ Txs_ManStop( p->pTxs );
// internal use
Vec_IntFreeP( &p->vPrio ); // priority flops
Vec_IntFree( p->vLits ); // array of literals
@@ -162,9 +382,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_IntFree( p->vVisits ); // intermediate
Vec_IntFree( p->vCi2Rem ); // CIs to be removed
Vec_IntFree( p->vRes ); // final result
- Vec_IntFree( p->vSuppLits ); // support literals
Vec_PtrFreeP( &p->vInfCubes );
- ABC_FREE( p->pCubeJust );
ABC_FREE( p->pTime4Outs );
if ( p->vCexes )
Vec_PtrFreeFree( p->vCexes );
@@ -197,7 +415,6 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
nFrames++;
// create the counter-example
pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames );
-// pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput;
pCex->iPo = p->iOutCur;
pCex->iFrame = nFrames-1;
for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
@@ -206,6 +423,8 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
Lit = pObl->pState->Lits[i];
if ( lit_sign(Lit) )
continue;
+ if ( lit_var(Lit) >= pCex->nPis ) // allows PPI literals to be thrown away
+ continue;
assert( lit_var(Lit) < pCex->nPis );
Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
}
@@ -215,6 +434,112 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
return pCex;
}
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example when abstraction is used.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi );
+
+ Gia_Man_t * pAbs;
+ Abc_Cex_t * pCex, * pCexCare;
+ Pdr_Obl_t * pObl;
+ int i, f, Lit, Flop, nFrames = 0;
+ int nPis = Saig_ManPiNum(p->pAig);
+ int nFfRefined = 0;
+ if ( !p->pPars->fUseAbs || !p->vMapPpi2Ff )
+ return Pdr_ManDeriveCex(p);
+ // restore previous map
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry( p->vMapFf2Ppi, Flop ) == i );
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, -1 );
+ }
+ Vec_IntClear( p->vMapPpi2Ff );
+ // count the number of frames
+ for ( pObl = p->pQueue; pObl; pObl = pObl->pNext )
+ {
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_var(Lit) < nPis ) // PI literal
+ continue;
+ Flop = lit_var(Lit) - nPis;
+ if ( Vec_IntEntry(p->vMapFf2Ppi, Flop) >= 0 ) // already used PPI literal
+ continue;
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, Vec_IntSize(p->vMapPpi2Ff) );
+ Vec_IntPush( p->vMapPpi2Ff, Flop );
+ }
+ nFrames++;
+ }
+ if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ if ( p->pPars->fUseSimpleRef )
+ {
+ // rely on ternary simulation to perform refinement
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry(p->vAbsFlops, Flop) == 0 );
+ Vec_IntWriteEntry( p->vAbsFlops, Flop, 1 );
+ nFfRefined++;
+ }
+ }
+ else
+ {
+ // create the counter-example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames );
+ pCex->iPo = p->iOutCur;
+ pCex->iFrame = nFrames-1;
+ for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_sign(Lit) )
+ continue;
+ if ( lit_var(Lit) < nPis ) // PI literal
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
+ else
+ {
+ int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis);
+ assert( iPPI < pCex->nPis );
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI );
+ }
+ }
+ assert( f == nFrames );
+ // perform CEX minimization
+ pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi );
+ pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 );
+ Gia_ManStop( pAbs );
+ assert( pCexCare->nPis == pCex->nPis );
+ Abc_CexFree( pCex );
+ // detect care PPIs
+ for ( f = 0; f < nFrames; f++ )
+ {
+ for ( i = nPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ {
+ if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted
+ Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++;
+ }
+ }
+ Abc_CexFree( pCexCare );
+ if ( nFfRefined == 0 ) // no refinement -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ }
+ //printf( "CEX-based refinement refined %d flops.\n", nFfRefined );
+ p->nCexesTotal++;
+ p->nCexes++;
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////