summaryrefslogtreecommitdiffstats
path: root/src/sat/bmc/bmcCexTools.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-11-29 13:34:07 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2012-11-29 13:34:07 -0800
commitc48e3c7ab43f7aac5b462b1a544d82e1be7cf9ea (patch)
tree08cfbcd4b36063bc58360dd308e1f7f78131e6ec /src/sat/bmc/bmcCexTools.c
parent661265984c6b9e32fcaece8aa361b06476756783 (diff)
downloadabc-c48e3c7ab43f7aac5b462b1a544d82e1be7cf9ea.tar.gz
abc-c48e3c7ab43f7aac5b462b1a544d82e1be7cf9ea.tar.bz2
abc-c48e3c7ab43f7aac5b462b1a544d82e1be7cf9ea.zip
Counter-example analysis and optimization.
Diffstat (limited to 'src/sat/bmc/bmcCexTools.c')
-rw-r--r--src/sat/bmc/bmcCexTools.c590
1 files changed, 590 insertions, 0 deletions
diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c
new file mode 100644
index 00000000..0cbb0e9a
--- /dev/null
+++ b/src/sat/bmc/bmcCexTools.c
@@ -0,0 +1,590 @@
+/**CFile****************************************************************
+
+ FileName [bmcCexTools.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based bounded model checking.]
+
+ Synopsis [CEX analysis and optimization toolbox.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: bmcCexTools.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "bmc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline word Bmc_CexBitMask( int iBit ) { assert( iBit < 64 ); return ~(((word)1) << iBit); }
+static inline void Bmc_CexCopySim( Vec_Wrd_t * vSims, int iObjTo, int iObjFrom ) { Vec_WrdWriteEntry( vSims, iObjTo, iObjFrom ); }
+static inline void Bmc_CexAndSim( Vec_Wrd_t * vSims, int iObjTo, int i, int j ) { Vec_WrdWriteEntry( vSims, iObjTo, Vec_WrdEntry(vSims, i) & Vec_WrdEntry(vSims, j) ); }
+static inline void Bmc_CexOrSim( Vec_Wrd_t * vSims, int iObjTo, int i, int j ) { Vec_WrdWriteEntry( vSims, iObjTo, Vec_WrdEntry(vSims, i) | Vec_WrdEntry(vSims, j) ); }
+static inline int Bmc_CexSim( Vec_Wrd_t * vSims, int iObj, int i ) { return (Vec_WrdEntry(vSims, iObj) >> i) & 1; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Prints one counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs )
+{
+ int i, k, Count, iBit = 0;
+ Abc_CexPrintStatsInputs( pCex, nInputs );
+ return;
+
+ for ( i = 0; i <= pCex->iFrame; i++ )
+ {
+ Count = 0;
+ printf( "%3d : ", i );
+ for ( k = 0; k < nInputs; k++ )
+ {
+ Count += Abc_InfoHasBit(pCex->pData, iBit);
+ printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) );
+ }
+ printf( " %3d ", Count );
+ Count = 0;
+ for ( ; k < pCex->nPis; k++ )
+ {
+ Count += Abc_InfoHasBit(pCex->pData, iBit);
+ printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) );
+ }
+ printf( " %3d\n", Count );
+ }
+ assert( iBit == pCex->nBits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies the care set of the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare )
+{
+ Gia_Obj_t * pObj;
+ int i, k;
+ assert( pCex->nRegs > 0 );
+ assert( pCexCare->nRegs == 0 );
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ Gia_ManForEachRi( p, pObj, k )
+ Gia_ObjTerSimSet0( pObj );
+ for ( i = 0; i <= pCex->iFrame; i++ )
+ {
+ Gia_ManForEachPi( p, pObj, k )
+ {
+ if ( !Abc_InfoHasBit( pCexCare->pData, i * pCexCare->nPis + k ) )
+ Gia_ObjTerSimSetX( pObj );
+ else if ( Abc_InfoHasBit( pCex->pData, pCex->nRegs + i * pCex->nPis + k ) )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachRo( p, pObj, k )
+ Gia_ObjTerSimRo( p, pObj );
+ Gia_ManForEachAnd( p, pObj, k )
+ Gia_ObjTerSimAnd( pObj );
+ Gia_ManForEachCo( p, pObj, k )
+ Gia_ObjTerSimCo( pObj );
+ }
+ pObj = Gia_ManPo( p, pCex->iPo );
+ return Gia_ObjTerSimGet1(pObj);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes internal states of the CEX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Bmc_CexInnerStates( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t ** ppCexImpl )
+{
+ Abc_Cex_t * pNew, * pNew2;
+ Gia_Obj_t * pObj, * pObjRo, * pObjRi;
+ int fCompl0, fCompl1;
+ int i, k, iBit = 0;
+ assert( pCex->nRegs > 0 );
+ // start the counter-example
+ pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCex->iFrame + 1 );
+ pNew->iFrame = pCex->iFrame;
+ pNew->iPo = pCex->iPo;
+ // start the counter-example
+ pNew2 = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCex->iFrame + 1 );
+ pNew2->iFrame = pCex->iFrame;
+ pNew2->iPo = pCex->iPo;
+ // set initial state
+ Gia_ManCleanMark01(p);
+ // set const0
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManConst0(p)->fMark1 = 1;
+ // set init state
+ Gia_ManForEachRi( p, pObjRi, k )
+ {
+ pObjRi->fMark0 = Abc_InfoHasBit(pCex->pData, iBit++);
+ pObjRi->fMark1 = 1;
+ }
+ for ( i = 0; i <= pCex->iFrame; i++ )
+ {
+ Gia_ManForEachPi( p, pObj, k )
+ pObj->fMark0 = Abc_InfoHasBit(pCex->pData, iBit++);
+ Gia_ManForEachRiRo( p, pObjRi, pObjRo, k )
+ {
+ pObjRo->fMark0 = pObjRi->fMark0;
+ pObjRo->fMark1 = pObjRi->fMark1;
+ }
+ Gia_ManForEachCi( p, pObj, k )
+ {
+ if ( pObj->fMark0 )
+ Abc_InfoSetBit( pNew->pData, pNew->nPis * i + k );
+ if ( pObj->fMark1 )
+ Abc_InfoSetBit( pNew2->pData, pNew2->nPis * i + k );
+ }
+ Gia_ManForEachAnd( p, pObj, k )
+ {
+ fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj);
+ pObj->fMark0 = fCompl0 & fCompl1;
+ if ( pObj->fMark0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 && !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1;
+ else if ( !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1;
+ else assert( 0 );
+ }
+ Gia_ManForEachCo( p, pObj, k )
+ {
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1;
+ }
+
+/*
+ // print input/state/output
+ printf( "%3d : ", i );
+ Gia_ManForEachPi( p, pObj, k )
+ printf( "%d", pObj->fMark0 );
+ printf( " " );
+ Gia_ManForEachRo( p, pObj, k )
+ printf( "%d", pObj->fMark0 );
+ printf( " " );
+ Gia_ManForEachPo( p, pObj, k )
+ printf( "%d", pObj->fMark0 );
+ printf( "\n" );
+*/
+ }
+ assert( iBit == pCex->nBits );
+ assert( Gia_ManPo(p, pCex->iPo)->fMark0 == 1 );
+
+ printf( "Inner states: " );
+ Bmc_CexPrint( pNew, Gia_ManPiNum(p) );
+ printf( "Implications: " );
+ Bmc_CexPrint( pNew2, Gia_ManPiNum(p) );
+ if ( ppCexImpl )
+ *ppCexImpl = pNew2;
+ else
+ Abc_CexFree( pNew2 );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes care bits of the CEX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bmc_CexCareBits_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int fCompl0, fCompl1;
+ if ( Gia_ObjIsConst0(pObj) )
+ return;
+ if ( pObj->fMark1 )
+ return;
+ pObj->fMark1 = 1;
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj);
+ if ( pObj->fMark0 )
+ {
+ assert( fCompl0 == 1 && fCompl1 == 1 );
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) );
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin1(pObj) );
+ }
+ else
+ {
+ assert( fCompl0 == 0 || fCompl1 == 0 );
+ if ( fCompl0 == 0 )
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) );
+ if ( fCompl1 == 0 )
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin1(pObj) );
+ }
+}
+void Bmc_CexCareBits2_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int fCompl0, fCompl1;
+ if ( Gia_ObjIsConst0(pObj) )
+ return;
+ if ( pObj->fMark1 )
+ return;
+ pObj->fMark1 = 1;
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj);
+ if ( pObj->fMark0 )
+ {
+ assert( fCompl0 == 1 && fCompl1 == 1 );
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) );
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin1(pObj) );
+ }
+ else
+ {
+ assert( fCompl0 == 0 || fCompl1 == 0 );
+ if ( fCompl0 == 0 )
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) );
+ /**/
+ else
+ /**/
+ if ( fCompl1 == 0 )
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin1(pObj) );
+ }
+}
+Abc_Cex_t * Bmc_CexCareBits( Gia_Man_t * p, Abc_Cex_t * pCexState, Abc_Cex_t * pCexImpl, Abc_Cex_t * pCexEss, int fFindAll )
+{
+ Abc_Cex_t * pNew;
+ Gia_Obj_t * pObj;
+ int fCompl0, fCompl1;
+ int i, k, iBit;
+ assert( pCexState->nRegs == 0 );
+ // start the counter-example
+ pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 );
+ pNew->iFrame = pCexState->iFrame;
+ pNew->iPo = pCexState->iPo;
+ // set initial state
+ Gia_ManCleanMark01(p);
+ // set const0
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManConst0(p)->fMark1 = 1;
+ for ( i = pCexState->iFrame; i >= 0; i-- )
+ {
+ // set correct values
+ iBit = pCexState->nPis * i;
+ Gia_ManForEachCi( p, pObj, k )
+ {
+ pObj->fMark0 = Abc_InfoHasBit(pCexState->pData, iBit+k);
+ pObj->fMark1 = Abc_InfoHasBit(pCexImpl->pData, iBit+k);
+ if ( pCexEss )
+ pObj->fMark1 |= Abc_InfoHasBit(pCexEss->pData, iBit+k);
+ }
+ Gia_ManForEachAnd( p, pObj, k )
+ {
+ fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj);
+ pObj->fMark0 = fCompl0 & fCompl1;
+ if ( pObj->fMark0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 && !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1;
+ else if ( !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1;
+ else assert( 0 );
+ }
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ // move values from COs to CIs
+ if ( i == pCexState->iFrame )
+ {
+ assert( Gia_ManPo(p, pCexState->iPo)->fMark0 == 1 );
+ if ( fFindAll )
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin0(Gia_ManPo(p, pCexState->iPo)) );
+ else
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(Gia_ManPo(p, pCexState->iPo)) );
+ }
+ else
+ {
+ Gia_ManForEachRi( p, pObj, k )
+ if ( Abc_InfoHasBit(pNew->pData, pNew->nPis * (i+1) + Gia_ManPiNum(p) + k) )
+ {
+ if ( fFindAll )
+ Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) );
+ else
+ Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) );
+ }
+ }
+ // save the results
+ Gia_ManForEachCi( p, pObj, k )
+ if ( pObj->fMark1 )
+ {
+ pObj->fMark1 = 0;
+ if ( !Abc_InfoHasBit(pCexImpl->pData, pNew->nPis * i + k) )
+ Abc_InfoSetBit(pNew->pData, pNew->nPis * i + k);
+ }
+ }
+ printf( "Care bits: " );
+ Bmc_CexPrint( pNew, Gia_ManPiNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one bit to check whether it is essential.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Bmc_CexEssentialBitOne( Gia_Man_t * p, Abc_Cex_t * pCexState, int iBit, Abc_Cex_t * pCexPrev, int * pfEqual )
+{
+ Abc_Cex_t * pNew;
+ Gia_Obj_t * pObj;
+ int i, k, fCompl0, fCompl1;
+ int iFrame = iBit / pCexState->nPis;
+ int iNumber = iBit % pCexState->nPis;
+ assert( pCexState->nRegs == 0 );
+ assert( iBit < pCexState->nBits );
+ if ( pfEqual )
+ *pfEqual = 0;
+ // start the counter-example
+ pNew = Abc_CexAllocFull( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 );
+ pNew->iFrame = pCexState->iFrame;
+ pNew->iPo = pCexState->iPo;
+ // clean bit
+ Abc_InfoXorBit( pNew->pData, iBit );
+ // simulate the remaining frames
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManConst0(p)->fMark1 = 1;
+ for ( i = iFrame; i <= pCexState->iFrame; i++ )
+ {
+ Gia_ManForEachCi( p, pObj, k )
+ {
+ pObj->fMark0 = Abc_InfoHasBit( pCexState->pData, i * pCexState->nPis + k );
+ pObj->fMark1 = Abc_InfoHasBit( pNew->pData, i * pCexState->nPis + k );
+ }
+ Gia_ManForEachAnd( p, pObj, k )
+ {
+ fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj);
+ pObj->fMark0 = fCompl0 & fCompl1;
+ if ( pObj->fMark0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 && !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1;
+ else if ( !fCompl0 )
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1;
+ else if ( !fCompl1 )
+ pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1;
+ else assert( 0 );
+ }
+ Gia_ManForEachCo( p, pObj, k )
+ {
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1;
+ }
+ if ( i < pCexState->iFrame )
+ {
+ int fChanges = 0;
+ int fEqual = (pCexPrev != NULL);
+ int iBitShift = (i + 1) * pCexState->nPis + Gia_ManPiNum(p);
+ Gia_ManForEachRi( p, pObj, k )
+ {
+ if ( fEqual && pCexPrev && (int)pObj->fMark1 != Abc_InfoHasBit(pCexPrev->pData, iBitShift + k) )
+ fEqual = 0;
+ if ( !pObj->fMark1 )
+ {
+ fChanges = 1;
+ Abc_InfoXorBit( pNew->pData, iBitShift + k );
+ }
+ }
+ if ( !fChanges || fEqual )
+ {
+ if ( pfEqual )
+ *pfEqual = fEqual;
+ Abc_CexFree( pNew );
+ return NULL;
+ }
+ }
+/*
+ if ( i == 20 )
+ {
+ printf( "Frame %d : ", i );
+ Gia_ManForEachRi( p, pObj, k )
+ printf( "%d", pObj->fMark1 );
+ printf( "\n" );
+ }
+*/
+ }
+ return pNew;
+}
+void Bmc_CexEssentialBitTest( Gia_Man_t * p, Abc_Cex_t * pCexState )
+{
+ Abc_Cex_t * pNew;
+ int b;
+ for ( b = 0; b < pCexState->nBits; b++ )
+ {
+ if ( b % 100 )
+ continue;
+ pNew = Bmc_CexEssentialBitOne( p, pCexState, b, NULL, NULL );
+ Bmc_CexPrint( pNew, Gia_ManPiNum(p) );
+
+ if ( Gia_ManPo(p, pCexState->iPo)->fMark1 )
+ printf( "Not essential\n" );
+ else
+ printf( "Essential\n" );
+
+ Abc_CexFree( pNew );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes essential bits of the CEX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Bmc_CexEssentialBits( Gia_Man_t * p, Abc_Cex_t * pCexState, Abc_Cex_t * pCexCare )
+{
+ Abc_Cex_t * pNew, * pTemp, * pPrev = NULL;
+ int b, fEqual = 0, fPrevStatus = 0;
+ clock_t clk = clock();
+ assert( pCexState->nBits == pCexCare->nBits );
+ // start the counter-example
+ pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 );
+ pNew->iFrame = pCexState->iFrame;
+ pNew->iPo = pCexState->iPo;
+ // iterate through care-bits
+ for ( b = 0; b < pCexState->nBits; b++ )
+ {
+ // skip don't-care bits
+ if ( !Abc_InfoHasBit(pCexCare->pData, b) )
+ continue;
+
+ // skip state bits
+ if ( b % pCexCare->nPis >= Gia_ManPiNum(p) )
+ {
+ Abc_InfoSetBit( pNew->pData, b );
+ continue;
+ }
+
+ // check if this is an essential bit
+ pTemp = Bmc_CexEssentialBitOne( p, pCexState, b, pPrev, &fEqual );
+// pTemp = Bmc_CexEssentialBitOne( p, pCexState, b, NULL, &fEqual );
+ if ( pTemp == NULL )
+ {
+ if ( fEqual && fPrevStatus )
+ Abc_InfoSetBit( pNew->pData, b );
+ continue;
+ }
+// Bmc_CexPrint( pTemp, Gia_ManPiNum(p) );
+ Abc_CexFree( pPrev );
+ pPrev = pTemp;
+
+ // record essential bit
+ fPrevStatus = !Gia_ManPo(p, pCexState->iPo)->fMark1;
+ if ( !Gia_ManPo(p, pCexState->iPo)->fMark1 )
+ Abc_InfoSetBit( pNew->pData, b );
+ }
+ Abc_CexFreeP( &pPrev );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ printf( "Essentials: " );
+ Bmc_CexPrint( pNew, Gia_ManPiNum(p) );
+ return pNew;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes essential bits of the CEX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex )
+{
+ Abc_Cex_t * pCexImpl = NULL;
+ Abc_Cex_t * pCexStates = Bmc_CexInnerStates( p, pCex, &pCexImpl );
+ Abc_Cex_t * pCexCare = Bmc_CexCareBits( p, pCexStates, pCexImpl, NULL, 1 );
+ Abc_Cex_t * pCexEss, * pCexMin;
+
+ if ( !Bmc_CexVerify( p, pCex, pCexCare ) )
+ printf( "Counter-example care-set verification has failed.\n" );
+
+// Bmc_CexEssentialBitTest( p, pCexStates );
+ pCexEss = Bmc_CexEssentialBits( p, pCexStates, pCexCare );
+
+ pCexMin = Bmc_CexCareBits( p, pCexStates, pCexImpl, pCexEss, 0 );
+
+ if ( !Bmc_CexVerify( p, pCex, pCexMin ) )
+ printf( "Counter-example care-set verification has failed.\n" );
+
+// if ( !Bmc_CexVerify( p, pCex, pCexEss ) )
+// printf( "Counter-example care-set verification has failed.\n" );
+
+ Abc_CexFreeP( &pCexStates );
+ Abc_CexFreeP( &pCexImpl );
+ Abc_CexFreeP( &pCexCare );
+ Abc_CexFreeP( &pCexEss );
+ Abc_CexFreeP( &pCexMin );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+