summaryrefslogtreecommitdiffstats
path: root/src/proof/abs
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-09-15 23:27:46 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2012-09-15 23:27:46 -0700
commit69bbfa98564efc7a8b865f06b01c0e404ac1e658 (patch)
tree188c18f4c23b986b1b1647738e4e14fe63513ec5 /src/proof/abs
parentec95f569dd543d6a6acc8b9910cb605f14e59e61 (diff)
downloadabc-69bbfa98564efc7a8b865f06b01c0e404ac1e658.tar.gz
abc-69bbfa98564efc7a8b865f06b01c0e404ac1e658.tar.bz2
abc-69bbfa98564efc7a8b865f06b01c0e404ac1e658.zip
Created new abstraction package from the code that was all over the place.
Diffstat (limited to 'src/proof/abs')
-rw-r--r--src/proof/abs/abs.c52
-rw-r--r--src/proof/abs/abs.h131
-rw-r--r--src/proof/abs/absDup.c445
-rw-r--r--src/proof/abs/absGla.c1899
-rw-r--r--src/proof/abs/absGlaOld.c1957
-rw-r--r--src/proof/abs/absIter.c147
-rw-r--r--src/proof/abs/absOldCex.c872
-rw-r--r--src/proof/abs/absOldRef.c369
-rw-r--r--src/proof/abs/absOldSat.c986
-rw-r--r--src/proof/abs/absOldSim.c477
-rw-r--r--src/proof/abs/absOut.c458
-rw-r--r--src/proof/abs/absPth.c199
-rw-r--r--src/proof/abs/absRef.c1001
-rw-r--r--src/proof/abs/absRef.h67
-rw-r--r--src/proof/abs/absRef2.c916
-rw-r--r--src/proof/abs/absRef2.h67
-rw-r--r--src/proof/abs/absUtil.c257
-rw-r--r--src/proof/abs/absVta.c1765
-rw-r--r--src/proof/abs/module.make15
19 files changed, 12080 insertions, 0 deletions
diff --git a/src/proof/abs/abs.c b/src/proof/abs/abs.c
new file mode 100644
index 00000000..3ba1abfb
--- /dev/null
+++ b/src/proof/abs/abs.c
@@ -0,0 +1,52 @@
+/**CFile****************************************************************
+
+ FileName [abs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/abs.h b/src/proof/abs/abs.h
new file mode 100644
index 00000000..eeeda583
--- /dev/null
+++ b/src/proof/abs/abs.h
@@ -0,0 +1,131 @@
+/**CFile****************************************************************
+
+ FileName [abs.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__proof_abs__Abs_h
+#define ABC__proof_abs__Abs_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "aig/gia/gia.h"
+#include "aig/gia/giaAig.h"
+#include "aig/saig/saig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// abstraction parameters
+typedef struct Abs_Par_t_ Abs_Par_t;
+struct Abs_Par_t_
+{
+ int nFramesMax; // maximum frames
+ int nFramesStart; // starting frame
+ int nFramesPast; // overlap frames
+ int nConfLimit; // conflict limit
+ int nLearnedMax; // max number of learned clauses
+ int nLearnedStart; // max number of learned clauses
+ int nLearnedDelta; // delta increase of learned clauses
+ int nLearnedPerce; // percentage of clauses to leave
+ int nTimeOut; // timeout in seconds
+ int nRatioMin; // stop when less than this % of object is abstracted
+ int nRatioMax; // restart when the number of abstracted object is more than this
+ int fUseTermVars; // use terminal variables
+ int fUseRollback; // use rollback to the starting number of frames
+ int fPropFanout; // propagate fanout implications
+ int fAddLayer; // refinement strategy by adding layers
+ int fUseSkip; // skip proving intermediate timeframes
+ int fUseSimple; // use simple CNF construction
+ int fSkipHash; // skip hashing CNF while unrolling
+ int fUseFullProof; // use full proof for UNSAT cores
+ int fDumpVabs; // dumps the abstracted model
+ int fDumpMabs; // dumps the original AIG with abstraction map
+ int fCallProver; // calls the prover
+ char * pFileVabs; // dumps the abstracted model into this file
+ int fVerbose; // verbose flag
+ int fVeryVerbose; // print additional information
+ int iFrame; // the number of frames covered
+ int iFrameProved; // the number of frames proved
+ int nFramesNoChange; // the number of last frames without changes
+ int nFramesNoChangeLim; // the number of last frames without changes to dump abstraction
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== abs.c =========================================================*/
+/*=== absDup.c =========================================================*/
+extern Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses );
+extern Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses );
+extern void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes );
+extern void Gia_ManPrintFlopClasses( Gia_Man_t * p );
+extern void Gia_ManPrintObjClasses( Gia_Man_t * p );
+extern void Gia_ManPrintGateClasses( Gia_Man_t * p );
+/*=== absGla.c =========================================================*/
+extern int Gia_ManPerformGla( Gia_Man_t * p, Abs_Par_t * pPars );
+/*=== absGlaOld.c =========================================================*/
+extern int Gia_ManPerformGlaOld( Gia_Man_t * p, Abs_Par_t * pPars, int fStartVta );
+/*=== absIter.c =========================================================*/
+extern Gia_Man_t * Gia_ManShrinkGla( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose );
+/*=== absVta.c =========================================================*/
+extern int Gia_VtaPerform( Gia_Man_t * pAig, Abs_Par_t * pPars );
+/*=== absUtil.c =========================================================*/
+extern void Abs_ParSetDefaults( Abs_Par_t * p );
+extern Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta );
+extern Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames );
+extern Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla );
+extern Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla );
+extern int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla );
+extern int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla );
+
+/*=== absOldCex.c ==========================================================*/
+extern Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect );
+extern Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose );
+/*=== absOldRef.c ==========================================================*/
+extern int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose );
+/*=== absOldSat.c ==========================================================*/
+extern Vec_Int_t * Saig_ManExtendCounterExampleTest3( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose );
+/*=== absOldSim.c ==========================================================*/
+extern Vec_Int_t * Saig_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose );
+
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/abs/absDup.c b/src/proof/abs/absDup.c
new file mode 100644
index 00000000..247137bd
--- /dev/null
+++ b/src/proof/abs/absDup.c
@@ -0,0 +1,445 @@
+/**CFile****************************************************************
+
+ FileName [absDup.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Duplication procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absDup.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG manager recursively.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupAbsFlops_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction of the AIG to preserve the included flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupAbsFlops( Gia_Man_t * p, Vec_Int_t * vFlopClasses )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, nFlops = 0;
+ Gia_ManFillValue( p );
+ // start the new manager
+ pNew = Gia_ManStart( 5000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ // create PIs
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create additional PIs
+ Gia_ManForEachRo( p, pObj, i )
+ if ( !Vec_IntEntry(vFlopClasses, i) )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create ROs
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_IntEntry(vFlopClasses, i) )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create POs
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ // create RIs
+ Gia_ManForEachRi( p, pObj, i )
+ if ( Vec_IntEntry(vFlopClasses, i) )
+ {
+ Gia_ManDupAbsFlops_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ nFlops++;
+ }
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, nFlops );
+ // clean up
+ pNew = Gia_ManSeqCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of neighbors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_GlaCollectAssigned( Gia_Man_t * p, Vec_Int_t * vGateClasses )
+{
+ Vec_Int_t * vAssigned;
+ Gia_Obj_t * pObj;
+ int i, Entry;
+ vAssigned = Vec_IntAlloc( 1000 );
+ Vec_IntForEachEntry( vGateClasses, Entry, i )
+ {
+ if ( Entry == 0 )
+ continue;
+ assert( Entry > 0 );
+ pObj = Gia_ManObj( p, i );
+ Vec_IntPush( vAssigned, Gia_ObjId(p, pObj) );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, pObj) );
+ Vec_IntPush( vAssigned, Gia_ObjFaninId1p(p, pObj) );
+ }
+ else if ( Gia_ObjIsRo(p, pObj) )
+ Vec_IntPush( vAssigned, Gia_ObjFaninId0p(p, Gia_ObjRoToRi(p, pObj)) );
+ else assert( Gia_ObjIsConst0(pObj) );
+ }
+ Vec_IntUniqify( vAssigned );
+ return vAssigned;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects PIs and PPIs of the abstraction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManGlaCollect( Gia_Man_t * p, Vec_Int_t * vGateClasses, Vec_Int_t ** pvPis, Vec_Int_t ** pvPPis, Vec_Int_t ** pvFlops, Vec_Int_t ** pvNodes )
+{
+ Vec_Int_t * vAssigned;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Gia_ManPoNum(p) == 1 );
+ assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) );
+ // create included objects and their fanins
+ vAssigned = Gia_GlaCollectAssigned( p, vGateClasses );
+ // create additional arrays
+ if ( pvPis ) *pvPis = Vec_IntAlloc( 100 );
+ if ( pvPPis ) *pvPPis = Vec_IntAlloc( 100 );
+ if ( pvFlops ) *pvFlops = Vec_IntAlloc( 100 );
+ if ( pvNodes ) *pvNodes = Vec_IntAlloc( 1000 );
+ Gia_ManForEachObjVec( vAssigned, p, pObj, i )
+ {
+ if ( Gia_ObjIsPi(p, pObj) )
+ { if ( pvPis ) Vec_IntPush( *pvPis, Gia_ObjId(p,pObj) ); }
+ else if ( !Vec_IntEntry(vGateClasses, Gia_ObjId(p,pObj)) )
+ { if ( pvPPis ) Vec_IntPush( *pvPPis, Gia_ObjId(p,pObj) ); }
+ else if ( Gia_ObjIsRo(p, pObj) )
+ { if ( pvFlops ) Vec_IntPush( *pvFlops, Gia_ObjId(p,pObj) ); }
+ else if ( Gia_ObjIsAnd(pObj) )
+ { if ( pvNodes ) Vec_IntPush( *pvNodes, Gia_ObjId(p,pObj) ); }
+ else assert( Gia_ObjIsConst0(pObj) );
+ }
+ Vec_IntFree( vAssigned );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG manager recursively.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupAbsGates_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManDupAbsGates_rec( pNew, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction of the AIG to preserve the included gates.]
+
+ Description [The array contains 1 for those objects (const, RO, AND)
+ that are included in the abstraction; 0, otherwise.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupAbsGates( Gia_Man_t * p, Vec_Int_t * vGateClasses )
+{
+ Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pCopy;
+ int i;//, nFlops = 0;
+ assert( Gia_ManPoNum(p) == 1 );
+ assert( Vec_IntSize(vGateClasses) == Gia_ManObjNum(p) );
+
+ // create additional arrays
+ Gia_ManGlaCollect( p, vGateClasses, &vPis, &vPPis, &vFlops, &vNodes );
+
+ // start the new manager
+ pNew = Gia_ManStart( 5000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ // create constant
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ // create PIs
+ Gia_ManForEachObjVec( vPis, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create additional PIs
+ Gia_ManForEachObjVec( vPPis, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create ROs
+ Gia_ManForEachObjVec( vFlops, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ // create internal nodes
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+// Gia_ManDupAbsGates_rec( pNew, pObj );
+ // create PO
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ // create RIs
+ Gia_ManForEachObjVec( vFlops, p, pObj, i )
+ Gia_ObjRoToRi(p, pObj)->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ObjRoToRi(p, pObj)) );
+ Gia_ManSetRegNum( pNew, Vec_IntSize(vFlops) );
+ // clean up
+ pNew = Gia_ManSeqCleanup( pTemp = pNew );
+ // transfer copy values: (p -> pTemp -> pNew) => (p -> pNew)
+ if ( Gia_ManObjNum(pTemp) != Gia_ManObjNum(pNew) )
+ {
+// printf( "Gia_ManDupAbsGates() Internal error: object mismatch.\n" );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( !~pObj->Value )
+ continue;
+ assert( !Abc_LitIsCompl(pObj->Value) );
+ pCopy = Gia_ObjCopy( pTemp, pObj );
+ if ( !~pCopy->Value )
+ {
+ Vec_IntWriteEntry( vGateClasses, i, 0 );
+ pObj->Value = ~0;
+ continue;
+ }
+ assert( !Abc_LitIsCompl(pCopy->Value) );
+ pObj->Value = pCopy->Value;
+ }
+ }
+ Gia_ManStop( pTemp );
+
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPPis );
+ Vec_IntFree( vFlops );
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats for the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintFlopClasses( Gia_Man_t * p )
+{
+ int Counter0, Counter1;
+ if ( p->vFlopClasses == NULL )
+ return;
+ if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) )
+ {
+ printf( "Gia_ManPrintFlopClasses(): The number of flop map entries differs from the number of flops.\n" );
+ return;
+ }
+ Counter0 = Vec_IntCountEntry( p->vFlopClasses, 0 );
+ Counter1 = Vec_IntCountEntry( p->vFlopClasses, 1 );
+ printf( "Flop-level abstraction: Excluded FFs = %d Included FFs = %d (%.2f %%) ",
+ Counter0, Counter1, 100.0*Counter1/(Counter0 + Counter1 + 1) );
+ if ( Counter0 + Counter1 < Gia_ManRegNum(p) )
+ printf( "and there are other FF classes..." );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats for the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintGateClasses( Gia_Man_t * p )
+{
+ Vec_Int_t * vPis, * vPPis, * vFlops, * vNodes;
+ int nTotal;
+ if ( p->vGateClasses == NULL )
+ return;
+ if ( Vec_IntSize(p->vGateClasses) != Gia_ManObjNum(p) )
+ {
+ printf( "Gia_ManPrintGateClasses(): The number of flop map entries differs from the number of flops.\n" );
+ return;
+ }
+ // create additional arrays
+ Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, &vFlops, &vNodes );
+ nTotal = 1 + Vec_IntSize(vFlops) + Vec_IntSize(vNodes);
+ printf( "Gate-level abstraction: PI = %d PPI = %d FF = %d (%.2f %%) AND = %d (%.2f %%) Obj = %d (%.2f %%)\n",
+ Vec_IntSize(vPis), Vec_IntSize(vPPis),
+ Vec_IntSize(vFlops), 100.0*Vec_IntSize(vFlops)/(Gia_ManRegNum(p)+1),
+ Vec_IntSize(vNodes), 100.0*Vec_IntSize(vNodes)/(Gia_ManAndNum(p)+1),
+ nTotal, 100.0*nTotal /(Gia_ManRegNum(p)+Gia_ManAndNum(p)+1) );
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPPis );
+ Vec_IntFree( vFlops );
+ Vec_IntFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats for the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintObjClasses( Gia_Man_t * p )
+{
+ Vec_Int_t * vSeens; // objects seen so far
+ Vec_Int_t * vAbs = p->vObjClasses;
+ int i, k, Entry, iStart, iStop = -1, nFrames;
+ int nObjBits, nObjMask, iObj, iFrame, nWords;
+ unsigned * pInfo;
+ int * pCountAll, * pCountUni;
+ if ( vAbs == NULL )
+ return;
+ nFrames = Vec_IntEntry( vAbs, 0 );
+ assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) );
+ pCountAll = ABC_ALLOC( int, nFrames + 1 );
+ pCountUni = ABC_ALLOC( int, nFrames + 1 );
+ // start storage for seen objects
+ nWords = Abc_BitWordNum( nFrames );
+ vSeens = Vec_IntStart( Gia_ManObjNum(p) * nWords );
+ // get the bitmasks
+ nObjBits = Abc_Base2Log( Gia_ManObjNum(p) );
+ nObjMask = (1 << nObjBits) - 1;
+ assert( Gia_ManObjNum(p) <= nObjMask );
+ // print info about frames
+ printf( "Frame Core F0 F1 F2 F3 ...\n" );
+ for ( i = 0; i < nFrames; i++ )
+ {
+ iStart = Vec_IntEntry( vAbs, i+1 );
+ iStop = Vec_IntEntry( vAbs, i+2 );
+ memset( pCountAll, 0, sizeof(int) * (nFrames + 1) );
+ memset( pCountUni, 0, sizeof(int) * (nFrames + 1) );
+ Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop )
+ {
+ iObj = (Entry & nObjMask);
+ iFrame = (Entry >> nObjBits);
+ pInfo = (unsigned *)Vec_IntEntryP( vSeens, nWords * iObj );
+ if ( Abc_InfoHasBit(pInfo, iFrame) == 0 )
+ {
+ Abc_InfoSetBit( pInfo, iFrame );
+ pCountUni[iFrame+1]++;
+ pCountUni[0]++;
+ }
+ pCountAll[iFrame+1]++;
+ pCountAll[0]++;
+ }
+ assert( pCountAll[0] == (iStop - iStart) );
+// printf( "%5d%5d ", pCountAll[0], pCountUni[0] );
+ printf( "%3d :", i );
+ printf( "%7d", pCountAll[0] );
+ if ( i >= 10 )
+ {
+ for ( k = 0; k < 4; k++ )
+ printf( "%5d", pCountAll[k+1] );
+ printf( " ..." );
+ for ( k = i-4; k <= i; k++ )
+ printf( "%5d", pCountAll[k+1] );
+ }
+ else
+ {
+ for ( k = 0; k <= i; k++ )
+ if ( k <= i )
+ printf( "%5d", pCountAll[k+1] );
+ }
+// for ( k = 0; k < nFrames; k++ )
+// if ( k <= i )
+// printf( "%5d", pCountAll[k+1] );
+ printf( "\n" );
+ }
+ assert( iStop == Vec_IntSize(vAbs) );
+ Vec_IntFree( vSeens );
+ ABC_FREE( pCountAll );
+ ABC_FREE( pCountUni );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absGla.c b/src/proof/abs/absGla.c
new file mode 100644
index 00000000..b026c6e3
--- /dev/null
+++ b/src/proof/abs/absGla.c
@@ -0,0 +1,1899 @@
+/**CFile****************************************************************
+
+ FileName [absGla2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Scalable gate-level abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absGla2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver2.h"
+#include "base/main/main.h"
+#include "abs.h"
+#include "absRef.h"
+//#include "absRef2.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define GA2_BIG_NUM 0x3FFFFFF0
+
+typedef struct Ga2_Man_t_ Ga2_Man_t; // manager
+struct Ga2_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia; // working AIG manager
+ Abs_Par_t * pPars; // parameters
+ // markings
+ Vec_Ptr_t * vCnfs; // for each object: CNF0, CNF1
+ // abstraction
+ Vec_Int_t * vIds; // abstraction ID for each GIA object
+ Vec_Int_t * vProofIds; // mapping of GIA objects into their proof IDs
+ Vec_Int_t * vAbs; // array of abstracted objects
+ Vec_Int_t * vValues; // array of objects with abstraction ID assigned
+ int nProofIds; // the counter of proof IDs
+ int LimAbs; // limit value for starting abstraction objects
+ int LimPpi; // limit value for starting PPI objects
+ int nMarked; // total number of marked nodes and flops
+ // refinement
+ Rnm_Man_t * pRnm; // refinement manager
+// Rf2_Man_t * pRf2; // refinement manager
+ // SAT solver and variables
+ Vec_Ptr_t * vId2Lit; // mapping, for each timeframe, of object ID into SAT literal
+ sat_solver2 * pSat; // incremental SAT solver
+ int nSatVars; // the number of SAT variables
+ int nCexes; // the number of counter-examples
+ int nObjAdded; // objs added during refinement
+ // hash table
+ int * pTable;
+ int nTable;
+ int nHashHit;
+ int nHashMiss;
+ int nHashOver;
+ // temporaries
+ Vec_Int_t * vLits;
+ Vec_Int_t * vIsopMem;
+ char * pSopSizes, ** pSops; // CNF representation
+ // statistics
+ clock_t timeStart;
+ clock_t timeInit;
+ clock_t timeSat;
+ clock_t timeUnsat;
+ clock_t timeCex;
+ clock_t timeOther;
+};
+
+static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); }
+static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); }
+static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); }
+static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); }
+static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); }
+static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; }
+
+static inline int Ga2_ObjId( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vIds, Gia_ObjId(p->pGia, pObj)); }
+static inline void Ga2_ObjSetId( Ga2_Man_t * p, Gia_Obj_t * pObj, int i ) { Vec_IntWriteEntry(p->vIds, Gia_ObjId(p->pGia, pObj), i); }
+
+static inline Vec_Int_t * Ga2_ObjCnf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj) ); }
+static inline Vec_Int_t * Ga2_ObjCnf1( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj)+1 ); }
+
+static inline int Ga2_ObjIsAbs0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < p->LimAbs; }
+static inline int Ga2_ObjIsLeaf0( Ga2_Man_t * p, Gia_Obj_t * pObj ) { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= p->LimAbs && Ga2_ObjId(p,pObj) < p->LimPpi; }
+static inline int Ga2_ObjIsAbs( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjCnf0(p,pObj); }
+static inline int Ga2_ObjIsLeaf( Ga2_Man_t * p, Gia_Obj_t * pObj ) { return Ga2_ObjId(p,pObj) >= 0 && !Ga2_ObjCnf0(p,pObj); }
+
+static inline Vec_Int_t * Ga2_MapFrameMap( Ga2_Man_t * p, int f ) { return (Vec_Int_t *)Vec_PtrEntry( p->vId2Lit, f ); }
+
+// returns literal of this object, or -1 if SAT variable of the object is not assigned
+static inline int Ga2_ObjFindLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+// int Id = Ga2_ObjId(p,pObj);
+ assert( Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < Vec_IntSize(p->vValues) );
+ return Vec_IntEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj) );
+}
+// inserts literal of this object
+static inline void Ga2_ObjAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int Lit )
+{
+// assert( Lit > 1 );
+ assert( Ga2_ObjFindLit(p, pObj, f) == -1 );
+ Vec_IntSetEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj), Lit );
+}
+// returns or inserts-and-returns literal of this object
+static inline int Ga2_ObjFindOrAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+ int Lit = Ga2_ObjFindLit( p, pObj, f );
+ if ( Lit == -1 )
+ {
+ Lit = toLitCond( p->nSatVars++, 0 );
+ Ga2_ObjAddLit( p, pObj, f, Lit );
+ }
+// assert( Lit > 1 );
+ return Lit;
+}
+
+
+// calling pthreads
+extern void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose );
+extern void Gia_Ga2ProveCancel( int fVerbose );
+extern int Gia_Ga2ProveCheck( int fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table for the marked node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ga2_ObjComputeTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst )
+{
+ unsigned Val0, Val1;
+ if ( pObj->fPhase && !fFirst )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Val0 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin0(pObj), 0 );
+ Val1 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin1(pObj), 0 );
+ return (Gia_ObjFaninC0(pObj) ? ~Val0 : Val0) & (Gia_ObjFaninC1(pObj) ? ~Val1 : Val1);
+}
+unsigned Ga2_ManComputeTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves )
+{
+ static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+ Gia_Obj_t * pObj;
+ unsigned Res;
+ int i;
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ pObj->Value = uTruth5[i];
+ Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ pObj->Value = 0;
+ return Res;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns AIG marked for CNF generation.]
+
+ Description [The marking satisfies the following requirements:
+ Each marked node has the number of marked fanins no more than N.]
+
+ SideEffects [Uses pObj->fPhase to store the markings.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Ga2_ManBreakTree_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst, int N )
+{ // breaks a tree rooted at the node into N-feasible subtrees
+ int Val0, Val1;
+ if ( pObj->fPhase && !fFirst )
+ return 1;
+ Val0 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin0(pObj), 0, N );
+ Val1 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin1(pObj), 0, N );
+ if ( Val0 + Val1 < N )
+ return Val0 + Val1;
+ if ( Val0 + Val1 == N )
+ {
+ pObj->fPhase = 1;
+ return 1;
+ }
+ assert( Val0 + Val1 > N );
+ assert( Val0 < N && Val1 < N );
+ if ( Val0 >= Val1 )
+ {
+ Gia_ObjFanin0(pObj)->fPhase = 1;
+ Val0 = 1;
+ }
+ else
+ {
+ Gia_ObjFanin1(pObj)->fPhase = 1;
+ Val1 = 1;
+ }
+ if ( Val0 + Val1 < N )
+ return Val0 + Val1;
+ if ( Val0 + Val1 == N )
+ {
+ pObj->fPhase = 1;
+ return 1;
+ }
+ assert( 0 );
+ return -1;
+}
+int Ga2_ManCheckNodesAnd( Gia_Man_t * p, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ if ( (!Gia_ObjFanin0(pObj)->fPhase && Gia_ObjFaninC0(pObj)) ||
+ (!Gia_ObjFanin1(pObj)->fPhase && Gia_ObjFaninC1(pObj)) )
+ return 0;
+ return 1;
+}
+void Ga2_ManCollectNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes, int fFirst )
+{
+ if ( pObj->fPhase && !fFirst )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Ga2_ManCollectNodes_rec( p, Gia_ObjFanin0(pObj), vNodes, 0 );
+ Ga2_ManCollectNodes_rec( p, Gia_ObjFanin1(pObj), vNodes, 0 );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+
+}
+void Ga2_ManCollectLeaves_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, int fFirst )
+{
+ if ( pObj->fPhase && !fFirst )
+ {
+ Vec_IntPushUnique( vLeaves, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin0(pObj), vLeaves, 0 );
+ Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin1(pObj), vLeaves, 0 );
+}
+int Ga2_ManMarkup( Gia_Man_t * p, int N, int fSimple )
+{
+ static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+// clock_t clk = clock();
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pObj;
+ int i, k, Leaf, CountMarks;
+
+ vLeaves = Vec_IntAlloc( 100 );
+
+ if ( fSimple )
+ {
+ Gia_ManForEachObj( p, pObj, i )
+ pObj->fPhase = !Gia_ObjIsCo(pObj);
+ }
+ else
+ {
+ // label nodes with multiple fanouts and inputs MUXes
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pObj->Value = 0;
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ Gia_ObjFanin0(pObj)->Value++;
+ Gia_ObjFanin1(pObj)->Value++;
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ Gia_ObjFanin0(Gia_ObjFanin0(pObj))->Value++;
+ Gia_ObjFanin1(Gia_ObjFanin0(pObj))->Value++;
+ Gia_ObjFanin0(Gia_ObjFanin1(pObj))->Value++;
+ Gia_ObjFanin1(Gia_ObjFanin1(pObj))->Value++;
+ }
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pObj->fPhase = 0;
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->fPhase = (pObj->Value > 1);
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjFanin0(pObj)->fPhase = 1;
+ else
+ pObj->fPhase = 1;
+ }
+ // add marks when needed
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !pObj->fPhase )
+ continue;
+ Vec_IntClear( vLeaves );
+ Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 );
+ if ( Vec_IntSize(vLeaves) > N )
+ Ga2_ManBreakTree_rec( p, pObj, 1, N );
+ }
+ }
+
+ // verify that the tree is split correctly
+ Vec_IntFreeP( &p->vMapping );
+ p->vMapping = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Gia_Obj_t * pObjRi = Gia_ObjRoToRi(p, pObj);
+ assert( pObj->fPhase );
+ assert( Gia_ObjFanin0(pObjRi)->fPhase );
+ // create map
+ Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) );
+ Vec_IntPush( p->vMapping, 1 );
+ Vec_IntPush( p->vMapping, Gia_ObjFaninId0p(p, pObjRi) );
+ Vec_IntPush( p->vMapping, Gia_ObjFaninC0(pObjRi) ? 0x55555555 : 0xAAAAAAAA );
+ Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter
+ }
+ CountMarks = Gia_ManRegNum(p);
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !pObj->fPhase )
+ continue;
+ Vec_IntClear( vLeaves );
+ Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 );
+ assert( Vec_IntSize(vLeaves) <= N );
+ // create map
+ Vec_IntWriteEntry( p->vMapping, i, Vec_IntSize(p->vMapping) );
+ Vec_IntPush( p->vMapping, Vec_IntSize(vLeaves) );
+ Vec_IntForEachEntry( vLeaves, Leaf, k )
+ {
+ Vec_IntPush( p->vMapping, Leaf );
+ Gia_ManObj(p, Leaf)->Value = uTruth5[k];
+ assert( Gia_ManObj(p, Leaf)->fPhase );
+ }
+ Vec_IntPush( p->vMapping, (int)Ga2_ObjComputeTruth_rec( p, pObj, 1 ) );
+ Vec_IntPush( p->vMapping, -1 ); // placeholder for ref counter
+ CountMarks++;
+ }
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ Vec_IntFree( vLeaves );
+ Gia_ManCleanValue( p );
+ return CountMarks;
+}
+void Ga2_ManComputeTest( Gia_Man_t * p )
+{
+ clock_t clk;
+// unsigned uTruth;
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ clk = clock();
+ Ga2_ManMarkup( p, 5, 0 );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !pObj->fPhase )
+ continue;
+// uTruth = Ga2_ObjTruth( p, pObj );
+// printf( "%6d : ", Counter );
+// Kit_DsdPrintFromTruth( &uTruth, Ga2_ObjLeaveNum(p, pObj) );
+// printf( "\n" );
+ Counter++;
+ }
+ Abc_Print( 1, "Marked AND nodes = %6d. ", Counter );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ga2_Man_t * Ga2_ManStart( Gia_Man_t * pGia, Abs_Par_t * pPars )
+{
+ Ga2_Man_t * p;
+ p = ABC_CALLOC( Ga2_Man_t, 1 );
+ p->timeStart = clock();
+ // user data
+ p->pGia = pGia;
+ p->pPars = pPars;
+ // markings
+ p->nMarked = Ga2_ManMarkup( pGia, 5, pPars->fUseSimple );
+ p->vCnfs = Vec_PtrAlloc( 1000 );
+ Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) );
+ Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) );
+ // abstraction
+ p->vIds = Vec_IntStartFull( Gia_ManObjNum(pGia) );
+ p->vProofIds = Vec_IntAlloc( 0 );
+ p->vAbs = Vec_IntAlloc( 1000 );
+ p->vValues = Vec_IntAlloc( 1000 );
+ // add constant node to abstraction
+ Ga2_ObjSetId( p, Gia_ManConst0(pGia), 0 );
+ Vec_IntPush( p->vValues, 0 );
+ Vec_IntPush( p->vAbs, 0 );
+ // refinement
+ p->pRnm = Rnm_ManStart( pGia );
+// p->pRf2 = Rf2_ManStart( pGia );
+ // SAT solver and variables
+ p->vId2Lit = Vec_PtrAlloc( 1000 );
+ // temporaries
+ p->vLits = Vec_IntAlloc( 100 );
+ p->vIsopMem = Vec_IntAlloc( 100 );
+ Cnf_ReadMsops( &p->pSopSizes, &p->pSops );
+ // hash table
+ p->nTable = Abc_PrimeCudd(1<<18);
+ p->pTable = ABC_CALLOC( int, 6 * p->nTable );
+ return p;
+}
+
+void Ga2_ManDumpStats( Gia_Man_t * pGia, Abs_Par_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN )
+{
+ FILE * pFile;
+ char pFileName[32];
+ sprintf( pFileName, "stats_gla%s%s.txt", fUseN ? "n":"", pPars->fUseFullProof ? "p":"" );
+
+ pFile = fopen( pFileName, "a+" );
+
+ fprintf( pFile, "%s pi=%d ff=%d and=%d mem=%d bmc=%d",
+ pGia->pName,
+ Gia_ManPiNum(pGia), Gia_ManRegNum(pGia), Gia_ManAndNum(pGia),
+ (int)(1 + sat_solver2_memory_proof(pSat)/(1<<20)),
+ iFrame );
+
+ if ( pGia->vGateClasses )
+ fprintf( pFile, " ff=%d and=%d",
+ Gia_GlaCountFlops( pGia, pGia->vGateClasses ),
+ Gia_GlaCountNodes( pGia, pGia->vGateClasses ) );
+
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+void Ga2_ManReportMemory( Ga2_Man_t * p )
+{
+ double memTot = 0;
+ double memAig = 1.0 * p->pGia->nObjsAlloc * sizeof(Gia_Obj_t) + Vec_IntMemory(p->pGia->vMapping);
+ double memSat = sat_solver2_memory( p->pSat, 1 );
+ double memPro = sat_solver2_memory_proof( p->pSat );
+ double memMap = Vec_VecMemoryInt( (Vec_Vec_t *)p->vId2Lit );
+ double memRef = Rnm_ManMemoryUsage( p->pRnm );
+ double memHash= sizeof(int) * 6 * p->nTable;
+ double memOth = sizeof(Ga2_Man_t);
+ memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCnfs );
+ memOth += Vec_IntMemory( p->vIds );
+ memOth += Vec_IntMemory( p->vProofIds );
+ memOth += Vec_IntMemory( p->vAbs );
+ memOth += Vec_IntMemory( p->vValues );
+ memOth += Vec_IntMemory( p->vLits );
+ memOth += Vec_IntMemory( p->vIsopMem );
+ memOth += 336450 + (sizeof(char) + sizeof(char*)) * 65536;
+ memTot = memAig + memSat + memPro + memMap + memRef + memHash + memOth;
+ ABC_PRMP( "Memory: AIG ", memAig, memTot );
+ ABC_PRMP( "Memory: SAT ", memSat, memTot );
+ ABC_PRMP( "Memory: Proof ", memPro, memTot );
+ ABC_PRMP( "Memory: Map ", memMap, memTot );
+ ABC_PRMP( "Memory: Refine ", memRef, memTot );
+ ABC_PRMP( "Memory: Hash ", memHash,memTot );
+ ABC_PRMP( "Memory: Other ", memOth, memTot );
+ ABC_PRMP( "Memory: TOTAL ", memTot, memTot );
+}
+void Ga2_ManStop( Ga2_Man_t * p )
+{
+ Vec_IntFreeP( &p->pGia->vMapping );
+ Gia_ManSetPhase( p->pGia );
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d ObjsAdded = %d\n",
+ sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat),
+ sat_solver2_nconflicts(p->pSat), sat_solver2_nlearnts(p->pSat),
+ p->pSat->nDBreduces, p->nCexes, p->nObjAdded );
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Hash hits = %d. Hash misses = %d. Hash overs = %d.\n",
+ p->nHashHit, p->nHashMiss, p->nHashOver );
+
+ if( p->pSat ) sat_solver2_delete( p->pSat );
+ Vec_VecFree( (Vec_Vec_t *)p->vCnfs );
+ Vec_VecFree( (Vec_Vec_t *)p->vId2Lit );
+ Vec_IntFree( p->vIds );
+ Vec_IntFree( p->vProofIds );
+ Vec_IntFree( p->vAbs );
+ Vec_IntFree( p->vValues );
+ Vec_IntFree( p->vLits );
+ Vec_IntFree( p->vIsopMem );
+ Rnm_ManStop( p->pRnm, 0 );
+// Rf2_ManStop( p->pRf2, p->pPars->fVerbose );
+ ABC_FREE( p->pTable );
+ ABC_FREE( p->pSopSizes );
+ ABC_FREE( p->pSops[1] );
+ ABC_FREE( p->pSops );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes a minimized truth table.]
+
+ Description [Input literals can be 0/1 (const 0/1), non-trivial literals
+ (integers that are more than 1) and unassigned literals (large integers).
+ This procedure computes the truth table that essentially depends on input
+ variables ordered in the increasing order of their positive literals.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned Ga2_ObjTruthDepends( unsigned t, int v )
+{
+ static unsigned uInvTruth5[5] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF };
+ assert( v >= 0 && v <= 4 );
+ return ((t ^ (t >> (1 << v))) & uInvTruth5[v]);
+}
+unsigned Ga2_ObjComputeTruthSpecial( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vLits )
+{
+ int fVerbose = 0;
+ static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+ unsigned Res;
+ Gia_Obj_t * pObj;
+ int i, Entry;
+// int Id = Gia_ObjId(p, pRoot);
+ assert( Gia_ObjIsAnd(pRoot) );
+
+ if ( fVerbose )
+ printf( "Object %d.\n", Gia_ObjId(p, pRoot) );
+
+ // assign elementary truth tables
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ {
+ Entry = Vec_IntEntry( vLits, i );
+ assert( Entry >= 0 );
+ if ( Entry == 0 )
+ pObj->Value = 0;
+ else if ( Entry == 1 )
+ pObj->Value = ~0;
+ else // non-trivial literal
+ pObj->Value = uTruth5[i];
+ if ( fVerbose )
+ printf( "%d ", Entry );
+ }
+
+ if ( fVerbose )
+ {
+ Res = Ga2_ObjTruth( p, pRoot );
+// Kit_DsdPrintFromTruth( &Res, Vec_IntSize(vLeaves) );
+ printf( "\n" );
+ }
+
+ // compute truth table
+ Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
+ if ( Res != 0 && Res != ~0 )
+ {
+ // find essential variables
+ int nUsed = 0, pUsed[5];
+ for ( i = 0; i < Vec_IntSize(vLeaves); i++ )
+ if ( Ga2_ObjTruthDepends( Res, i ) )
+ pUsed[nUsed++] = i;
+ assert( nUsed > 0 );
+ // order positions by literal value
+ Vec_IntSelectSortCost( pUsed, nUsed, vLits );
+ assert( Vec_IntEntry(vLits, pUsed[0]) <= Vec_IntEntry(vLits, pUsed[nUsed-1]) );
+ // assign elementary truth tables to the leaves
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ {
+ Entry = Vec_IntEntry( vLits, i );
+ assert( Entry >= 0 );
+ if ( Entry == 0 )
+ pObj->Value = 0;
+ else if ( Entry == 1 )
+ pObj->Value = ~0;
+ else // non-trivial literal
+ pObj->Value = 0xDEADCAFE; // not important
+ }
+ for ( i = 0; i < nUsed; i++ )
+ {
+ Entry = Vec_IntEntry( vLits, pUsed[i] );
+ assert( Entry > 1 );
+ pObj = Gia_ManObj( p, Vec_IntEntry(vLeaves, pUsed[i]) );
+ pObj->Value = Abc_LitIsCompl(Entry) ? ~uTruth5[i] : uTruth5[i];
+// pObj->Value = uTruth5[i];
+ // remember this literal
+ pUsed[i] = Abc_LitRegular(Entry);
+// pUsed[i] = Entry;
+ }
+ // compute truth table
+ Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
+ // reload the literals
+ Vec_IntClear( vLits );
+ for ( i = 0; i < nUsed; i++ )
+ {
+ Vec_IntPush( vLits, pUsed[i] );
+ assert( Ga2_ObjTruthDepends(Res, i) );
+ if ( fVerbose )
+ printf( "%d ", pUsed[i] );
+ }
+ for ( ; i < 5; i++ )
+ assert( !Ga2_ObjTruthDepends(Res, i) );
+
+if ( fVerbose )
+{
+// Kit_DsdPrintFromTruth( &Res, nUsed );
+ printf( "\n" );
+}
+
+ }
+ else
+ {
+
+if ( fVerbose )
+{
+ Vec_IntClear( vLits );
+ printf( "Const %d\n", Res > 0 );
+}
+
+ }
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ pObj->Value = 0;
+ return Res;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns CNF of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover )
+{
+ extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth );
+ int RetValue;
+ assert( nVars <= 5 );
+ // transform truth table into the SOP
+ RetValue = Kit_TruthIsop( &uTruth, nVars, vCover, 0 );
+ assert( RetValue == 0 );
+ // check the case of constant cover
+ return Vec_IntDup( vCover );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives CNF for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ga2_ManCnfAddDynamic( Ga2_Man_t * p, int uTruth, int Lits[], int iLitOut, int ProofId )
+{
+ int i, k, b, Cube, nClaLits, ClaLits[6];
+// assert( uTruth > 0 && uTruth < 0xffff );
+ 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;
+ Cube = p->pSops[uTruth][k];
+ for ( b = 3; b >= 0; b-- )
+ {
+ if ( Cube % 3 == 0 ) // value 0 --> add positive literal
+ {
+ assert( Lits[b] > 1 );
+ ClaLits[nClaLits++] = Lits[b];
+ }
+ else if ( Cube % 3 == 1 ) // value 1 --> add negative literal
+ {
+ assert( Lits[b] > 1 );
+ ClaLits[nClaLits++] = lit_neg(Lits[b]);
+ }
+ Cube = Cube / 3;
+ }
+ sat_solver2_addclause( p->pSat, ClaLits, ClaLits+nClaLits, ProofId );
+ }
+ }
+}
+void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int Lits[], int iLitOut, int ProofId )
+{
+ Vec_Int_t * vCnf;
+ int i, k, b, Cube, Literal, nClaLits, ClaLits[6];
+ for ( i = 0; i < 2; i++ )
+ {
+ vCnf = i ? vCnf1 : vCnf0;
+ Vec_IntForEachEntry( vCnf, Cube, k )
+ {
+ nClaLits = 0;
+ ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut;
+ for ( b = 0; b < 5; b++ )
+ {
+ Literal = 3 & (Cube >> (b << 1));
+ if ( Literal == 1 ) // value 0 --> add positive literal
+ {
+// assert( Lits[b] > 1 );
+ ClaLits[nClaLits++] = Lits[b];
+ }
+ else if ( Literal == 2 ) // value 1 --> add negative literal
+ {
+// assert( Lits[b] > 1 );
+ ClaLits[nClaLits++] = lit_neg(Lits[b]);
+ }
+ else if ( Literal != 0 )
+ assert( 0 );
+ }
+ sat_solver2_addclause( pSat, ClaLits, ClaLits+nClaLits, ProofId );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned Saig_ManBmcHashKey( int * pArray )
+{
+ static int s_Primes[5] = { 12582917, 25165843, 50331653, 100663319, 201326611 };
+ unsigned i, Key = 0;
+ for ( i = 0; i < 5; i++ )
+ Key += pArray[i] * s_Primes[i];
+ return Key;
+}
+static inline int * Saig_ManBmcLookup( Ga2_Man_t * p, int * pArray )
+{
+ int * pTable = p->pTable + 6 * (Saig_ManBmcHashKey(pArray) % p->nTable);
+ if ( memcmp( pTable, pArray, 20 ) )
+ {
+ if ( pTable[0] == 0 )
+ p->nHashMiss++;
+ else
+ p->nHashOver++;
+ memcpy( pTable, pArray, 20 );
+ pTable[5] = 0;
+ }
+ else
+ p->nHashHit++;
+ assert( pTable + 5 < pTable + 6 * p->nTable );
+ return pTable + 5;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ga2_ManSetupNode( Ga2_Man_t * p, Gia_Obj_t * pObj, int fAbs )
+{
+ unsigned uTruth;
+ int nLeaves;
+// int Id = Gia_ObjId(p->pGia, pObj);
+ assert( pObj->fPhase );
+ assert( Vec_PtrSize(p->vCnfs) == 2 * Vec_IntSize(p->vValues) );
+ // assign abstraction ID to the node
+ if ( Ga2_ObjId(p,pObj) == -1 )
+ {
+ Ga2_ObjSetId( p, pObj, Vec_IntSize(p->vValues) );
+ Vec_IntPush( p->vValues, Gia_ObjId(p->pGia, pObj) );
+ Vec_PtrPush( p->vCnfs, NULL );
+ Vec_PtrPush( p->vCnfs, NULL );
+ }
+ assert( Ga2_ObjCnf0(p, pObj) == NULL );
+ if ( !fAbs )
+ return;
+ Vec_IntPush( p->vAbs, Gia_ObjId(p->pGia, pObj) );
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
+ // compute parameters
+ nLeaves = Ga2_ObjLeaveNum(p->pGia, pObj);
+ uTruth = Ga2_ObjTruth( p->pGia, pObj );
+ // create CNF for pos/neg phases
+ Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), Ga2_ManCnfCompute( uTruth, nLeaves, p->vIsopMem) );
+ Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, Ga2_ManCnfCompute(~uTruth, nLeaves, p->vIsopMem) );
+}
+
+static inline void Ga2_ManAddToAbsOneStatic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int fUseId )
+{
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pLeaf;
+ int k, Lit, iLitOut = Ga2_ObjFindOrAddLit( p, pObj, f );
+ assert( iLitOut > 1 );
+ assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
+ if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) )
+ {
+ iLitOut = Abc_LitNot( iLitOut );
+ sat_solver2_addclause( p->pSat, &iLitOut, &iLitOut + 1, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 );
+ }
+ else
+ {
+ int fUseStatic = 1;
+ Vec_IntClear( p->vLits );
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, k )
+ {
+ Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f - Gia_ObjIsRo(p->pGia, pObj) );
+ Vec_IntPush( p->vLits, Lit );
+ if ( Lit < 2 )
+ fUseStatic = 0;
+ }
+ if ( fUseStatic || Gia_ObjIsRo(p->pGia, pObj) )
+ Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), iLitOut, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 );
+ else
+ {
+ unsigned uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits );
+ Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), iLitOut, Gia_ObjId(p->pGia, pObj) );
+ }
+ }
+}
+static inline void Ga2_ManAddToAbsOneDynamic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+// int Id = Gia_ObjId(p->pGia, pObj);
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pLeaf;
+ unsigned uTruth;
+ int i, Lit;
+
+ assert( Ga2_ObjIsAbs0(p, pObj) );
+ assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
+ if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) )
+ {
+ Ga2_ObjAddLit( p, pObj, f, 0 );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ // if flop is included in the abstraction, but its driver is not
+ // flop input driver has no variable assigned -- we assign it here
+ pLeaf = Gia_ObjRoToRi( p->pGia, pObj );
+ Lit = Ga2_ObjFindOrAddLit( p, Gia_ObjFanin0(pLeaf), f-1 );
+ assert( Lit >= 0 );
+ Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(pLeaf) );
+ Ga2_ObjAddLit( p, pObj, f, Lit );
+ }
+ else
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ Vec_IntClear( p->vLits );
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i )
+ {
+ if ( Ga2_ObjIsAbs0(p, pLeaf) ) // belongs to original abstraction
+ {
+ Lit = Ga2_ObjFindLit( p, pLeaf, f );
+ assert( Lit >= 0 );
+ }
+ else if ( Ga2_ObjIsLeaf0(p, pLeaf) ) // belongs to original PPIs
+ {
+ Lit = Ga2_ObjFindLit( p, pLeaf, f );
+// Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
+ if ( Lit == -1 )
+ {
+ Lit = GA2_BIG_NUM + 2*i;
+// assert( 0 );
+ }
+ }
+ else assert( 0 );
+ Vec_IntPush( p->vLits, Lit );
+ }
+
+ // minimize truth table
+ uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits );
+ if ( uTruth == 0 || uTruth == ~0 ) // const 0 / 1
+ {
+ Lit = (uTruth > 0);
+ Ga2_ObjAddLit( p, pObj, f, Lit );
+ }
+ else if ( uTruth == 0xAAAAAAAA || uTruth == 0x55555555 ) // buffer / inverter
+ {
+ Lit = Vec_IntEntry( p->vLits, 0 );
+ if ( Lit >= GA2_BIG_NUM )
+ {
+ pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) );
+ Lit = Ga2_ObjFindLit( p, pLeaf, f );
+ assert( Lit == -1 );
+ Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
+ }
+ assert( Lit >= 0 );
+ Lit = Abc_LitNotCond( Lit, uTruth == 0x55555555 );
+ Ga2_ObjAddLit( p, pObj, f, Lit );
+ assert( Lit < 10000000 );
+ }
+ else
+ {
+ assert( Vec_IntSize(p->vLits) > 1 && Vec_IntSize(p->vLits) < 6 );
+ // replace literals
+ Vec_IntForEachEntry( p->vLits, Lit, i )
+ {
+ if ( Lit >= GA2_BIG_NUM )
+ {
+ pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) );
+ Lit = Ga2_ObjFindLit( p, pLeaf, f );
+ assert( Lit == -1 );
+ Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
+ Vec_IntWriteEntry( p->vLits, i, Lit );
+ }
+ assert( Lit < 10000000 );
+ }
+
+ // add new nodes
+ if ( Vec_IntSize(p->vLits) == 5 )
+ {
+ Vec_IntClear( p->vLits );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i )
+ Vec_IntPush( p->vLits, Ga2_ObjFindOrAddLit( p, pLeaf, f ) );
+ Lit = Ga2_ObjFindOrAddLit(p, pObj, f);
+ Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), Lit, -1 );
+ }
+ else
+ {
+// int fUseHash = 1;
+ if ( !p->pPars->fSkipHash )
+ {
+ int * pLookup, nSize = Vec_IntSize(p->vLits);
+ assert( Vec_IntSize(p->vLits) < 5 );
+ assert( Vec_IntEntry(p->vLits, 0) <= Vec_IntEntryLast(p->vLits) );
+ assert( Ga2_ObjFindLit(p, pObj, f) == -1 );
+ for ( i = Vec_IntSize(p->vLits); i < 4; i++ )
+ Vec_IntPush( p->vLits, GA2_BIG_NUM );
+ Vec_IntPush( p->vLits, (int)uTruth );
+ assert( Vec_IntSize(p->vLits) == 5 );
+
+ // perform structural hashing here!!!
+ pLookup = Saig_ManBmcLookup( p, Vec_IntArray(p->vLits) );
+ if ( *pLookup == 0 )
+ {
+ *pLookup = Ga2_ObjFindOrAddLit(p, pObj, f);
+ Vec_IntShrink( p->vLits, nSize );
+ Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), *pLookup, -1 );
+ }
+ else
+ Ga2_ObjAddLit( p, pObj, f, *pLookup );
+
+ }
+ else
+ {
+ Lit = Ga2_ObjFindOrAddLit(p, pObj, f);
+ Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), Lit, -1 );
+ }
+ }
+ }
+ }
+}
+
+void Ga2_ManAddAbsClauses( Ga2_Man_t * p, int f )
+{
+ int fSimple = 0;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
+ {
+ if ( i == p->LimAbs )
+ break;
+ if ( fSimple )
+ Ga2_ManAddToAbsOneStatic( p, pObj, f, 0 );
+ else
+ Ga2_ManAddToAbsOneDynamic( p, pObj, f );
+ }
+ Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
+ if ( i >= p->LimAbs )
+ Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 );
+// sat_solver2_simplify( p->pSat );
+}
+
+void Ga2_ManAddToAbs( Ga2_Man_t * p, Vec_Int_t * vToAdd )
+{
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pObj, * pFanin;
+ int f, i, k;
+ // add abstraction objects
+ Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
+ {
+ Ga2_ManSetupNode( p, pObj, 1 );
+ if ( p->pSat->pPrf2 )
+ Vec_IntWriteEntry( p->vProofIds, Gia_ObjId(p->pGia, pObj), p->nProofIds++ );
+ }
+ // add PPI objects
+ Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
+ {
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ if ( Ga2_ObjId( p, pFanin ) == -1 )
+ Ga2_ManSetupNode( p, pFanin, 0 );
+ }
+ // add new clauses to the timeframes
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ {
+ Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 );
+ Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
+ Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 );
+ }
+// sat_solver2_simplify( p->pSat );
+}
+
+void Ga2_ManShrinkAbs( Ga2_Man_t * p, int nAbs, int nValues, int nSatVars )
+{
+ Vec_Int_t * vMap;
+ Gia_Obj_t * pObj;
+ int i, k, Entry;
+ assert( nAbs > 0 );
+ assert( nValues > 0 );
+ assert( nSatVars > 0 );
+ // shrink abstraction
+ Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
+ {
+ if ( !i ) continue;
+ assert( Ga2_ObjCnf0(p, pObj) != NULL );
+ assert( Ga2_ObjCnf1(p, pObj) != NULL );
+ if ( i < nAbs )
+ continue;
+ Vec_IntFree( Ga2_ObjCnf0(p, pObj) );
+ Vec_IntFree( Ga2_ObjCnf1(p, pObj) );
+ Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj), NULL );
+ Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, NULL );
+ }
+ Vec_IntShrink( p->vAbs, nAbs );
+ // shrink values
+ Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
+ {
+ assert( Ga2_ObjId(p,pObj) >= 0 );
+ if ( i < nValues )
+ continue;
+ Ga2_ObjSetId( p, pObj, -1 );
+ }
+ Vec_IntShrink( p->vValues, nValues );
+ Vec_PtrShrink( p->vCnfs, 2 * nValues );
+ // hack to clear constant
+ if ( nValues == 1 )
+ nValues = 0;
+ // clean mapping for each timeframe
+ Vec_PtrForEachEntry( Vec_Int_t *, p->vId2Lit, vMap, i )
+ {
+ Vec_IntShrink( vMap, nValues );
+ Vec_IntForEachEntryStart( vMap, Entry, k, p->LimAbs )
+ if ( Entry >= 2*nSatVars )
+ Vec_IntWriteEntry( vMap, k, -1 );
+ }
+ // shrink SAT variables
+ p->nSatVars = nSatVars;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ga2_ManAbsTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vClasses, int fFirst )
+{
+ if ( pObj->fPhase && !fFirst )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin0(pObj), vClasses, 0 );
+ Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin1(pObj), vClasses, 0 );
+ Vec_IntWriteEntry( vClasses, Gia_ObjId(p, pObj), 1 );
+}
+
+Vec_Int_t * Ga2_ManAbsTranslate( Ga2_Man_t * p )
+{
+ Vec_Int_t * vGateClasses;
+ Gia_Obj_t * pObj;
+ int i;
+ vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) );
+ Vec_IntWriteEntry( vGateClasses, 0, 1 );
+ Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Ga2_ManAbsTranslate_rec( p->pGia, pObj, vGateClasses, 1 );
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ Vec_IntWriteEntry( vGateClasses, Gia_ObjId(p->pGia, pObj), 1 );
+ else if ( !Gia_ObjIsConst0(pObj) )
+ assert( 0 );
+// Gia_ObjPrint( p->pGia, pObj );
+ }
+ return vGateClasses;
+}
+
+Vec_Int_t * Ga2_ManAbsDerive( Gia_Man_t * p )
+{
+ Vec_Int_t * vToAdd;
+ Gia_Obj_t * pObj;
+ int i;
+ vToAdd = Vec_IntAlloc( 1000 );
+ Gia_ManForEachRo( p, pObj, i )
+ if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)) )
+ Vec_IntPush( vToAdd, Gia_ObjId(p, pObj) );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, i) )
+ Vec_IntPush( vToAdd, i );
+ return vToAdd;
+}
+
+void Ga2_ManRestart( Ga2_Man_t * p )
+{
+ Vec_Int_t * vToAdd;
+ int Lit = 1;
+ assert( p->pGia != NULL && p->pGia->vGateClasses != NULL );
+ assert( Gia_ManPi(p->pGia, 0)->fPhase ); // marks are set
+ // clear SAT variable numbers (begin with 1)
+ if ( p->pSat ) sat_solver2_delete( p->pSat );
+ p->pSat = sat_solver2_new();
+ p->pSat->nLearntStart = p->pPars->nLearnedStart;
+ p->pSat->nLearntDelta = p->pPars->nLearnedDelta;
+ p->pSat->nLearntRatio = p->pPars->nLearnedPerce;
+ p->pSat->nLearntMax = p->pSat->nLearntStart;
+ // add clause x0 = 0 (lit0 = 1; lit1 = 0)
+ sat_solver2_addclause( p->pSat, &Lit, &Lit + 1, -1 );
+ // remove previous abstraction
+ Ga2_ManShrinkAbs( p, 1, 1, 1 );
+ // start new abstraction
+ vToAdd = Ga2_ManAbsDerive( p->pGia );
+ assert( p->pSat->pPrf2 == NULL );
+ assert( p->pPars->iFrame < 0 );
+ Ga2_ManAddToAbs( p, vToAdd );
+ Vec_IntFree( vToAdd );
+ p->LimAbs = Vec_IntSize(p->vAbs);
+ p->LimPpi = Vec_IntSize(p->vValues);
+ // set runtime limit
+ if ( p->pPars->nTimeOut )
+ sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + p->timeStart );
+ // clean the hash table
+ memset( p->pTable, 0, 6 * sizeof(int) * p->nTable );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vec_IntCheckUnique( Vec_Int_t * p )
+{
+ int RetValue;
+ Vec_Int_t * pDup = Vec_IntDup( p );
+ Vec_IntUniqify( pDup );
+ RetValue = Vec_IntSize(p) - Vec_IntSize(pDup);
+ Vec_IntFree( pDup );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Ga2_ObjSatValue( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+ int Lit = Ga2_ObjFindLit( p, pObj, f );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Lit == -1 )
+ return 0;
+ if ( Abc_Lit2Var(Lit) >= p->pSat->size )
+ return 0;
+ return Abc_LitIsCompl(Lit) ^ sat_solver2_var_value( p->pSat, Abc_Lit2Var(Lit) );
+}
+Abc_Cex_t * Ga2_ManDeriveCex( Ga2_Man_t * p, Vec_Int_t * vPis )
+{
+ Abc_Cex_t * pCex;
+ Gia_Obj_t * pObj;
+ int i, f;
+ pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
+ pCex->iPo = 0;
+ pCex->iFrame = p->pPars->iFrame;
+ Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
+ {
+ if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ assert( Gia_ObjIsPi(p->pGia, pObj) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ if ( Ga2_ObjSatValue( p, pObj, f ) )
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) );
+ }
+ return pCex;
+}
+void Ga2_ManRefinePrint( Ga2_Man_t * p, Vec_Int_t * vVec )
+{
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k;
+ printf( "\n Unsat core: \n" );
+ Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
+ {
+ Vec_Int_t * vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ printf( "%12d : ", i );
+ printf( "Obj =%6d ", Gia_ObjId(p->pGia, pObj) );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ printf( "ff " );
+ else
+ printf( " " );
+ if ( Ga2_ObjIsAbs0(p, pObj) )
+ printf( "a " );
+ else if ( Ga2_ObjIsLeaf0(p, pObj) )
+ printf( "l " );
+ else
+ printf( " " );
+ printf( "Fanins: " );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ {
+ printf( "%6d ", Gia_ObjId(p->pGia, pFanin) );
+ if ( Gia_ObjIsRo(p->pGia, pFanin) )
+ printf( "ff " );
+ else
+ printf( " " );
+ if ( Ga2_ObjIsAbs0(p, pFanin) )
+ printf( "a " );
+ else if ( Ga2_ObjIsLeaf0(p, pFanin) )
+ printf( "l " );
+ else
+ printf( " " );
+ }
+ printf( "\n" );
+ }
+}
+void Ga2_ManRefinePrintPPis( Ga2_Man_t * p )
+{
+ Vec_Int_t * vVec = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
+ {
+ if ( !i ) continue;
+ if ( Ga2_ObjIsAbs(p, pObj) )
+ continue;
+ assert( pObj->fPhase );
+ assert( Ga2_ObjIsLeaf(p, pObj) );
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
+ Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) );
+ }
+ printf( " Current PPIs (%d): ", Vec_IntSize(vVec) );
+ Vec_IntSort( vVec, 1 );
+ Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
+ printf( "%d ", Gia_ObjId(p->pGia, pObj) );
+ printf( "\n" );
+ Vec_IntFree( vVec );
+}
+
+
+void Ga2_GlaPrepareCexAndMap( Ga2_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMaps )
+{
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vMap;
+ Gia_Obj_t * pObj;
+ int f, i, k;
+/*
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ if ( Ga2_ObjId(p, pObj) >= 0 )
+ assert( Vec_IntEntry(p->vValues, Ga2_ObjId(p, pObj)) == i );
+*/
+ // find PIs and PPIs
+ vMap = Vec_IntAlloc( 1000 );
+ Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
+ {
+ if ( !i ) continue;
+ if ( Ga2_ObjIsAbs(p, pObj) )
+ continue;
+ assert( pObj->fPhase );
+ assert( Ga2_ObjIsLeaf(p, pObj) );
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
+ Vec_IntPush( vMap, Gia_ObjId(p->pGia, pObj) );
+ }
+ // derive counter-example
+ pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 );
+ pCex->iFrame = p->pPars->iFrame;
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ Gia_ManForEachObjVec( vMap, p->pGia, pObj, k )
+ if ( Ga2_ObjSatValue( p, pObj, f ) )
+ Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k );
+ *pvMaps = vMap;
+ *ppCex = pCex;
+}
+Vec_Int_t * Ga2_ManRefine( Ga2_Man_t * p )
+{
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vMap, * vVec;
+ Gia_Obj_t * pObj;
+ int i, k;
+ if ( p->pPars->fAddLayer )
+ {
+ // use simplified refinement strategy, which adds logic near at PPI without finding important ones
+ vVec = Vec_IntAlloc( 100 );
+ Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
+ {
+ if ( !i ) continue;
+ if ( Ga2_ObjIsAbs(p, pObj) )
+ continue;
+ assert( pObj->fPhase );
+ assert( Ga2_ObjIsLeaf(p, pObj) );
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
+ if ( Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) );
+ }
+ p->nObjAdded += Vec_IntSize(vVec);
+ return vVec;
+ }
+ Ga2_GlaPrepareCexAndMap( p, &pCex, &vMap );
+ // Rf2_ManRefine( p->pRf2, pCex, vMap, p->pPars->fPropFanout, 1 );
+ vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 1, 1 );
+// printf( "Refinement %d\n", Vec_IntSize(vVec) );
+ Abc_CexFree( pCex );
+ if ( Vec_IntSize(vVec) == 0 )
+ {
+ Vec_IntFree( vVec );
+ Abc_CexFreeP( &p->pGia->pCexSeq );
+ p->pGia->pCexSeq = Ga2_ManDeriveCex( p, vMap );
+ Vec_IntFree( vMap );
+ return NULL;
+ }
+ Vec_IntFree( vMap );
+ // remove those already added
+ k = 0;
+ Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
+ if ( !Ga2_ObjIsAbs(p, pObj) )
+ Vec_IntWriteEntry( vVec, k++, Gia_ObjId(p->pGia, pObj) );
+ Vec_IntShrink( vVec, k );
+
+ // these objects should be PPIs that are not abstracted yet
+ Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
+ assert( pObj->fPhase );//&& Ga2_ObjIsLeaf(p, pObj) );
+ p->nObjAdded += Vec_IntSize(vVec);
+ return vVec;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ga2_GlaAbsCount( Ga2_Man_t * p, int fRo, int fAnd )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ if ( fRo )
+ Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
+ Counter += Gia_ObjIsRo(p->pGia, pObj);
+ else if ( fAnd )
+ Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
+ Counter += Gia_ObjIsAnd(pObj);
+ else assert( 0 );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ga2_ManAbsPrintFrame( Ga2_Man_t * p, int nFrames, int nConfls, int nCexes, clock_t Time, int fFinal )
+{
+ if ( Abc_FrameIsBatchMode() && !(((fFinal && nCexes) || p->pPars->fVeryVerbose)) )
+ return;
+ Abc_Print( 1, "%4d :", nFrames );
+ Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Vec_IntSize(p->vAbs) / p->nMarked) );
+ Abc_Print( 1, "%6d", Vec_IntSize(p->vAbs) );
+ Abc_Print( 1, "%5d", Vec_IntSize(p->vValues)-Vec_IntSize(p->vAbs)-1 );
+ Abc_Print( 1, "%5d", Ga2_GlaAbsCount(p, 1, 0) );
+ Abc_Print( 1, "%6d", Ga2_GlaAbsCount(p, 0, 1) );
+ Abc_Print( 1, "%8d", nConfls );
+ if ( nCexes == 0 )
+ Abc_Print( 1, "%5c", '-' );
+ else
+ Abc_Print( 1, "%5d", nCexes );
+ Abc_PrintInt( sat_solver2_nvars(p->pSat) );
+ Abc_PrintInt( sat_solver2_nclauses(p->pSat) );
+ Abc_PrintInt( sat_solver2_nlearnts(p->pSat) );
+ Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC );
+ Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) );
+ Abc_Print( 1, "%s", ((fFinal && nCexes) || p->pPars->fVeryVerbose) ? "\n" : "\r" );
+ fflush( stdout );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Ga2_GlaGetFileName( Ga2_Man_t * p, int fAbs )
+{
+ static char * pFileNameDef = "glabs.aig";
+ if ( p->pPars->pFileVabs )
+ return p->pPars->pFileVabs;
+ if ( p->pGia->pSpec )
+ {
+ if ( fAbs )
+ return Extra_FileNameGenericAppend( p->pGia->pSpec, "_abs.aig");
+ else
+ return Extra_FileNameGenericAppend( p->pGia->pSpec, "_gla.aig");
+ }
+ return pFileNameDef;
+}
+
+void Ga2_GlaDumpAbsracted( Ga2_Man_t * p, int fVerbose )
+{
+ char * pFileName;
+ assert( p->pPars->fDumpMabs || p->pPars->fDumpVabs || p->pPars->fCallProver );
+ if ( p->pPars->fDumpMabs )
+ {
+ pFileName = Ga2_GlaGetFileName(p, 0);
+// if ( fVerbose )
+// Abc_Print( 1, "Dumping miter with abstraction map into file \"%s\"...\n", pFileName );
+ // dump abstraction map
+ Vec_IntFreeP( &p->pGia->vGateClasses );
+ p->pGia->vGateClasses = Ga2_ManAbsTranslate( p );
+ Gia_WriteAiger( p->pGia, pFileName, 0, 0 );
+ }
+ if ( p->pPars->fDumpVabs || p->pPars->fCallProver )
+ {
+ Vec_Int_t * vGateClasses;
+ Gia_Man_t * pAbs;
+ pFileName = Ga2_GlaGetFileName(p, 1);
+// if ( fVerbose )
+// Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName );
+ // dump absracted model
+ vGateClasses = Ga2_ManAbsTranslate( p );
+ pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses );
+ Gia_ManCleanValue( p->pGia );
+ Gia_WriteAiger( pAbs, pFileName, 0, 0 );
+ Gia_ManStop( pAbs );
+ Vec_IntFreeP( &vGateClasses );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_Ga2SendAbsracted( Ga2_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p );
+ Gia_Man_t * pAbs;
+ Vec_Int_t * vGateClasses;
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Sending abstracted model...\n" );
+ // create abstraction (value of p->pGia is not used here)
+ vGateClasses = Ga2_ManAbsTranslate( p );
+ pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses );
+ Vec_IntFreeP( &vGateClasses );
+ Gia_ManCleanValue( p->pGia );
+ // send it out
+ Gia_ManToBridgeAbsNetlist( stdout, pAbs );
+ Gia_ManStop( pAbs );
+}
+void Gia_Ga2SendCancel( Ga2_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeBadAbs( FILE * pFile );
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Cancelling previously sent model...\n" );
+ Gia_ManToBridgeBadAbs( stdout );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs gate-level abstraction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManPerformGla( Gia_Man_t * pAig, Abs_Par_t * pPars )
+{
+ int fUseSecondCore = 1;
+ Ga2_Man_t * p;
+ Vec_Int_t * vCore, * vPPis;
+ clock_t clk2, clk = clock();
+ int Status = l_Undef, RetValue = -1, iFrameTryToProve = -1, fOneIsSent = 0;
+ int i, c, f, Lit;
+ // check trivial case
+ assert( Gia_ManPoNum(pAig) == 1 );
+ ABC_FREE( pAig->pCexSeq );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) )
+ {
+ if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) )
+ {
+ Abc_Print( 1, "Sequential miter is trivially UNSAT.\n" );
+ return 1;
+ }
+ pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 );
+ Abc_Print( 1, "Sequential miter is trivially SAT.\n" );
+ return 0;
+ }
+ // create gate classes if not given
+ if ( pAig->vGateClasses == NULL )
+ {
+ pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) );
+ Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 );
+ Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 );
+ }
+ // start the manager
+ p = Ga2_ManStart( pAig, pPars );
+ p->timeInit = clock() - clk;
+ // perform initial abstraction
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" );
+ Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %% RatioMax = %d %%\n",
+ pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin, pPars->nRatioMax );
+ Abc_Print( 1, "LrnStart = %d LrnDelta = %d LrnRatio = %d %% Skip = %d SimpleCNF = %d Dump = %d\n",
+ pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce, pPars->fUseSkip, pPars->fUseSimple, pPars->fDumpVabs|pPars->fDumpMabs|pPars->fCallProver );
+ if ( pPars->fDumpVabs || pPars->fDumpMabs )
+ Abc_Print( 1, "%s will be dumped into file \"%s\".\n",
+ pPars->fDumpVabs ? "Abstracted model" : "Miter with abstraction map",
+ Ga2_GlaGetFileName(p, pPars->fDumpVabs) );
+ Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" );
+ }
+ // iterate unrolling
+ for ( i = f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; i++ )
+ {
+ int nAbsOld;
+ // remember the timeframe
+ p->pPars->iFrame = -1;
+ // create new SAT solver
+ Ga2_ManRestart( p );
+ // remember abstraction size after the last restart
+ nAbsOld = Vec_IntSize(p->vAbs);
+ // unroll the circuit
+ for ( f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; f++ )
+ {
+ // remember current limits
+ int nConflsBeg = sat_solver2_nconflicts(p->pSat);
+ int nAbs = Vec_IntSize(p->vAbs);
+ int nValues = Vec_IntSize(p->vValues);
+ int nVarsOld;
+ // remember the timeframe
+ p->pPars->iFrame = f;
+ // extend and clear storage
+ if ( f == Vec_PtrSize(p->vId2Lit) )
+ Vec_PtrPush( p->vId2Lit, Vec_IntAlloc(0) );
+ Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 );
+ // add static clauses to this timeframe
+ Ga2_ManAddAbsClauses( p, f );
+ // skip checking if skipcheck is enabled (&gla -s)
+ if ( p->pPars->fUseSkip && f <= p->pPars->iFrameProved )
+ continue;
+ // skip checking if we need to skip several starting frames (&gla -S <num>)
+ if ( p->pPars->nFramesStart && f <= p->pPars->nFramesStart )
+ continue;
+ // get the output literal
+// Lit = Ga2_ManUnroll_rec( p, Gia_ManPo(pAig,0), f );
+ Lit = Ga2_ObjFindLit( p, Gia_ObjFanin0(Gia_ManPo(pAig,0)), f );
+ assert( Lit >= 0 );
+ Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(Gia_ManPo(pAig,0)) );
+ if ( Lit == 0 )
+ continue;
+ assert( Lit > 1 );
+ // check for counter-examples
+ if ( p->nSatVars > sat_solver2_nvars(p->pSat) )
+ sat_solver2_setnvars( p->pSat, p->nSatVars );
+ nVarsOld = p->nSatVars;
+ for ( c = 0; ; c++ )
+ {
+ // consider the special case when the target literal is implied false
+ // by implications which happened as a result of previous refinements
+ // note that incremental UNSAT core cannot be computed because there is no learned clauses
+ // in this case, we will assume that UNSAT core cannot reduce the problem
+ if ( var_is_assigned(p->pSat, Abc_Lit2Var(Lit)) )
+ {
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ break;
+ }
+ // perform SAT solving
+ clk2 = clock();
+ Status = sat_solver2_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_True ) // perform refinement
+ {
+ p->nCexes++;
+ p->timeSat += clock() - clk2;
+
+ // cancel old one if it was sent
+ if ( Abc_FrameIsBridgeMode() && fOneIsSent )
+ {
+ Gia_Ga2SendCancel( p, pPars->fVerbose );
+ fOneIsSent = 0;
+ }
+ if ( iFrameTryToProve >= 0 )
+ {
+ Gia_Ga2ProveCancel( pPars->fVerbose );
+ iFrameTryToProve = -1;
+ }
+
+ // perform refinement
+ clk2 = clock();
+ vPPis = Ga2_ManRefine( p );
+ p->timeCex += clock() - clk2;
+ if ( vPPis == NULL )
+ {
+ if ( pPars->fVerbose )
+ Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 );
+ goto finish;
+ }
+
+ if ( c == 0 )
+ {
+// Ga2_ManRefinePrintPPis( p );
+ // create bookmark to be used for rollback
+ assert( nVarsOld == p->pSat->size );
+ sat_solver2_bookmark( p->pSat );
+ // start incremental proof manager
+ assert( p->pSat->pPrf2 == NULL );
+ p->pSat->pPrf2 = Prf_ManAlloc();
+ if ( p->pSat->pPrf2 )
+ {
+ p->nProofIds = 0;
+ Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 );
+ Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) );
+ }
+ }
+ else
+ {
+ // resize the proof logger
+ if ( p->pSat->pPrf2 )
+ Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) );
+ }
+
+ Ga2_ManAddToAbs( p, vPPis );
+ Vec_IntFree( vPPis );
+ if ( pPars->fVerbose )
+ Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c+1, clock() - clk, 0 );
+ continue;
+ }
+ p->timeUnsat += clock() - clk2;
+ if ( Status == l_Undef ) // ran out of resources
+ goto finish;
+ if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit ) // timeout
+ goto finish;
+ if ( c == 0 )
+ {
+ if ( f > p->pPars->iFrameProved )
+ p->pPars->nFramesNoChange++;
+ break;
+ }
+ if ( f > p->pPars->iFrameProved )
+ p->pPars->nFramesNoChange = 0;
+
+ // derive the core
+ assert( p->pSat->pPrf2 != NULL );
+ vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat );
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ // update the SAT solver
+ sat_solver2_rollback( p->pSat );
+ // reduce abstraction
+ Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld );
+
+ // purify UNSAT core
+ if ( fUseSecondCore )
+ {
+// int nOldCore = Vec_IntSize(vCore);
+ // reverse the order of objects in the core
+// Vec_IntSort( vCore, 0 );
+// Vec_IntPrint( vCore );
+ // create bookmark to be used for rollback
+ assert( nVarsOld == p->pSat->size );
+ sat_solver2_bookmark( p->pSat );
+ // start incremental proof manager
+ assert( p->pSat->pPrf2 == NULL );
+ p->pSat->pPrf2 = Prf_ManAlloc();
+ if ( p->pSat->pPrf2 )
+ {
+ p->nProofIds = 0;
+ Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 );
+ Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vCore) );
+
+ Ga2_ManAddToAbs( p, vCore );
+ Vec_IntFree( vCore );
+ }
+ // run SAT solver
+ clk2 = clock();
+ Status = sat_solver2_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_Undef )
+ goto finish;
+ assert( Status == l_False );
+ p->timeUnsat += clock() - clk2;
+
+ // derive the core
+ assert( p->pSat->pPrf2 != NULL );
+ vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat );
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ // update the SAT solver
+ sat_solver2_rollback( p->pSat );
+ // reduce abstraction
+ Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld );
+// printf( "\n%4d -> %4d\n", nOldCore, Vec_IntSize(vCore) );
+ }
+
+ Ga2_ManAddToAbs( p, vCore );
+// Ga2_ManRefinePrint( p, vCore );
+ Vec_IntFree( vCore );
+ break;
+ }
+ // remember the last proved frame
+ if ( p->pPars->iFrameProved < f )
+ p->pPars->iFrameProved = f;
+ // print statistics
+ if ( pPars->fVerbose )
+ Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, clock() - clk, 1 );
+ // check if abstraction was proved
+ if ( Gia_Ga2ProveCheck( pPars->fVerbose ) )
+ {
+ RetValue = 1;
+ goto finish;
+ }
+ if ( c > 0 )
+ {
+ if ( p->pPars->fVeryVerbose )
+ Abc_Print( 1, "\n" );
+ // recompute the abstraction
+ Vec_IntFreeP( &pAig->vGateClasses );
+ pAig->vGateClasses = Ga2_ManAbsTranslate( p );
+ // check if the number of objects is below limit
+ if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 )
+ {
+ Status = l_Undef;
+ goto finish;
+ }
+ }
+ // check the number of stable frames
+ if ( p->pPars->nFramesNoChange == p->pPars->nFramesNoChangeLim )
+ {
+ // dump the model into file
+ if ( p->pPars->fDumpVabs || p->pPars->fDumpMabs || p->pPars->fCallProver )
+ {
+ char Command[1000];
+ Abc_FrameSetStatus( -1 );
+ Abc_FrameSetCex( NULL );
+ Abc_FrameSetNFrames( f+1 );
+ sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") );
+ Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
+ Ga2_GlaDumpAbsracted( p, pPars->fVerbose );
+ }
+ // call the prover
+ if ( p->pPars->fCallProver )
+ {
+ // cancel old one if it is proving
+ if ( iFrameTryToProve >= 0 )
+ Gia_Ga2ProveCancel( pPars->fVerbose );
+ // prove new one
+ Gia_Ga2ProveAbsracted( Ga2_GlaGetFileName(p, 1), pPars->fVerbose );
+ iFrameTryToProve = f;
+ }
+ // speak to the bridge
+ if ( Abc_FrameIsBridgeMode() )
+ {
+ // cancel old one if it was sent
+ if ( fOneIsSent )
+ Gia_Ga2SendCancel( p, pPars->fVerbose );
+ // send new one
+ Gia_Ga2SendAbsracted( p, pPars->fVerbose );
+ fOneIsSent = 1;
+ }
+ }
+ // if abstraction grew more than a certain percentage, force a restart
+ if ( pPars->nRatioMax == 0 )
+ continue;
+ if ( c > 0 && (f > 20 || Vec_IntSize(p->vAbs) > 100) && Vec_IntSize(p->vAbs) - nAbsOld >= nAbsOld * pPars->nRatioMax / 100 )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Forcing restart because abstraction grew from %d to %d (more than %d %%).\n",
+ nAbsOld, Vec_IntSize(p->vAbs), pPars->nRatioMax );
+ break;
+ }
+ }
+ }
+finish:
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ // cancel old one if it is proving
+ if ( iFrameTryToProve >= 0 )
+ Gia_Ga2ProveCancel( pPars->fVerbose );
+ // analize the results
+ if ( RetValue == 1 )
+ Abc_Print( 1, "GLA completed %d frames and proved abstraction derived in frame %d. ", p->pPars->iFrameProved+1, iFrameTryToProve );
+ else if ( pAig->pCexSeq == NULL )
+ {
+// if ( pAig->vGateClasses != NULL )
+// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" );
+ Vec_IntFreeP( &pAig->vGateClasses );
+ pAig->vGateClasses = Ga2_ManAbsTranslate( p );
+ if ( Status == l_Undef )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "\n" );
+ if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit )
+ Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
+ else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit )
+ Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
+ else if ( Vec_IntSize(p->vAbs) >= p->nMarked * (100 - pPars->nRatioMin) / 100 )
+ Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, p->pPars->iFrameProved+1 );
+ else
+ Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", p->pPars->iFrameProved+1 );
+ }
+ else
+ {
+ p->pPars->iFrame = p->pPars->iFrameProved;
+ Abc_Print( 1, "GLA completed %d frames and produced a %d-stable abstraction. ", p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
+ }
+ }
+ else
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "\n" );
+ if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) )
+ Abc_Print( 1, " Gia_ManPerformGlaOld(): CEX verification has failed!\n" );
+ Abc_Print( 1, "True counter-example detected in frame %d. ", f );
+ p->pPars->iFrame = f - 1;
+ Vec_IntFreeP( &pAig->vGateClasses );
+ RetValue = 0;
+ }
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ if ( p->pPars->fVerbose )
+ {
+ p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit;
+ ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk );
+ ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk );
+ ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk );
+ ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk );
+ ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk );
+ ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk );
+ Ga2_ManReportMemory( p );
+ }
+// Ga2_ManDumpStats( p->pGia, p->pPars, p->pSat, p->pPars->iFrameProved, 0 );
+ Ga2_ManStop( p );
+ fflush( stdout );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absGlaOld.c b/src/proof/abs/absGlaOld.c
new file mode 100644
index 00000000..5ee69739
--- /dev/null
+++ b/src/proof/abs/absGlaOld.c
@@ -0,0 +1,1957 @@
+/**CFile****************************************************************
+
+ FileName [absGla.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Gate-level abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absGla.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver2.h"
+#include "base/main/main.h"
+#include "abs.h"
+#include "absRef.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Rfn_Obj_t_ Rfn_Obj_t; // refinement object
+struct Rfn_Obj_t_
+{
+ unsigned Value : 1; // value
+ unsigned fVisit : 1; // visited
+ unsigned fPPi : 1; // PPI
+ unsigned Prio : 16; // priority
+ unsigned Sign : 12; // traversal signature
+};
+
+typedef struct Gla_Obj_t_ Gla_Obj_t; // abstraction object
+struct Gla_Obj_t_
+{
+ int iGiaObj; // corresponding GIA obj
+ unsigned fAbs : 1; // belongs to abstraction
+ unsigned fCompl0 : 1; // compl bit of the first fanin
+ unsigned fConst : 1; // object attribute
+ unsigned fPi : 1; // object attribute
+ unsigned fPo : 1; // object attribute
+ unsigned fRo : 1; // object attribute
+ unsigned fRi : 1; // object attribute
+ unsigned fAnd : 1; // object attribute
+ unsigned fMark : 1; // nearby object
+ unsigned nFanins : 23; // fanin count
+ int Fanins[4]; // fanins
+ Vec_Int_t vFrames; // variables in each timeframe
+};
+
+typedef struct Gla_Man_t_ Gla_Man_t; // manager
+struct Gla_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia0; // starting AIG manager
+ Gia_Man_t * pGia; // working AIG manager
+ Abs_Par_t * pPars; // parameters
+ // internal data
+ Vec_Int_t * vAbs; // abstracted objects
+ Gla_Obj_t * pObjRoot; // the primary output
+ Gla_Obj_t * pObjs; // objects
+ unsigned * pObj2Obj; // mapping of GIA obj into GLA obj
+ int nObjs; // the number of objects
+ int nAbsOld; // previous abstraction
+// int nAbsNew; // previous abstraction
+// int nLrnOld; // the number of bytes
+// int nLrnNew; // the number of bytes
+ // other data
+ int nCexes; // the number of counter-examples
+ int nObjAdded; // total number of objects added
+ int nSatVars; // the number of SAT variables
+ Cnf_Dat_t * pCnf; // CNF derived for the nodes
+ sat_solver2 * pSat; // incremental SAT solver
+ Vec_Int_t * vTemp; // temporary array
+ Vec_Int_t * vAddedNew; // temporary array
+ Vec_Int_t * vObjCounts; // object counters
+ Vec_Int_t * vCoreCounts; // counts how many times each object appears in the core
+ Vec_Int_t * vProofIds; // counts how many times each object appears in the core
+ int nProofIds; // proof ID counter
+ // refinement
+ Vec_Int_t * pvRefis; // vectors of each object
+ // refinement manager
+ Gia_Man_t * pGia2;
+ Rnm_Man_t * pRnm;
+ // statistics
+ clock_t timeInit;
+ clock_t timeSat;
+ clock_t timeUnsat;
+ clock_t timeCex;
+ clock_t timeOther;
+};
+
+// declarations
+static Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis );
+static int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame );
+static int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame );
+
+// object procedures
+static inline int Gla_ObjId( Gla_Man_t * p, Gla_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; }
+static inline Gla_Obj_t * Gla_ManObj( Gla_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; }
+static inline Gia_Obj_t * Gla_ManGiaObj( Gla_Man_t * p, Gla_Obj_t * pObj ) { return Gia_ManObj( p->pGia, pObj->iGiaObj ); }
+static inline int Gla_ObjSatValue( Gla_Man_t * p, int iGia, int f ) { return Gla_ManCheckVar(p, p->pObj2Obj[iGia], f) ? sat_solver2_var_value( p->pSat, Gla_ManGetVar(p, p->pObj2Obj[iGia], f) ) : 0; }
+
+static inline Rfn_Obj_t * Gla_ObjRef( Gla_Man_t * p, Gia_Obj_t * pObj, int f ) { return (Rfn_Obj_t *)Vec_IntGetEntryP( &(p->pvRefis[Gia_ObjId(p->pGia, pObj)]), f ); }
+static inline void Gla_ObjClearRef( Rfn_Obj_t * p ) { *((int *)p) = 0; }
+
+
+// iterator through abstracted objects
+#define Gla_ManForEachObj( p, pObj ) \
+ for ( pObj = p->pObjs + 1; pObj < p->pObjs + p->nObjs; pObj++ )
+#define Gla_ManForEachObjAbs( p, pObj, i ) \
+ for ( i = 0; i < Vec_IntSize(p->vAbs) && ((pObj = Gla_ManObj(p, Vec_IntEntry(p->vAbs, i))),1); i++)
+#define Gla_ManForEachObjAbsVec( vVec, p, pObj, i ) \
+ for ( i = 0; i < Vec_IntSize(vVec) && ((pObj = Gla_ManObj(p, Vec_IntEntry(vVec, i))),1); i++)
+
+// iterator through fanins of an abstracted object
+#define Gla_ObjForEachFanin( p, pObj, pFanin, i ) \
+ for ( i = 0; (i < (int)pObj->nFanins) && ((pFanin = Gla_ManObj(p, pObj->Fanins[i])),1); i++ )
+
+// some lessons learned from debugging mismatches between GIA and mapped CNF
+// - inputs/output of AND-node may be PPIs (have SAT vars), but the node is not included in the abstraction
+// - some logic node can be a PPI of one LUT and an internal node of another LUT
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Prepares CEX and vMap for refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_GlaPrepareCexAndMap( Gla_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMap )
+{
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vMap;
+ Gla_Obj_t * pObj, * pFanin;
+ Gia_Obj_t * pGiaObj;
+ int f, i, k;
+ // find PIs and PPIs
+ vMap = Vec_IntAlloc( 1000 );
+ Gla_ManForEachObjAbs( p, pObj, i )
+ {
+ assert( pObj->fConst || pObj->fRo || pObj->fAnd );
+ Gla_ObjForEachFanin( p, pObj, pFanin, k )
+ if ( !pFanin->fAbs )
+ Vec_IntPush( vMap, pFanin->iGiaObj );
+ }
+ Vec_IntUniqify( vMap );
+ // derive counter-example
+ pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 );
+ pCex->iFrame = p->pPars->iFrame;
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ Gia_ManForEachObjVec( vMap, p->pGia, pGiaObj, k )
+ if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pGiaObj), f ) )
+ Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k );
+ *pvMap = vMap;
+ *ppCex = pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example using current assignments.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gla_ManDeriveCex( Gla_Man_t * p, Vec_Int_t * vPis )
+{
+ Abc_Cex_t * pCex;
+ Gia_Obj_t * pObj;
+ int i, f;
+ pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
+ pCex->iPo = 0;
+ pCex->iFrame = p->pPars->iFrame;
+ Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
+ {
+ if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ assert( Gia_ObjIsPi(p->pGia, pObj) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) )
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) );
+ }
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects GIA abstraction objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManCollectInternal_rec( Gia_Man_t * p, Gia_Obj_t * pGiaObj, Vec_Int_t * vRoAnds )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pGiaObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pGiaObj);
+ assert( Gia_ObjIsAnd(pGiaObj) );
+ Gla_ManCollectInternal_rec( p, Gia_ObjFanin0(pGiaObj), vRoAnds );
+ Gla_ManCollectInternal_rec( p, Gia_ObjFanin1(pGiaObj), vRoAnds );
+ Vec_IntPush( vRoAnds, Gia_ObjId(p, pGiaObj) );
+}
+void Gla_ManCollect( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vCos, Vec_Int_t * vRoAnds )
+{
+ Gla_Obj_t * pObj, * pFanin;
+ Gia_Obj_t * pGiaObj;
+ int i, k;
+
+ // collect COs
+ Vec_IntPush( vCos, Gia_ObjId(p->pGia, Gia_ManPo(p->pGia, 0)) );
+ // collect fanins of abstracted objects
+ Gla_ManForEachObjAbs( p, pObj, i )
+ {
+ assert( pObj->fConst || pObj->fRo || pObj->fAnd );
+ if ( pObj->fRo )
+ {
+ pGiaObj = Gia_ObjRoToRi( p->pGia, Gia_ManObj(p->pGia, pObj->iGiaObj) );
+ Vec_IntPush( vCos, Gia_ObjId(p->pGia, pGiaObj) );
+ }
+ Gla_ObjForEachFanin( p, pObj, pFanin, k )
+ if ( !pFanin->fAbs )
+ Vec_IntPush( (pFanin->fPi ? vPis : vPPis), pFanin->iGiaObj );
+ }
+ Vec_IntUniqify( vPis );
+ Vec_IntUniqify( vPPis );
+ Vec_IntSort( vCos, 0 );
+ // sorting PIs/PPIs/COs leads to refinements that are more "well-aligned"...
+
+ // mark const/PIs/PPIs
+ Gia_ManIncrementTravId( p->pGia );
+ Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) );
+ Gia_ManForEachObjVec( vPis, p->pGia, pGiaObj, i )
+ Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj );
+ Gia_ManForEachObjVec( vPPis, p->pGia, pGiaObj, i )
+ Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj );
+ // mark and add ROs first
+ Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i )
+ {
+ if ( i == 0 ) continue;
+ pGiaObj = Gia_ObjRiToRo( p->pGia, pGiaObj );
+ Gia_ObjSetTravIdCurrent( p->pGia, pGiaObj );
+ Vec_IntPush( vRoAnds, Gia_ObjId(p->pGia, pGiaObj) );
+ }
+ // collect nodes between PIs/PPIs/ROs and COs
+ Gia_ManForEachObjVec( vCos, p->pGia, pGiaObj, i )
+ Gla_ManCollectInternal_rec( p->pGia, Gia_ObjFanin0(pGiaObj), vRoAnds );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Drive implications of the given node towards primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManRefSetAndPropFanout_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign )
+{
+ int i;//, Id = Gia_ObjId(p->pGia, pObj);
+ Rfn_Obj_t * pRef0, * pRef1, * pRef = Gla_ObjRef( p, pObj, f );
+ Gia_Obj_t * pFanout;
+ int k;
+ if ( (int)pRef->Sign != Sign )
+ return;
+ assert( pRef->fVisit == 0 );
+ pRef->fVisit = 1;
+ if ( pRef->fPPi )
+ {
+ assert( (int)pRef->Prio > 0 );
+ for ( i = p->pPars->iFrame; i >= 0; i-- )
+ if ( !Gla_ObjRef(p, pObj, i)->fVisit )
+ Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign );
+ Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) );
+ return;
+ }
+ if ( (Gia_ObjIsCo(pObj) && f == p->pPars->iFrame) || Gia_ObjIsPo(p->pGia, pObj) )
+ return;
+ if ( Gia_ObjIsRi(p->pGia, pObj) )
+ {
+ pFanout = Gia_ObjRiToRo(p->pGia, pObj);
+ if ( !Gla_ObjRef(p, pFanout, f+1)->fVisit )
+ Gia_ManRefSetAndPropFanout_rec( p, pFanout, f+1, vSelect, Sign );
+ return;
+ }
+ assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
+ Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k )
+ {
+// Rfn_Obj_t * pRefF = Gla_ObjRef(p, pFanout, f);
+ if ( Gla_ObjRef(p, pFanout, f)->fVisit )
+ continue;
+ if ( Gia_ObjIsCo(pFanout) )
+ {
+ Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign );
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pFanout) );
+ pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pFanout), f );
+ pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pFanout), f );
+ if ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRef0->fVisit) ||
+ ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRef1->fVisit) ||
+ ( ((pRef0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRef0->fVisit) &&
+ ((pRef1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRef1->fVisit) ) )
+ Gia_ManRefSetAndPropFanout_rec( p, pFanout, f, vSelect, Sign );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Selects assignments to be refined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManRefSelect_rec( Gla_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect, int Sign )
+{
+ int i;//, Id = Gia_ObjId(p->pGia, pObj);
+ Rfn_Obj_t * pRef = Gla_ObjRef( p, pObj, f );
+// assert( (int)pRef->Sign == Sign );
+ if ( pRef->fVisit )
+ return;
+ if ( p->pPars->fPropFanout )
+ Gia_ManRefSetAndPropFanout_rec( p, pObj, f, vSelect, Sign );
+ else
+ pRef->fVisit = 1;
+ if ( pRef->fPPi )
+ {
+ assert( (int)pRef->Prio > 0 );
+ if ( p->pPars->fPropFanout )
+ {
+ for ( i = p->pPars->iFrame; i >= 0; i-- )
+ if ( !Gla_ObjRef(p, pObj, i)->fVisit )
+ Gia_ManRefSetAndPropFanout_rec( p, pObj, i, vSelect, Sign );
+ }
+ else
+ {
+ Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) );
+ Vec_IntAddToEntry( p->vObjCounts, f, 1 );
+ }
+ return;
+ }
+ if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) )
+ return;
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect, Sign );
+ return;
+ }
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Rfn_Obj_t * pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f );
+ Rfn_Obj_t * pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f );
+ if ( pRef->Value == 1 )
+ {
+ if ( pRef0->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign );
+ if ( pRef1->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign );
+ }
+ else // select one value
+ {
+ if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ {
+ if ( pRef0->Prio <= pRef1->Prio ) // choice
+ {
+ if ( pRef0->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign );
+ }
+ else
+ {
+ if ( pRef1->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign );
+ }
+ }
+ else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 )
+ {
+ if ( pRef0->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin0(pObj), f, vSelect, Sign );
+ }
+ else if ( (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ {
+ if ( pRef1->Prio > 0 )
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin1(pObj), f, vSelect, Sign );
+ }
+ else assert( 0 );
+ }
+ }
+ else assert( 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManVerifyUsingTerSim( Gla_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vPPis, Vec_Int_t * vRoAnds, Vec_Int_t * vCos, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj;
+ int i, f;
+// Gia_ManForEachObj( p->pGia, pObj, i )
+// assert( Gia_ObjTerSimGetC(pObj) );
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ {
+ Gia_ObjTerSimSet0( Gia_ManConst0(p->pGia) );
+ Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
+ {
+ if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i )
+ Gia_ObjTerSimSetX( pObj );
+ Gia_ManForEachObjVec( vRes, p->pGia, pObj, i )
+ if ( Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f ) )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+
+ Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ObjTerSimAnd( pObj );
+ else if ( f == 0 )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimRo( p->pGia, pObj );
+ }
+ Gia_ManForEachObjVec( vCos, p->pGia, pObj, i )
+ Gia_ObjTerSimCo( pObj );
+ }
+ pObj = Gia_ManPo( p->pGia, 0 );
+ if ( !Gia_ObjTerSimGet1(pObj) )
+ Abc_Print( 1, "\nRefinement verification has failed!!!\n" );
+ // clear
+ Gia_ObjTerSimSetC( Gia_ManConst0(p->pGia) );
+ Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
+ Gia_ObjTerSimSetC( pObj );
+ Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i )
+ Gia_ObjTerSimSetC( pObj );
+ Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i )
+ Gia_ObjTerSimSetC( pObj );
+ Gia_ManForEachObjVec( vCos, p->pGia, pObj, i )
+ Gia_ObjTerSimSetC( pObj );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gla_ManRefinement( Gla_Man_t * p )
+{
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vMap, * vVec;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_GlaPrepareCexAndMap( p, &pCex, &vMap );
+ vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, 0, 1 );
+ Abc_CexFree( pCex );
+ if ( Vec_IntSize(vVec) == 0 )
+ {
+ Vec_IntFree( vVec );
+ Abc_CexFreeP( &p->pGia->pCexSeq );
+ p->pGia->pCexSeq = Gla_ManDeriveCex( p, vMap );
+ Vec_IntFree( vMap );
+ return NULL;
+ }
+ Vec_IntFree( vMap );
+ // remap them into GLA objects
+ Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
+ Vec_IntWriteEntry( vVec, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] );
+ p->nObjAdded += Vec_IntSize(vVec);
+ return vVec;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gla_ManRefinement2( Gla_Man_t * p )
+{
+ int fVerify = 1;
+ static int Sign = 0;
+ Vec_Int_t * vPis, * vPPis, * vCos, * vRoAnds, * vSelect = NULL;
+ Rfn_Obj_t * pRef, * pRef0, * pRef1;
+ Gia_Obj_t * pObj;
+ int i, f;
+ Sign++;
+
+ // compute PIs and pseudo-PIs
+ vCos = Vec_IntAlloc( 1000 );
+ vPis = Vec_IntAlloc( 1000 );
+ vPPis = Vec_IntAlloc( 1000 );
+ vRoAnds = Vec_IntAlloc( 1000 );
+ Gla_ManCollect( p, vPis, vPPis, vCos, vRoAnds );
+
+/*
+ // check how many pseudo PIs have variables
+ Gla_ManForEachObjAbsVec( vPis, p, pGla, i )
+ {
+ Abc_Print( 1, " %5d : ", Gla_ObjId(p, pGla) );
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) );
+ Abc_Print( 1, "\n" );
+ }
+
+ // check how many pseudo PIs have variables
+ Gla_ManForEachObjAbsVec( vPPis, p, pGla, i )
+ {
+ Abc_Print( 1, "%5d : ", Gla_ObjId(p, pGla) );
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ Abc_Print( 1, "%d", Gla_ManCheckVar(p, Gla_ObjId(p, pGla), f) );
+ Abc_Print( 1, "\n" );
+ }
+*/
+ // propagate values
+ for ( f = 0; f <= p->pPars->iFrame; f++ )
+ {
+ // constant
+ pRef = Gla_ObjRef( p, Gia_ManConst0(p->pGia), f ); Gla_ObjClearRef( pRef );
+ pRef->Value = 0;
+ pRef->Prio = 0;
+ pRef->Sign = Sign;
+ // primary input
+ Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
+ {
+// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) );
+ pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef );
+ pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f );
+ pRef->Prio = 0;
+ pRef->Sign = Sign;
+ assert( pRef->fVisit == 0 );
+ }
+ // primary input
+ Gia_ManForEachObjVec( vPPis, p->pGia, pObj, i )
+ {
+// assert( f == p->pPars->iFrame || Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) );
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
+ pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef );
+ pRef->Value = Gla_ObjSatValue( p, Gia_ObjId(p->pGia, pObj), f );
+ pRef->Prio = i+1;
+ pRef->fPPi = 1;
+ pRef->Sign = Sign;
+ assert( pRef->fVisit == 0 );
+ }
+ // internal nodes
+ Gia_ManForEachObjVec( vRoAnds, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
+ pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f == 0 )
+ {
+ pRef->Value = 0;
+ pRef->Prio = 0;
+ pRef->Sign = Sign;
+ }
+ else
+ {
+ pRef0 = Gla_ObjRef( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 );
+ pRef->Value = pRef0->Value;
+ pRef->Prio = pRef0->Prio;
+ pRef->Sign = Sign;
+ }
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f );
+ pRef1 = Gla_ObjRef( p, Gia_ObjFanin1(pObj), f );
+ pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj)) & (pRef1->Value ^ Gia_ObjFaninC1(pObj));
+
+ if ( p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] != ~0 &&
+ Gla_ManCheckVar(p, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)], f) &&
+ (int)pRef->Value != Gla_ObjSatValue(p, Gia_ObjId(p->pGia, pObj), f) )
+ {
+ Abc_Print( 1, "Object has value mismatch " );
+ Gia_ObjPrint( p->pGia, pObj );
+ }
+
+ if ( pRef->Value == 1 )
+ pRef->Prio = Abc_MaxInt( pRef0->Prio, pRef1->Prio );
+ else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRef1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ pRef->Prio = Abc_MinInt( pRef0->Prio, pRef1->Prio ); // choice
+ else if ( (pRef0->Value ^ Gia_ObjFaninC0(pObj)) == 0 )
+ pRef->Prio = pRef0->Prio;
+ else
+ pRef->Prio = pRef1->Prio;
+ assert( pRef->fVisit == 0 );
+ pRef->Sign = Sign;
+ }
+ // output nodes
+ Gia_ManForEachObjVec( vCos, p->pGia, pObj, i )
+ {
+ pRef = Gla_ObjRef( p, pObj, f ); Gla_ObjClearRef( pRef );
+ pRef0 = Gla_ObjRef( p, Gia_ObjFanin0(pObj), f );
+ pRef->Value = (pRef0->Value ^ Gia_ObjFaninC0(pObj));
+ pRef->Prio = pRef0->Prio;
+ assert( pRef->fVisit == 0 );
+ pRef->Sign = Sign;
+ }
+ }
+
+ // make sure the output value is 1
+ pObj = Gia_ManPo( p->pGia, 0 );
+ pRef = Gla_ObjRef( p, pObj, p->pPars->iFrame );
+ if ( pRef->Value != 1 )
+ Abc_Print( 1, "\nCounter-example verification has failed!!!\n" );
+
+ // check the CEX
+ if ( pRef->Prio == 0 )
+ {
+ p->pGia->pCexSeq = Gla_ManDeriveCex( p, vPis );
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPPis );
+ Vec_IntFree( vRoAnds );
+ Vec_IntFree( vCos );
+ return NULL;
+ }
+
+ // select objects
+ vSelect = Vec_IntAlloc( 100 );
+ Vec_IntFill( p->vObjCounts, p->pPars->iFrame+1, 0 );
+ Gla_ManRefSelect_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), p->pPars->iFrame, vSelect, Sign );
+ Vec_IntUniqify( vSelect );
+
+/*
+ for ( f = 0; f < p->pPars->iFrame; f++ )
+ printf( "%2d", Vec_IntEntry(p->vObjCounts, f) );
+ printf( "\n" );
+*/
+ if ( fVerify )
+ Gla_ManVerifyUsingTerSim( p, vPis, vPPis, vRoAnds, vCos, vSelect );
+
+ // remap them into GLA objects
+ Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i )
+ Vec_IntWriteEntry( vSelect, i, p->pObj2Obj[Gia_ObjId(p->pGia, pObj)] );
+
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPPis );
+ Vec_IntFree( vRoAnds );
+ Vec_IntFree( vCos );
+
+ p->nObjAdded += Vec_IntSize(vSelect);
+ return vSelect;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses for the given obj in the given frame.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManCollectFanins( Gla_Man_t * p, Gla_Obj_t * pGla, int iObj, Vec_Int_t * vFanins )
+{
+ int i, nClauses, iFirstClause, * pLit;
+ nClauses = p->pCnf->pObj2Count[pGla->iGiaObj];
+ iFirstClause = p->pCnf->pObj2Clause[pGla->iGiaObj];
+ Vec_IntClear( vFanins );
+ for ( i = iFirstClause; i < iFirstClause + nClauses; i++ )
+ for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ )
+ if ( lit_var(*pLit) != iObj )
+ Vec_IntPushUnique( vFanins, lit_var(*pLit) );
+ assert( Vec_IntSize( vFanins ) <= 4 );
+ Vec_IntSort( vFanins, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG while decoupling nodes duplicated in the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupMapped_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Man_t * pNew )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupMapped_rec( p, Gia_ObjFanin0(pObj), pNew );
+ Gia_ManDupMapped_rec( p, Gia_ObjFanin1(pObj), pNew );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Vec_IntPush( pNew->vLutConfigs, Gia_ObjId(p, pObj) );
+}
+Gia_Man_t * Gia_ManDupMapped( Gia_Man_t * p, Vec_Int_t * vMapping )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, * pMapping, * pObj2Obj;
+ // start new manager
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ // start mapping
+ Gia_ManFillValue( p );
+ pObj2Obj = ABC_FALLOC( int, Gia_ManObjNum(p) );
+ pObj2Obj[0] = 0;
+ // create reverse mapping and attach it to the node
+ pNew->vLutConfigs = Vec_IntAlloc( Gia_ManObjNum(p) * 4 / 3 );
+ Vec_IntPush( pNew->vLutConfigs, 0 );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ int Offset = Vec_IntEntry(vMapping, Gia_ObjId(p, pObj));
+ if ( Offset == 0 )
+ continue;
+ pMapping = Vec_IntEntryP( vMapping, Offset );
+ Gia_ManIncrementTravId( p );
+ for ( k = 1; k <= 4; k++ )
+ {
+ if ( pMapping[k] == -1 )
+ continue;
+ pFanin = Gia_ManObj(p, pMapping[k]);
+ Gia_ObjSetTravIdCurrent( p, pFanin );
+ pFanin->Value = pObj2Obj[pMapping[k]];
+ assert( ~pFanin->Value );
+ }
+ assert( !Gia_ObjIsTravIdCurrent(p, pObj) );
+ assert( !~pObj->Value );
+ Gia_ManDupMapped_rec( p, pObj, pNew );
+ pObj2Obj[i] = pObj->Value;
+ assert( ~pObj->Value );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ {
+ pObj2Obj[i] = Gia_ManAppendCi( pNew );
+ Vec_IntPush( pNew->vLutConfigs, i );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->Value = pObj2Obj[Gia_ObjFaninId0p(p, pObj)];
+ assert( ~Gia_ObjFanin0(pObj)->Value );
+ pObj2Obj[i] = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntPush( pNew->vLutConfigs, i );
+ }
+ }
+ assert( Vec_IntSize(pNew->vLutConfigs) == Gia_ManObjNum(pNew) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ // map original AIG into the new AIG
+ Gia_ManForEachObj( p, pObj, i )
+ pObj->Value = pObj2Obj[i];
+ ABC_FREE( pObj2Obj );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gla_Man_t * Gla_ManStart( Gia_Man_t * pGia0, Abs_Par_t * pPars )
+{
+ Gla_Man_t * p;
+ Aig_Man_t * pAig;
+ Gia_Obj_t * pObj;
+ Gla_Obj_t * pGla;
+ Vec_Int_t * vMappingNew;
+ int i, k, Offset, * pMapping, * pLits, * pObj2Count, * pObj2Clause;
+
+ // start
+ p = ABC_CALLOC( Gla_Man_t, 1 );
+ p->pGia0 = pGia0;
+ p->pPars = pPars;
+ p->vAbs = Vec_IntAlloc( 100 );
+ p->vTemp = Vec_IntAlloc( 100 );
+ p->vAddedNew = Vec_IntAlloc( 100 );
+ p->vObjCounts = Vec_IntAlloc( 100 );
+
+ // internal data
+ pAig = Gia_ManToAigSimple( pGia0 );
+ p->pCnf = Cnf_DeriveOther( pAig, 1 );
+ Aig_ManStop( pAig );
+ // create working GIA
+ p->pGia = Gia_ManDupMapped( pGia0, p->pCnf->vMapping );
+ if ( pPars->fPropFanout )
+ Gia_ManStaticFanoutStart( p->pGia );
+
+ // derive new gate map
+ assert( pGia0->vGateClasses != 0 );
+ p->pGia->vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) );
+ p->vCoreCounts = Vec_IntStart( Gia_ManObjNum(p->pGia) );
+ p->vProofIds = Vec_IntAlloc(0);
+ // update p->pCnf->vMapping, p->pCnf->pObj2Count, p->pCnf->pObj2Clause
+ // (here are not updating p->pCnf->pVarNums because it is not needed)
+ vMappingNew = Vec_IntStart( Gia_ManObjNum(p->pGia) );
+ pObj2Count = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) );
+ pObj2Clause = ABC_FALLOC( int, Gia_ManObjNum(p->pGia) );
+ Gia_ManForEachObj( pGia0, pObj, i )
+ {
+ // skip internal nodes not used in the mapping
+ if ( !~pObj->Value )
+ continue;
+ // replace positive literal by variable
+ assert( !Abc_LitIsCompl(pObj->Value) );
+ pObj->Value = Abc_Lit2Var(pObj->Value);
+ assert( (int)pObj->Value < Gia_ManObjNum(p->pGia) );
+ // update arrays
+ pObj2Count[pObj->Value] = p->pCnf->pObj2Count[i];
+ pObj2Clause[pObj->Value] = p->pCnf->pObj2Clause[i];
+ if ( Vec_IntEntry(pGia0->vGateClasses, i) )
+ Vec_IntWriteEntry( p->pGia->vGateClasses, pObj->Value, 1 );
+ // update mappings
+ Offset = Vec_IntEntry(p->pCnf->vMapping, i);
+ Vec_IntWriteEntry( vMappingNew, pObj->Value, Vec_IntSize(vMappingNew) );
+ pMapping = Vec_IntEntryP(p->pCnf->vMapping, Offset);
+ Vec_IntPush( vMappingNew, pMapping[0] );
+ for ( k = 1; k <= 4; k++ )
+ {
+ if ( pMapping[k] == -1 )
+ Vec_IntPush( vMappingNew, -1 );
+ else
+ {
+ assert( ~Gia_ManObj(pGia0, pMapping[k])->Value );
+ Vec_IntPush( vMappingNew, Gia_ManObj(pGia0, pMapping[k])->Value );
+ }
+ }
+ }
+ // update mapping after the offset (currently not being done because it is not used)
+ Vec_IntFree( p->pCnf->vMapping ); p->pCnf->vMapping = vMappingNew;
+ ABC_FREE( p->pCnf->pObj2Count ); p->pCnf->pObj2Count = pObj2Count;
+ ABC_FREE( p->pCnf->pObj2Clause ); p->pCnf->pObj2Clause = pObj2Clause;
+
+
+ // count the number of variables
+ p->nObjs = 1;
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ if ( p->pCnf->pObj2Count[i] >= 0 )
+ pObj->Value = p->nObjs++;
+ else
+ pObj->Value = ~0;
+
+ // re-express CNF using new variable IDs
+ pLits = p->pCnf->pClauses[0];
+ for ( i = 0; i < p->pCnf->nLiterals; i++ )
+ {
+ // find the original AIG object
+ pObj = Gia_ManObj( pGia0, lit_var(pLits[i]) );
+ assert( ~pObj->Value );
+ // find the working AIG object
+ pObj = Gia_ManObj( p->pGia, pObj->Value );
+ assert( ~pObj->Value );
+ // express literal in terms of LUT variables
+ pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) );
+ }
+
+ // create objects
+ p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs );
+ p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) );
+// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) );
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ {
+ p->pObj2Obj[i] = pObj->Value;
+ if ( !~pObj->Value )
+ continue;
+ pGla = Gla_ManObj( p, pObj->Value );
+ pGla->iGiaObj = i;
+ pGla->fCompl0 = Gia_ObjFaninC0(pObj);
+ pGla->fConst = Gia_ObjIsConst0(pObj);
+ pGla->fPi = Gia_ObjIsPi(p->pGia, pObj);
+ pGla->fPo = Gia_ObjIsPo(p->pGia, pObj);
+ pGla->fRi = Gia_ObjIsRi(p->pGia, pObj);
+ pGla->fRo = Gia_ObjIsRo(p->pGia, pObj);
+ pGla->fAnd = Gia_ObjIsAnd(pObj);
+ if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ pGla->nFanins = 1;
+ pGla->Fanins[0] = Gia_ObjFanin0(pObj)->Value;
+ continue;
+ }
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+// Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp );
+// pGla->nFanins = Vec_IntSize( p->vTemp );
+// memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) );
+ Offset = Vec_IntEntry( p->pCnf->vMapping, i );
+ pMapping = Vec_IntEntryP( p->pCnf->vMapping, Offset );
+ pGla->nFanins = 0;
+ for ( k = 1; k <= 4; k++ )
+ if ( pMapping[k] != -1 )
+ pGla->Fanins[ pGla->nFanins++ ] = Gia_ManObj(p->pGia, pMapping[k])->Value;
+ continue;
+ }
+ assert( Gia_ObjIsRo(p->pGia, pObj) );
+ pGla->nFanins = 1;
+ pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value;
+ pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) );
+ }
+ p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value );
+ // abstraction
+ assert( p->pGia->vGateClasses != NULL );
+ Gla_ManForEachObj( p, pGla )
+ {
+ if ( Vec_IntEntry( p->pGia->vGateClasses, pGla->iGiaObj ) == 0 )
+ continue;
+ pGla->fAbs = 1;
+ Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) );
+ }
+ // other
+ p->pSat = sat_solver2_new();
+ if ( pPars->fUseFullProof )
+ p->pSat->pPrf1 = Vec_SetAlloc( 20 );
+// p->pSat->fVerbose = p->pPars->fVerbose;
+// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax );
+ p->pSat->nLearntStart = p->pPars->nLearnedStart;
+ p->pSat->nLearntDelta = p->pPars->nLearnedDelta;
+ p->pSat->nLearntRatio = p->pPars->nLearnedPerce;
+ p->pSat->nLearntMax = p->pSat->nLearntStart;
+ p->nSatVars = 1;
+ // start the refinement manager
+// p->pGia2 = Gia_ManDup( p->pGia );
+ p->pRnm = Rnm_ManStart( p->pGia );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gla_Man_t * Gla_ManStart2( Gia_Man_t * pGia, Abs_Par_t * pPars )
+{
+ Gla_Man_t * p;
+ Aig_Man_t * pAig;
+ Gia_Obj_t * pObj;
+ Gla_Obj_t * pGla;
+ int i, * pLits;
+ // start
+ p = ABC_CALLOC( Gla_Man_t, 1 );
+ p->pGia = pGia;
+ p->pPars = pPars;
+ p->vAbs = Vec_IntAlloc( 100 );
+ p->vTemp = Vec_IntAlloc( 100 );
+ p->vAddedNew = Vec_IntAlloc( 100 );
+ // internal data
+ pAig = Gia_ManToAigSimple( p->pGia );
+ p->pCnf = Cnf_DeriveOther( pAig, 1 );
+ Aig_ManStop( pAig );
+ // count the number of variables
+ p->nObjs = 1;
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ if ( p->pCnf->pObj2Count[i] >= 0 )
+ pObj->Value = p->nObjs++;
+ else
+ pObj->Value = ~0;
+ // re-express CNF using new variable IDs
+ pLits = p->pCnf->pClauses[0];
+ for ( i = 0; i < p->pCnf->nLiterals; i++ )
+ {
+ pObj = Gia_ManObj( p->pGia, lit_var(pLits[i]) );
+ assert( ~pObj->Value );
+ pLits[i] = toLitCond( pObj->Value, lit_sign(pLits[i]) );
+ }
+ // create objects
+ p->pObjs = ABC_CALLOC( Gla_Obj_t, p->nObjs );
+ p->pObj2Obj = ABC_FALLOC( unsigned, Gia_ManObjNum(p->pGia) );
+// p->pvRefis = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(p->pGia) );
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ {
+ p->pObj2Obj[i] = pObj->Value;
+ if ( !~pObj->Value )
+ continue;
+ pGla = Gla_ManObj( p, pObj->Value );
+ pGla->iGiaObj = i;
+ pGla->fCompl0 = Gia_ObjFaninC0(pObj);
+ pGla->fConst = Gia_ObjIsConst0(pObj);
+ pGla->fPi = Gia_ObjIsPi(p->pGia, pObj);
+ pGla->fPo = Gia_ObjIsPo(p->pGia, pObj);
+ pGla->fRi = Gia_ObjIsRi(p->pGia, pObj);
+ pGla->fRo = Gia_ObjIsRo(p->pGia, pObj);
+ pGla->fAnd = Gia_ObjIsAnd(pObj);
+ if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ if ( Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) )
+ {
+ Gla_ManCollectFanins( p, pGla, pObj->Value, p->vTemp );
+ pGla->nFanins = Vec_IntSize( p->vTemp );
+ memcpy( pGla->Fanins, Vec_IntArray(p->vTemp), sizeof(int) * Vec_IntSize(p->vTemp) );
+ continue;
+ }
+ assert( Gia_ObjIsRo(p->pGia, pObj) );
+ pGla->nFanins = 1;
+ pGla->Fanins[0] = Gia_ObjFanin0( Gia_ObjRoToRi(p->pGia, pObj) )->Value;
+ pGla->fCompl0 = Gia_ObjFaninC0( Gia_ObjRoToRi(p->pGia, pObj) );
+ }
+ p->pObjRoot = Gla_ManObj( p, Gia_ManPo(p->pGia, 0)->Value );
+ // abstraction
+ assert( pGia->vGateClasses != NULL );
+ Gla_ManForEachObj( p, pGla )
+ {
+ if ( Vec_IntEntry( pGia->vGateClasses, pGla->iGiaObj ) == 0 )
+ continue;
+ pGla->fAbs = 1;
+ Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) );
+ }
+ // other
+ p->pSat = sat_solver2_new();
+ p->nSatVars = 1;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManStop( Gla_Man_t * p )
+{
+ Gla_Obj_t * pGla;
+ int i;
+
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n",
+ sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat),
+ sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded );
+
+ // stop the refinement manager
+// Gia_ManStopP( &p->pGia2 );
+ Rnm_ManStop( p->pRnm, 0 );
+
+ if ( p->pvRefis )
+ for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ )
+ ABC_FREE( p->pvRefis[i].pArray );
+ Gla_ManForEachObj( p, pGla )
+ ABC_FREE( pGla->vFrames.pArray );
+ Cnf_DataFree( p->pCnf );
+ if ( p->pGia0 != NULL )
+ Gia_ManStop( p->pGia );
+// Gia_ManStaticFanoutStart( p->pGia0 );
+ sat_solver2_delete( p->pSat );
+ Vec_IntFreeP( &p->vObjCounts );
+ Vec_IntFreeP( &p->vAddedNew );
+ Vec_IntFreeP( &p->vCoreCounts );
+ Vec_IntFreeP( &p->vProofIds );
+ Vec_IntFreeP( &p->vTemp );
+ Vec_IntFreeP( &p->vAbs );
+ ABC_FREE( p->pvRefis );
+ ABC_FREE( p->pObj2Obj );
+ ABC_FREE( p->pObjs );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_GlaAbsCount( Gla_Man_t * p, int fRo, int fAnd )
+{
+ Gla_Obj_t * pObj;
+ int i, Counter = 0;
+ if ( fRo )
+ Gla_ManForEachObjAbs( p, pObj, i )
+ Counter += (pObj->fRo && pObj->fAbs);
+ else if ( fAnd )
+ Gla_ManForEachObjAbs( p, pObj, i )
+ Counter += (pObj->fAnd && pObj->fAbs);
+ else
+ Gla_ManForEachObjAbs( p, pObj, i )
+ Counter += (pObj->fAbs);
+ return Counter;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives new abstraction map.]
+
+ Description [Returns 1 if node contains abstracted leaf on the path.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gla_ManTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla, int nUsageCount )
+{
+ int Value0, Value1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return 1;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Gla_ManTranslate_rec( p, Gia_ObjFanin0(pObj), vGla, nUsageCount );
+ Value1 = Gla_ManTranslate_rec( p, Gia_ObjFanin1(pObj), vGla, nUsageCount );
+ if ( Value0 || Value1 )
+ Vec_IntAddToEntry( vGla, Gia_ObjId(p, pObj), nUsageCount );
+ return Value0 || Value1;
+}
+Vec_Int_t * Gla_ManTranslate( Gla_Man_t * p )
+{
+ Vec_Int_t * vGla, * vGla2;
+ Gla_Obj_t * pObj, * pFanin;
+ Gia_Obj_t * pGiaObj;
+ int i, k, nUsageCount;
+ vGla = Vec_IntStart( Gia_ManObjNum(p->pGia) );
+ Gla_ManForEachObjAbs( p, pObj, i )
+ {
+ nUsageCount = Vec_IntEntry(p->vCoreCounts, pObj->iGiaObj);
+ assert( nUsageCount >= 0 );
+ if ( nUsageCount == 0 )
+ nUsageCount++;
+ pGiaObj = Gla_ManGiaObj( p, pObj );
+ if ( Gia_ObjIsConst0(pGiaObj) || Gia_ObjIsRo(p->pGia, pGiaObj) )
+ {
+ Vec_IntWriteEntry( vGla, pObj->iGiaObj, nUsageCount );
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pGiaObj) );
+ Gia_ManIncrementTravId( p->pGia );
+ Gla_ObjForEachFanin( p, pObj, pFanin, k )
+ Gia_ObjSetTravIdCurrent( p->pGia, Gla_ManGiaObj(p, pFanin) );
+ Gla_ManTranslate_rec( p->pGia, pGiaObj, vGla, nUsageCount );
+ }
+ Vec_IntWriteEntry( vGla, 0, p->pPars->iFrame+1 );
+ if ( p->pGia->vLutConfigs ) // use mapping from new to old
+ {
+ vGla2 = Vec_IntStart( Gia_ManObjNum(p->pGia0) );
+ for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ )
+ if ( Vec_IntEntry(vGla, i) )
+ Vec_IntWriteEntry( vGla2, Vec_IntEntry(p->pGia->vLutConfigs, i), Vec_IntEntry(vGla, i) );
+ Vec_IntFree( vGla );
+ return vGla2;
+ }
+ return vGla;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect pseudo-PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gla_ManCollectPPis( Gla_Man_t * p, Vec_Int_t * vPis )
+{
+ Vec_Int_t * vPPis;
+ Gla_Obj_t * pObj, * pFanin;
+ int i, k;
+ vPPis = Vec_IntAlloc( 1000 );
+ if ( vPis )
+ Vec_IntClear( vPis );
+ Gla_ManForEachObjAbs( p, pObj, i )
+ {
+ assert( pObj->fConst || pObj->fRo || pObj->fAnd );
+ Gla_ObjForEachFanin( p, pObj, pFanin, k )
+ if ( !pFanin->fPi && !pFanin->fAbs )
+ Vec_IntPush( vPPis, pObj->Fanins[k] );
+ else if ( vPis && pFanin->fPi && !pFanin->fAbs )
+ Vec_IntPush( vPis, pObj->Fanins[k] );
+ }
+ Vec_IntUniqify( vPPis );
+ Vec_IntReverseOrder( vPPis );
+ if ( vPis )
+ Vec_IntUniqify( vPis );
+ return vPPis;
+}
+int Gla_ManCountPPis( Gla_Man_t * p )
+{
+ Vec_Int_t * vPPis = Gla_ManCollectPPis( p, NULL );
+ int RetValue = Vec_IntSize( vPPis );
+ Vec_IntFree( vPPis );
+ return RetValue;
+}
+void Gla_ManExplorePPis( Gla_Man_t * p, Vec_Int_t * vPPis )
+{
+ static int Round = 0;
+ Gla_Obj_t * pObj, * pFanin;
+ int i, j, k, Count;
+ if ( (Round++ % 5) == 0 )
+ return;
+ j = 0;
+ Gla_ManForEachObjAbsVec( vPPis, p, pObj, i )
+ {
+ assert( pObj->fAbs == 0 );
+ Count = 0;
+ Gla_ObjForEachFanin( p, pObj, pFanin, k )
+ Count += pFanin->fAbs;
+ if ( Count == 0 || ((Round & 1) && Count == 1) )
+ continue;
+ Vec_IntWriteEntry( vPPis, j++, Gla_ObjId(p, pObj) );
+ }
+// printf( "\n%d -> %d\n", Vec_IntSize(vPPis), j );
+ Vec_IntShrink( vPPis, j );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds CNF for the given timeframe.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gla_ManCheckVar( Gla_Man_t * p, int iObj, int iFrame )
+{
+ Gla_Obj_t * pGla = Gla_ManObj( p, iObj );
+ int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame );
+ assert( !pGla->fPo && !pGla->fRi );
+ return (iVar > 0);
+}
+int Gla_ManGetVar( Gla_Man_t * p, int iObj, int iFrame )
+{
+ Gla_Obj_t * pGla = Gla_ManObj( p, iObj );
+ int iVar = Vec_IntGetEntry( &pGla->vFrames, iFrame );
+ assert( !pGla->fPo && !pGla->fRi );
+ if ( iVar == 0 )
+ {
+ Vec_IntSetEntry( &pGla->vFrames, iFrame, (iVar = p->nSatVars++) );
+ // remember the change
+ Vec_IntPush( p->vAddedNew, iObj );
+ Vec_IntPush( p->vAddedNew, iFrame );
+ }
+ return iVar;
+}
+void Gla_ManAddClauses( Gla_Man_t * p, int iObj, int iFrame, Vec_Int_t * vLits )
+{
+ Gla_Obj_t * pGlaObj = Gla_ManObj( p, iObj );
+ int iVar, iVar1, iVar2;
+ if ( pGlaObj->fConst )
+ {
+ iVar = Gla_ManGetVar( p, iObj, iFrame );
+ sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj );
+ }
+ else if ( pGlaObj->fRo )
+ {
+ assert( pGlaObj->nFanins == 1 );
+ if ( iFrame == 0 )
+ {
+ iVar = Gla_ManGetVar( p, iObj, iFrame );
+ sat_solver2_add_const( p->pSat, iVar, 1, 0, iObj );
+ }
+ else
+ {
+ iVar1 = Gla_ManGetVar( p, iObj, iFrame );
+ iVar2 = Gla_ManGetVar( p, pGlaObj->Fanins[0], iFrame-1 );
+ sat_solver2_add_buffer( p->pSat, iVar1, iVar2, pGlaObj->fCompl0, 0, iObj );
+ }
+ }
+ else if ( pGlaObj->fAnd )
+ {
+ int i, RetValue, nClauses, iFirstClause, * pLit;
+ nClauses = p->pCnf->pObj2Count[pGlaObj->iGiaObj];
+ iFirstClause = p->pCnf->pObj2Clause[pGlaObj->iGiaObj];
+ for ( i = iFirstClause; i < iFirstClause + nClauses; i++ )
+ {
+ Vec_IntClear( vLits );
+ for ( pLit = p->pCnf->pClauses[i]; pLit < p->pCnf->pClauses[i+1]; pLit++ )
+ {
+ iVar = Gla_ManGetVar( p, lit_var(*pLit), iFrame );
+ Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) );
+ }
+ RetValue = sat_solver2_addclause( p->pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits), iObj );
+ }
+ }
+ else assert( 0 );
+}
+void Gia_GlaAddToCounters( Gla_Man_t * p, Vec_Int_t * vCore )
+{
+ Gla_Obj_t * pGla;
+ int i;
+ Gla_ManForEachObjAbsVec( vCore, p, pGla, i )
+ Vec_IntAddToEntry( p->vCoreCounts, pGla->iGiaObj, 1 );
+}
+void Gia_GlaAddToAbs( Gla_Man_t * p, Vec_Int_t * vAbsAdd, int fCheck )
+{
+ Gla_Obj_t * pGla;
+ int i, k = 0;
+ Gla_ManForEachObjAbsVec( vAbsAdd, p, pGla, i )
+ {
+ if ( fCheck )
+ {
+ assert( pGla->fAbs == 0 );
+ if ( p->pSat->pPrf2 )
+ Vec_IntWriteEntry( p->vProofIds, Gla_ObjId(p, pGla), p->nProofIds++ );
+ }
+ if ( pGla->fAbs )
+ continue;
+ pGla->fAbs = 1;
+ Vec_IntPush( p->vAbs, Gla_ObjId(p, pGla) );
+ // filter clauses to remove those contained in the abstraction
+ Vec_IntWriteEntry( vAbsAdd, k++, Gla_ObjId(p, pGla) );
+ }
+ Vec_IntShrink( vAbsAdd, k );
+}
+void Gia_GlaAddTimeFrame( Gla_Man_t * p, int f )
+{
+ Gla_Obj_t * pObj;
+ int i;
+ Gla_ManForEachObjAbs( p, pObj, i )
+ Gla_ManAddClauses( p, Gla_ObjId(p, pObj), f, p->vTemp );
+ sat_solver2_simplify( p->pSat );
+}
+void Gia_GlaAddOneSlice( Gla_Man_t * p, int fCur, Vec_Int_t * vCore )
+{
+ int f, i, iGlaObj;
+ for ( f = fCur; f >= 0; f-- )
+ Vec_IntForEachEntry( vCore, iGlaObj, i )
+ Gla_ManAddClauses( p, iGlaObj, f, p->vTemp );
+ sat_solver2_simplify( p->pSat );
+}
+void Gla_ManRollBack( Gla_Man_t * p )
+{
+ int i, iObj, iFrame;
+ Vec_IntForEachEntryDouble( p->vAddedNew, iObj, iFrame, i )
+ {
+ assert( Vec_IntEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame ) > 0 );
+ Vec_IntWriteEntry( &Gla_ManObj(p, iObj)->vFrames, iFrame, 0 );
+ }
+ Vec_IntForEachEntryStart( p->vAbs, iObj, i, p->nAbsOld )
+ {
+ assert( Gla_ManObj( p, iObj )->fAbs == 1 );
+ Gla_ManObj( p, iObj )->fAbs = 0;
+ }
+ Vec_IntShrink( p->vAbs, p->nAbsOld );
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Finds the set of clauses involved in the UNSAT core.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gla_ManGetOutLit( Gla_Man_t * p, int f )
+{
+ Gla_Obj_t * pFanin = Gla_ManObj( p, p->pObjRoot->Fanins[0] );
+ int iSat = Vec_IntEntry( &pFanin->vFrames, f );
+ assert( iSat > 0 );
+ if ( f == 0 && pFanin->fRo && !p->pObjRoot->fCompl0 )
+ return -1;
+ return Abc_Var2Lit( iSat, p->pObjRoot->fCompl0 );
+}
+Vec_Int_t * Gla_ManUnsatCore( Gla_Man_t * p, int f, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls )
+{
+ Vec_Int_t * vCore = NULL;
+ int nConfPrev = pSat->stats.conflicts;
+ int RetValue, iLit = Gla_ManGetOutLit( p, f );
+ clock_t clk = clock();
+ if ( piRetValue )
+ *piRetValue = 1;
+ // consider special case when PO points to the flop
+ // this leads to immediate conflict in the first timeframe
+ if ( iLit == -1 )
+ {
+ vCore = Vec_IntAlloc( 1 );
+ Vec_IntPush( vCore, p->pObjRoot->Fanins[0] );
+ return vCore;
+ }
+ // solve the problem
+ RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( pnConfls )
+ *pnConfls = (int)pSat->stats.conflicts - nConfPrev;
+ if ( RetValue == l_Undef )
+ {
+ if ( piRetValue )
+ *piRetValue = -1;
+ return NULL;
+ }
+ if ( RetValue == l_True )
+ {
+ if ( piRetValue )
+ *piRetValue = 0;
+ return NULL;
+ }
+ if ( fVerbose )
+ {
+// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev );
+// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ assert( RetValue == l_False );
+ // derive the UNSAT core
+ clk = clock();
+ vCore = (Vec_Int_t *)Sat_ProofCore( pSat );
+ if ( vCore )
+ Vec_IntSort( vCore, 1 );
+ if ( fVerbose )
+ {
+// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ return vCore;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gla_ManAbsPrintFrame( Gla_Man_t * p, int nCoreSize, int nFrames, int nConfls, int nCexes, clock_t Time )
+{
+ if ( Abc_FrameIsBatchMode() && nCoreSize <= 0 )
+ return;
+ Abc_Print( 1, "%4d :", nFrames-1 );
+ Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Gia_GlaAbsCount(p, 0, 0) / (p->nObjs - Gia_ManPoNum(p->pGia) + Gia_ManCoNum(p->pGia) + 1)) );
+ Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 0) );
+ Abc_Print( 1, "%5d", Gla_ManCountPPis(p) );
+ Abc_Print( 1, "%5d", Gia_GlaAbsCount(p, 1, 0) );
+ Abc_Print( 1, "%6d", Gia_GlaAbsCount(p, 0, 1) );
+ Abc_Print( 1, "%8d", nConfls );
+ if ( nCexes == 0 )
+ Abc_Print( 1, "%5c", '-' );
+ else
+ Abc_Print( 1, "%5d", nCexes );
+// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) );
+ Abc_PrintInt( sat_solver2_nvars(p->pSat) );
+ Abc_PrintInt( sat_solver2_nclauses(p->pSat) );
+ Abc_PrintInt( sat_solver2_nlearnts(p->pSat) );
+// Abc_Print( 1, " %6d", nCoreSize > 0 ? nCoreSize : 0 );
+ Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC );
+ Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) );
+// Abc_PrintInt( p->nAbsNew );
+// Abc_PrintInt( p->nLrnNew );
+// Abc_Print( 1, "%4.1f MB", 4.0 * p->nLrnNew * Abc_BitWordNum(p->nAbsNew) / (1<<20) );
+ Abc_Print( 1, "%s", (nCoreSize > 0 && nCexes > 0) ? "\n" : "\r" );
+ fflush( stdout );
+}
+void Gla_ManReportMemory( Gla_Man_t * p )
+{
+ Gla_Obj_t * pGla;
+ double memTot = 0;
+ double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t);
+ double memSat = sat_solver2_memory( p->pSat, 1 );
+ double memPro = sat_solver2_memory_proof( p->pSat );
+ double memMap = p->nObjs * sizeof(Gla_Obj_t) + Gia_ManObjNum(p->pGia) * sizeof(int);
+ double memRef = Rnm_ManMemoryUsage( p->pRnm );
+ double memOth = sizeof(Gla_Man_t);
+ for ( pGla = p->pObjs; pGla < p->pObjs + p->nObjs; pGla++ )
+ memMap += Vec_IntCap(&pGla->vFrames) * sizeof(int);
+ memOth += Vec_IntCap(p->vAddedNew) * sizeof(int);
+ memOth += Vec_IntCap(p->vTemp) * sizeof(int);
+ memOth += Vec_IntCap(p->vAbs) * sizeof(int);
+ memTot = memAig + memSat + memPro + memMap + memRef + memOth;
+ ABC_PRMP( "Memory: AIG ", memAig, memTot );
+ ABC_PRMP( "Memory: SAT ", memSat, memTot );
+ ABC_PRMP( "Memory: Proof ", memPro, memTot );
+ ABC_PRMP( "Memory: Map ", memMap, memTot );
+ ABC_PRMP( "Memory: Refine ", memRef, memTot );
+ ABC_PRMP( "Memory: Other ", memOth, memTot );
+ ABC_PRMP( "Memory: TOTAL ", memTot, memTot );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_GlaSendAbsracted( Gla_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p );
+ Gia_Man_t * pAbs;
+ Vec_Int_t * vGateClasses;
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Sending abstracted model...\n" );
+ // create abstraction (value of p->pGia is not used here)
+ vGateClasses = Gla_ManTranslate( p );
+ pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses );
+ Vec_IntFreeP( &vGateClasses );
+ // send it out
+ Gia_ManToBridgeAbsNetlist( stdout, pAbs );
+ Gia_ManStop( pAbs );
+}
+void Gia_GlaSendCancel( Gla_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeBadAbs( FILE * pFile );
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Cancelling previously sent model...\n" );
+ Gia_ManToBridgeBadAbs( stdout );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_GlaDumpAbsracted( Gla_Man_t * p, int fVerbose )
+{
+ char * pFileNameDef = "glabs.aig";
+ char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef;
+ Gia_Man_t * pAbs;
+ Vec_Int_t * vGateClasses;
+ if ( fVerbose )
+ Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName );
+ // create abstraction
+ vGateClasses = Gla_ManTranslate( p );
+ pAbs = Gia_ManDupAbsGates( p->pGia0, vGateClasses );
+ Vec_IntFreeP( &vGateClasses );
+ // write into file
+ Gia_WriteAiger( pAbs, pFileName, 0, 0 );
+ Gia_ManStop( pAbs );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs gate-level abstraction]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManPerformGlaOld( Gia_Man_t * pAig, Abs_Par_t * pPars, int fStartVta )
+{
+ extern int Gia_VtaPerformInt( Gia_Man_t * pAig, Abs_Par_t * pPars );
+ extern void Ga2_ManDumpStats( Gia_Man_t * pGia, Abs_Par_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN );
+ Gla_Man_t * p;
+ Vec_Int_t * vPPis, * vCore;//, * vCore2 = NULL;
+ Abc_Cex_t * pCex = NULL;
+ int f, i, iPrev, nConfls, Status, nVarsOld = 0, nCoreSize, fOneIsSent = 0, RetValue = -1;
+ clock_t clk2, clk = clock();
+ // preconditions
+ assert( Gia_ManPoNum(pAig) == 1 );
+ assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) )
+ {
+ if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) )
+ {
+ printf( "Sequential miter is trivially UNSAT.\n" );
+ return 1;
+ }
+ ABC_FREE( pAig->pCexSeq );
+ pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 );
+ printf( "Sequential miter is trivially SAT.\n" );
+ return 0;
+ }
+
+ // compute intial abstraction
+ if ( pAig->vGateClasses == NULL )
+ {
+ if ( fStartVta )
+ {
+ int nFramesMaxOld = pPars->nFramesMax;
+ int nFramesStartOld = pPars->nFramesStart;
+ int nTimeOutOld = pPars->nTimeOut;
+ int nDumpOld = pPars->fDumpVabs;
+ pPars->nFramesMax = pPars->nFramesStart;
+ pPars->nFramesStart = Abc_MinInt( pPars->nFramesStart/2 + 1, 3 );
+ pPars->nTimeOut = 20;
+ pPars->fDumpVabs = 0;
+ RetValue = Gia_VtaPerformInt( pAig, pPars );
+ pPars->nFramesMax = nFramesMaxOld;
+ pPars->nFramesStart = nFramesStartOld;
+ pPars->nTimeOut = nTimeOutOld;
+ pPars->fDumpVabs = nDumpOld;
+ // create gate classes
+ Vec_IntFreeP( &pAig->vGateClasses );
+ if ( pAig->vObjClasses )
+ pAig->vGateClasses = Gia_VtaConvertToGla( pAig, pAig->vObjClasses );
+ Vec_IntFreeP( &pAig->vObjClasses );
+ // return if VTA solve the problem if could not start
+ if ( RetValue == 0 || pAig->vGateClasses == NULL )
+ return RetValue;
+ }
+ else
+ {
+ pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) );
+ Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 );
+ Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 );
+ }
+ }
+ // start the manager
+ p = Gla_ManStart( pAig, pPars );
+ p->timeInit = clock() - clk;
+ // set runtime limit
+ if ( p->pPars->nTimeOut )
+ sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() );
+ // perform initial abstraction
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" );
+ Abc_Print( 1, "FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%.\n",
+ pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin );
+ Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n",
+ pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce );
+ Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" );
+ }
+ for ( f = i = iPrev = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++, iPrev = i )
+ {
+ int nConflsBeg = sat_solver2_nconflicts(p->pSat);
+ p->pPars->iFrame = f;
+
+ // load timeframe
+ Gia_GlaAddTimeFrame( p, f );
+
+ // iterate as long as there are counter-examples
+ for ( i = 0; ; i++ )
+ {
+ clk2 = clock();
+ vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls );
+// assert( (vCore != NULL) == (Status == 1) );
+ if ( Status == -1 || (p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit) ) // resource limit is reached
+ {
+ Prf_ManStopP( &p->pSat->pPrf2 );
+// if ( Gia_ManRegNum(p->pGia) > 1 ) // for comb cases, return the abstraction
+// Vec_IntShrink( p->vAbs, p->nAbsOld );
+ goto finish;
+ }
+ if ( Status == 1 )
+ {
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ p->timeUnsat += clock() - clk2;
+ break;
+ }
+ p->timeSat += clock() - clk2;
+ assert( Status == 0 );
+ p->nCexes++;
+
+ // cancel old one if it was sent
+ if ( Abc_FrameIsBridgeMode() && fOneIsSent )
+ {
+ Gia_GlaSendCancel( p, pPars->fVerbose );
+ fOneIsSent = 0;
+ }
+
+ // perform the refinement
+ clk2 = clock();
+ if ( pPars->fAddLayer )
+ {
+ vPPis = Gla_ManCollectPPis( p, NULL );
+// Gla_ManExplorePPis( p, vPPis );
+ }
+ else
+ {
+ vPPis = Gla_ManRefinement( p );
+ if ( vPPis == NULL )
+ {
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ pCex = p->pGia->pCexSeq; p->pGia->pCexSeq = NULL;
+ break;
+ }
+ }
+ assert( pCex == NULL );
+
+ // start proof logging
+ if ( i == 0 )
+ {
+ // create bookmark to be used for rollback
+ sat_solver2_bookmark( p->pSat );
+ Vec_IntClear( p->vAddedNew );
+ p->nAbsOld = Vec_IntSize( p->vAbs );
+ nVarsOld = p->nSatVars;
+// p->nLrnOld = sat_solver2_nlearnts( p->pSat );
+// p->nAbsNew = 0;
+// p->nLrnNew = 0;
+
+ // start incremental proof manager
+ assert( p->pSat->pPrf2 == NULL );
+ if ( p->pSat->pPrf1 == NULL )
+ p->pSat->pPrf2 = Prf_ManAlloc();
+ if ( p->pSat->pPrf2 )
+ {
+ p->nProofIds = 0;
+ Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 );
+ Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) );
+ }
+ }
+ else
+ {
+ // resize the proof logger
+ if ( p->pSat->pPrf2 )
+ Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) );
+ }
+
+ Gia_GlaAddToAbs( p, vPPis, 1 );
+ Gia_GlaAddOneSlice( p, f, vPPis );
+ Vec_IntFree( vPPis );
+
+ // print the result (do not count it towards change)
+ if ( p->pPars->fVerbose )
+ Gla_ManAbsPrintFrame( p, -1, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk );
+ }
+ if ( pCex != NULL )
+ break;
+ assert( Status == 1 );
+
+ // valid core is obtained
+ nCoreSize = 1;
+ if ( vCore )
+ {
+ nCoreSize += Vec_IntSize( vCore );
+ Gia_GlaAddToCounters( p, vCore );
+ }
+ if ( i == 0 )
+ {
+ p->pPars->nFramesNoChange++;
+ Vec_IntFreeP( &vCore );
+ }
+ else
+ {
+ p->pPars->nFramesNoChange = 0;
+// p->nAbsNew = Vec_IntSize( p->vAbs ) - p->nAbsOld;
+// p->nLrnNew = Abc_AbsInt( sat_solver2_nlearnts( p->pSat ) - p->nLrnOld );
+ // update the SAT solver
+ sat_solver2_rollback( p->pSat );
+ // update storage
+ Gla_ManRollBack( p );
+ p->nSatVars = nVarsOld;
+ // load this timeframe
+ Gia_GlaAddToAbs( p, vCore, 0 );
+ Gia_GlaAddOneSlice( p, f, vCore );
+ Vec_IntFree( vCore );
+ // run SAT solver
+ clk2 = clock();
+ vCore = Gla_ManUnsatCore( p, f, p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls );
+ p->timeUnsat += clock() - clk2;
+// assert( (vCore != NULL) == (Status == 1) );
+ Vec_IntFreeP( &vCore );
+ if ( Status == -1 ) // resource limit is reached
+ break;
+ if ( Status == 0 )
+ {
+ assert( 0 );
+ // Vta_ManSatVerify( p );
+ // make sure, there was no initial abstraction (otherwise, it was invalid)
+ assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart );
+ // pCex = Vga_ManDeriveCex( p );
+ break;
+ }
+ }
+ // print the result
+ if ( p->pPars->fVerbose )
+ Gla_ManAbsPrintFrame( p, nCoreSize, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk );
+
+ if ( f > 2 && iPrev > 0 && i == 0 ) // change has happened
+ {
+ if ( Abc_FrameIsBridgeMode() )
+ {
+ // cancel old one if it was sent
+ if ( fOneIsSent )
+ Gia_GlaSendCancel( p, pPars->fVerbose );
+ // send new one
+ Gia_GlaSendAbsracted( p, pPars->fVerbose );
+ fOneIsSent = 1;
+ }
+
+ // dump the model into file
+ if ( p->pPars->fDumpVabs )
+ {
+ char Command[1000];
+ Abc_FrameSetStatus( -1 );
+ Abc_FrameSetCex( NULL );
+ Abc_FrameSetNFrames( f+1 );
+ sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status") );
+ Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
+ Gia_GlaDumpAbsracted( p, pPars->fVerbose );
+ }
+ }
+
+ // check if the number of objects is below limit
+ if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 )
+ {
+ Status = -1;
+ break;
+ }
+ }
+finish:
+ // analize the results
+ if ( pCex == NULL )
+ {
+ if ( p->pPars->fVerbose && Status == -1 )
+ printf( "\n" );
+// if ( pAig->vGateClasses != NULL )
+// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" );
+ Vec_IntFreeP( &pAig->vGateClasses );
+ pAig->vGateClasses = Gla_ManTranslate( p );
+ if ( Status == -1 )
+ {
+ if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit )
+ Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange );
+ else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit )
+ Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange );
+ else if ( Gia_GlaAbsCount(p,0,0) >= (p->nObjs - 1) * (100 - pPars->nRatioMin) / 100 )
+ Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f );
+ else
+ Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f );
+ }
+ else
+ {
+ p->pPars->iFrame++;
+ Abc_Print( 1, "GLA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange );
+ }
+ }
+ else
+ {
+ if ( p->pPars->fVerbose )
+ printf( "\n" );
+ ABC_FREE( pAig->pCexSeq );
+ pAig->pCexSeq = pCex;
+ if ( !Gia_ManVerifyCex( pAig, pCex, 0 ) )
+ Abc_Print( 1, " Gia_ManPerformGlaOld(): CEX verification has failed!\n" );
+ Abc_Print( 1, "Counter-example detected in frame %d. ", f );
+ p->pPars->iFrame = pCex->iFrame - 1;
+ Vec_IntFreeP( &pAig->vGateClasses );
+ RetValue = 0;
+ }
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ if ( p->pPars->fVerbose )
+ {
+ p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit;
+ ABC_PRTP( "Runtime: Initializing", p->timeInit, clock() - clk );
+ ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk );
+ ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk );
+ ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk );
+ ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk );
+ ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk );
+ Gla_ManReportMemory( p );
+ }
+// Ga2_ManDumpStats( pAig, p->pPars, p->pSat, p->pPars->iFrame, 1 );
+ Gla_ManStop( p );
+ fflush( stdout );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absIter.c b/src/proof/abs/absIter.c
new file mode 100644
index 00000000..88cbe39d
--- /dev/null
+++ b/src/proof/abs/absIter.c
@@ -0,0 +1,147 @@
+/**CFile****************************************************************
+
+ FileName [absIter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Iterative improvement of abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Gia_ObjIsInGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)); }
+static inline void Gia_ObjAddToGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 1); }
+static inline void Gia_ObjRemFromGla( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_IntWriteEntry(p->vGateClasses, Gia_ObjId(p, pObj), 0); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_IterTryImprove( Gia_Man_t * p, int nTimeOut, int iFrame0 )
+{
+ Gia_Man_t * pAbs = Gia_ManDupAbsGates( p, p->vGateClasses );
+ Aig_Man_t * pAig = Gia_ManToAigSimple( pAbs );
+ int nStart = 0;
+ int nFrames = iFrame0 ? iFrame0 + 1 : 10000000;
+ int nNodeDelta = 2000;
+ int nBTLimit = 0;
+ int nBTLimitAll = 0;
+ int fVerbose = 0;
+ int RetValue, iFrame;
+ RetValue = Saig_BmcPerform( pAig, nStart, nFrames, nNodeDelta, nTimeOut, nBTLimit, nBTLimitAll, fVerbose, 0, &iFrame, 1 );
+ assert( RetValue == 0 || RetValue == -1 );
+ Aig_ManStop( pAig );
+ Gia_ManStop( pAbs );
+ return iFrame;
+}
+Gia_Man_t * Gia_ManShrinkGla( Gia_Man_t * p, int nFrameMax, int nTimeOut, int fUsePdr, int fUseSat, int fUseBdd, int fVerbose )
+{
+ Gia_Obj_t * pObj;
+ int i, iFrame0, iFrame;
+ int nTotal = 0, nRemoved = 0;
+ Vec_Int_t * vGScopy;
+ clock_t clk, clkTotal = clock();
+ assert( Gia_ManPoNum(p) == 1 );
+ assert( p->vGateClasses != NULL );
+ vGScopy = Vec_IntDup( p->vGateClasses );
+ if ( nFrameMax == 0 )
+ iFrame0 = Gia_IterTryImprove( p, 0, 0 );
+ else
+ iFrame0 = nFrameMax - 1;
+ while ( 1 )
+ {
+ int fChanges = 0;
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( pObj->fMark0 )
+ continue;
+ if ( !Gia_ObjIsInGla(p, pObj) )
+ continue;
+ if ( pObj == Gia_ObjFanin0( Gia_ManPo(p, 0) ) )
+ continue;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(pObj)) && Gia_ObjIsInGla(p, Gia_ObjFanin1(pObj)) )
+ continue;
+ }
+ if ( Gia_ObjIsRo(p, pObj) )
+ {
+ if ( Gia_ObjIsInGla(p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj))) )
+ continue;
+ }
+ clk = clock();
+ printf( "%5d : ", nTotal );
+ printf( "Obj =%7d ", i );
+ Gia_ObjRemFromGla( p, pObj );
+ iFrame = Gia_IterTryImprove( p, nTimeOut, iFrame0 );
+ if ( nFrameMax )
+ assert( iFrame <= nFrameMax );
+ else
+ assert( iFrame <= iFrame0 );
+ printf( "Frame =%6d ", iFrame );
+ if ( iFrame < iFrame0 )
+ {
+ pObj->fMark0 = 1;
+ Gia_ObjAddToGla( p, pObj );
+ printf( " " );
+ }
+ else
+ {
+ fChanges = 1;
+ nRemoved++;
+ printf( "Removing " );
+ Vec_IntWriteEntry( vGScopy, Gia_ObjId(p, pObj), 0 );
+ }
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ nTotal++;
+ // update the classes
+ Vec_IntFreeP( &p->vGateClasses );
+ p->vGateClasses = Vec_IntDup(vGScopy);
+ }
+ if ( !fChanges )
+ break;
+ }
+ Gia_ManCleanMark0(p);
+ Vec_IntFree( vGScopy );
+ printf( "Tried = %d. ", nTotal );
+ printf( "Removed = %d. (%.2f %%) ", nRemoved, 100.0 * nRemoved / Vec_IntCountPositive(p->vGateClasses) );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absOldCex.c b/src/proof/abs/absOldCex.c
new file mode 100644
index 00000000..fec6d152
--- /dev/null
+++ b/src/proof/abs/absOldCex.c
@@ -0,0 +1,872 @@
+/**CFile****************************************************************
+
+ FileName [saigAbsCba.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Sequential AIG package.]
+
+ Synopsis [CEX-based abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: saigAbsCba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// local manager
+typedef struct Saig_ManCba_t_ Saig_ManCba_t;
+struct Saig_ManCba_t_
+{
+ // user data
+ Aig_Man_t * pAig; // user's AIG
+ Abc_Cex_t * pCex; // user's CEX
+ int nInputs; // the number of first inputs to skip
+ int fVerbose; // verbose flag
+ // unrolling
+ Aig_Man_t * pFrames; // unrolled timeframes
+ Vec_Int_t * vMapPiF2A; // mapping of frame PIs into real PIs
+ // additional information
+ Vec_Vec_t * vReg2Frame; // register to frame mapping
+ Vec_Vec_t * vReg2Value; // register to value mapping
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Selects the best flops from the given array.]
+
+ Description [Selects the best 'nFfsToSelect' flops among the array
+ 'vAbsFfsToAdd' of flops that should be added to the abstraction.
+ To this end, this procedure simulates the original AIG (pAig) using
+ the given CEX (pAbsCex), which was detected for the abstraction.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManCbaFilterFlops( Aig_Man_t * pAig, Abc_Cex_t * pAbsCex, Vec_Int_t * vFlopClasses, Vec_Int_t * vAbsFfsToAdd, int nFfsToSelect )
+{
+ Aig_Obj_t * pObj, * pObjRi, * pObjRo;
+ Vec_Int_t * vMapEntries, * vFlopCosts, * vFlopAddCosts, * vFfsToAddBest;
+ int i, k, f, Entry, iBit, * pPerm;
+ assert( Aig_ManRegNum(pAig) == Vec_IntSize(vFlopClasses) );
+ assert( Vec_IntSize(vAbsFfsToAdd) > nFfsToSelect );
+ // map previously abstracted flops into their original numbers
+ vMapEntries = Vec_IntAlloc( Vec_IntSize(vFlopClasses) );
+ Vec_IntForEachEntry( vFlopClasses, Entry, i )
+ if ( Entry == 0 )
+ Vec_IntPush( vMapEntries, i );
+ // simulate one frame at a time
+ assert( Saig_ManPiNum(pAig) + Vec_IntSize(vMapEntries) == pAbsCex->nPis );
+ vFlopCosts = Vec_IntStart( Vec_IntSize(vMapEntries) );
+ // initialize the flops
+ Aig_ManCleanMarkB(pAig);
+ Aig_ManConst1(pAig)->fMarkB = 1;
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->fMarkB = 0;
+ for ( f = 0; f < pAbsCex->iFrame; f++ )
+ {
+ // override the flop values according to the cex
+ iBit = pAbsCex->nRegs + f * pAbsCex->nPis + Saig_ManPiNum(pAig);
+ Vec_IntForEachEntry( vMapEntries, Entry, k )
+ Saig_ManLo(pAig, Entry)->fMarkB = Abc_InfoHasBit(pAbsCex->pData, iBit + k);
+ // simulate
+ Aig_ManForEachNode( pAig, pObj, k )
+ pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) &
+ (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj));
+ Aig_ManForEachCo( pAig, pObj, k )
+ pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj);
+ // transfer
+ Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k )
+ pObjRo->fMarkB = pObjRi->fMarkB;
+ // compare
+ iBit = pAbsCex->nRegs + (f + 1) * pAbsCex->nPis + Saig_ManPiNum(pAig);
+ Vec_IntForEachEntry( vMapEntries, Entry, k )
+ if ( Saig_ManLi(pAig, Entry)->fMarkB != (unsigned)Abc_InfoHasBit(pAbsCex->pData, iBit + k) )
+ Vec_IntAddToEntry( vFlopCosts, k, 1 );
+ }
+// Vec_IntForEachEntry( vFlopCosts, Entry, i )
+// printf( "%d ", Entry );
+// printf( "\n" );
+ // remap the cost
+ vFlopAddCosts = Vec_IntAlloc( Vec_IntSize(vAbsFfsToAdd) );
+ Vec_IntForEachEntry( vAbsFfsToAdd, Entry, i )
+ Vec_IntPush( vFlopAddCosts, -Vec_IntEntry(vFlopCosts, Entry) );
+ // sort the flops
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vFlopAddCosts), Vec_IntSize(vFlopAddCosts) );
+ // shrink the array
+ vFfsToAddBest = Vec_IntAlloc( nFfsToSelect );
+ for ( i = 0; i < nFfsToSelect; i++ )
+ {
+// printf( "%d ", Vec_IntEntry(vFlopAddCosts, pPerm[i]) );
+ Vec_IntPush( vFfsToAddBest, Vec_IntEntry(vAbsFfsToAdd, pPerm[i]) );
+ }
+// printf( "\n" );
+ // cleanup
+ ABC_FREE( pPerm );
+ Vec_IntFree( vMapEntries );
+ Vec_IntFree( vFlopCosts );
+ Vec_IntFree( vFlopAddCosts );
+ Aig_ManCleanMarkB(pAig);
+ // return the computed flops
+ return vFfsToAddBest;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicate with literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManDupWithCubes( Aig_Man_t * pAig, Vec_Vec_t * vReg2Value )
+{
+ Vec_Int_t * vLevel;
+ Aig_Man_t * pAigNew;
+ Aig_Obj_t * pObj, * pMiter;
+ int i, k, Lit;
+ assert( pAig->nConstrs == 0 );
+ // start the new manager
+ pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) + Vec_VecSizeSize(vReg2Value) );
+ pAigNew->pName = Abc_UtilStrsav( pAig->pName );
+ // map the constant node
+ Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
+ // create variables for PIs
+ Aig_ManForEachCi( pAig, pObj, i )
+ pObj->pData = Aig_ObjCreateCi( pAigNew );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ // create POs for cubes
+ Vec_VecForEachLevelInt( vReg2Value, vLevel, i )
+ {
+ pMiter = Aig_ManConst1( pAigNew );
+ Vec_IntForEachEntry( vLevel, Lit, k )
+ {
+ pObj = Saig_ManLi( pAig, Abc_Lit2Var(Lit) );
+ pMiter = Aig_And( pAigNew, pMiter, Aig_NotCond(Aig_ObjChild0Copy(pObj), Abc_LitIsCompl(Lit)) );
+ }
+ Aig_ObjCreateCo( pAigNew, pMiter );
+ }
+ // transfer to register outputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) );
+ // finalize
+ Aig_ManCleanup( pAigNew );
+ Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Maps array of frame PI IDs into array of additional PI IDs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManCbaReason2Inputs( Saig_ManCba_t * p, Vec_Int_t * vReasons )
+{
+ Vec_Int_t * vOriginal, * vVisited;
+ int i, Entry;
+ vOriginal = Vec_IntAlloc( Saig_ManPiNum(p->pAig) );
+ vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) );
+ Vec_IntForEachEntry( vReasons, Entry, i )
+ {
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry );
+ assert( iInput >= p->nInputs && iInput < Aig_ManCiNum(p->pAig) );
+ if ( Vec_IntEntry(vVisited, iInput) == 0 )
+ Vec_IntPush( vOriginal, iInput - p->nInputs );
+ Vec_IntAddToEntry( vVisited, iInput, 1 );
+ }
+ Vec_IntFree( vVisited );
+ return vOriginal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_ManCbaReason2Cex( Saig_ManCba_t * p, Vec_Int_t * vReasons )
+{
+ Abc_Cex_t * pCare;
+ int i, Entry, iInput, iFrame;
+ pCare = Abc_CexDup( p->pCex, p->pCex->nRegs );
+ memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) );
+ Vec_IntForEachEntry( vReasons, Entry, i )
+ {
+ assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pFrames) );
+ iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry );
+ iFrame = Vec_IntEntry( p->vMapPiF2A, 2*Entry+1 );
+ Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput );
+ }
+/*
+ for ( iFrame = 0; iFrame <= pCare->iFrame; iFrame++ )
+ {
+ int Count = 0;
+ for ( i = 0; i < pCare->nPis; i++ )
+ Count += Abc_InfoHasBit(pCare->pData, pCare->nRegs + pCare->nPis * iFrame + i);
+ printf( "%d ", Count );
+ }
+printf( "\n" );
+*/
+ return pCare;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns reasons for the property to fail.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManCbaFindReason_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vPrios, Vec_Int_t * vReasons )
+{
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Aig_ObjSetTravIdCurrent(p, pObj);
+ if ( Aig_ObjIsConst1(pObj) )
+ return;
+ if ( Aig_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vReasons, Aig_ObjCioId(pObj) );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ if ( pObj->fPhase )
+ {
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ }
+ else
+ {
+ int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase;
+ int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase;
+ assert( !fPhase0 || !fPhase1 );
+ if ( !fPhase0 && fPhase1 )
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ else if ( fPhase0 && !fPhase1 )
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ else
+ {
+ int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) );
+ int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) );
+ if ( iPrio0 <= iPrio1 )
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ else
+ Saig_ManCbaFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns reasons for the property to fail.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManCbaFindReason( Saig_ManCba_t * p )
+{
+ Aig_Obj_t * pObj;
+ Vec_Int_t * vPrios, * vReasons;
+ int i;
+
+ // set PI values according to CEX
+ vPrios = Vec_IntStartFull( Aig_ManObjNumMax(p->pFrames) );
+ Aig_ManConst1(p->pFrames)->fPhase = 1;
+ Aig_ManForEachCi( p->pFrames, pObj, i )
+ {
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i );
+ int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 );
+ pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput );
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), i );
+ }
+
+ // traverse and set the priority
+ Aig_ManForEachNode( p->pFrames, pObj, i )
+ {
+ int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase;
+ int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase;
+ int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) );
+ int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) );
+ pObj->fPhase = fPhase0 && fPhase1;
+ if ( fPhase0 && fPhase1 ) // both are one
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MaxInt(iPrio0, iPrio1) );
+ else if ( !fPhase0 && fPhase1 )
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio0 );
+ else if ( fPhase0 && !fPhase1 )
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio1 );
+ else // both are zero
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MinInt(iPrio0, iPrio1) );
+ }
+ // check the property output
+ pObj = Aig_ManCo( p->pFrames, 0 );
+ pObj->fPhase = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase;
+ assert( !pObj->fPhase );
+
+ // select the reason
+ vReasons = Vec_IntAlloc( 100 );
+ Aig_ManIncrementTravId( p->pFrames );
+ Saig_ManCbaFindReason_rec( p->pFrames, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ Vec_IntFree( vPrios );
+// assert( !Aig_ObjIsTravIdCurrent(p->pFrames, Aig_ManConst1(p->pFrames)) );
+ return vReasons;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes in the unrolled timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManCbaUnrollCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots )
+{
+ if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
+ return;
+ Aig_ObjSetTravIdCurrent(pAig, pObj);
+ if ( Aig_ObjIsCo(pObj) )
+ Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots );
+ Saig_ManCbaUnrollCollect_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots );
+ }
+ if ( vRoots && Saig_ObjIsLo( pAig, pObj ) )
+ Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) );
+ Vec_IntPush( vObjs, Aig_ObjId(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive unrolled timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManCbaUnrollWithCex( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, Vec_Int_t ** pvMapPiF2A, Vec_Vec_t ** pvReg2Frame )
+{
+ Aig_Man_t * pFrames; // unrolled timeframes
+ Vec_Vec_t * vFrameCos; // the list of COs per frame
+ Vec_Vec_t * vFrameObjs; // the list of objects per frame
+ Vec_Int_t * vRoots, * vObjs;
+ Aig_Obj_t * pObj;
+ int i, f;
+ // sanity checks
+ assert( Saig_ManPiNum(pAig) == pCex->nPis );
+// assert( Saig_ManRegNum(pAig) == pCex->nRegs );
+ assert( pCex->iPo >= 0 && pCex->iPo < Saig_ManPoNum(pAig) );
+
+ // map PIs of the unrolled frames into PIs of the original design
+ *pvMapPiF2A = Vec_IntAlloc( 1000 );
+
+ // collect COs and Objs visited in each frame
+ vFrameCos = Vec_VecStart( pCex->iFrame+1 );
+ vFrameObjs = Vec_VecStart( pCex->iFrame+1 );
+ // initialized the topmost frame
+ pObj = Aig_ManCo( pAig, pCex->iPo );
+ Vec_VecPushInt( vFrameCos, pCex->iFrame, Aig_ObjId(pObj) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ {
+ // collect nodes starting from the roots
+ Aig_ManIncrementTravId( pAig );
+ vRoots = Vec_VecEntryInt( vFrameCos, f );
+ Aig_ManForEachObjVec( vRoots, pAig, pObj, i )
+ Saig_ManCbaUnrollCollect_rec( pAig, pObj,
+ Vec_VecEntryInt(vFrameObjs, f),
+ (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) );
+ }
+
+ // derive unrolled timeframes
+ pFrames = Aig_ManStart( 10000 );
+ pFrames->pName = Abc_UtilStrsav( pAig->pName );
+ pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec );
+ // initialize the flops
+ if ( Saig_ManRegNum(pAig) == pCex->nRegs )
+ {
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, i) );
+ }
+ else // this is the case when synthesis was applied, assume all-0 init state
+ {
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), 1 );
+ }
+ // iterate through the frames
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // construct
+ vObjs = Vec_VecEntryInt( vFrameObjs, f );
+ Aig_ManForEachObjVec( vObjs, pAig, pObj, i )
+ {
+ if ( Aig_ObjIsNode(pObj) )
+ pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ else if ( Aig_ObjIsCo(pObj) )
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ else if ( Aig_ObjIsConst1(pObj) )
+ pObj->pData = Aig_ManConst1(pFrames);
+ else if ( Saig_ObjIsPi(pAig, pObj) )
+ {
+ if ( Aig_ObjCioId(pObj) < nInputs )
+ {
+ int iBit = pCex->nRegs + f * pCex->nPis + Aig_ObjCioId(pObj);
+ pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, iBit) );
+ }
+ else
+ {
+ pObj->pData = Aig_ObjCreateCi( pFrames );
+ Vec_IntPush( *pvMapPiF2A, Aig_ObjCioId(pObj) );
+ Vec_IntPush( *pvMapPiF2A, f );
+ }
+ }
+ }
+ if ( f == pCex->iFrame )
+ break;
+ // transfer
+ vRoots = Vec_VecEntryInt( vFrameCos, f );
+ Aig_ManForEachObjVec( vRoots, pAig, pObj, i )
+ {
+ Saig_ObjLiToLo( pAig, pObj )->pData = pObj->pData;
+ if ( *pvReg2Frame )
+ {
+ Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjId(pObj) ); // record LO
+ Vec_VecPushInt( *pvReg2Frame, f, Aig_ObjToLit((Aig_Obj_t *)pObj->pData) ); // record its literal
+ }
+ }
+ }
+ // create output
+ pObj = Aig_ManCo( pAig, pCex->iPo );
+ Aig_ObjCreateCo( pFrames, Aig_Not((Aig_Obj_t *)pObj->pData) );
+ Aig_ManSetRegNum( pFrames, 0 );
+ // cleanup
+ Vec_VecFree( vFrameCos );
+ Vec_VecFree( vFrameObjs );
+ // finallize
+ Aig_ManCleanup( pFrames );
+ // return
+ return pFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates refinement manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Saig_ManCba_t * Saig_ManCbaStart( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose )
+{
+ Saig_ManCba_t * p;
+ p = ABC_CALLOC( Saig_ManCba_t, 1 );
+ p->pAig = pAig;
+ p->pCex = pCex;
+ p->nInputs = nInputs;
+ p->fVerbose = fVerbose;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Destroys refinement manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManCbaStop( Saig_ManCba_t * p )
+{
+ Vec_VecFreeP( &p->vReg2Frame );
+ Vec_VecFreeP( &p->vReg2Value );
+ Aig_ManStopP( &p->pFrames );
+ Vec_IntFreeP( &p->vMapPiF2A );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Destroys refinement manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManCbaShrink( Saig_ManCba_t * p )
+{
+ Aig_Man_t * pManNew;
+ Aig_Obj_t * pObjLi, * pObjFrame;
+ Vec_Int_t * vLevel, * vLevel2;
+ int f, k, ObjId, Lit;
+ // assuming that important objects are labeled in Saig_ManCbaFindReason()
+ Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, f )
+ {
+ Vec_IntForEachEntryDouble( vLevel, ObjId, Lit, k )
+ {
+ pObjFrame = Aig_ManObj( p->pFrames, Abc_Lit2Var(Lit) );
+ if ( pObjFrame == NULL || (!Aig_ObjIsConst1(pObjFrame) && !Aig_ObjIsTravIdCurrent(p->pFrames, pObjFrame)) )
+ continue;
+ pObjLi = Aig_ManObj( p->pAig, ObjId );
+ assert( Saig_ObjIsLi(p->pAig, pObjLi) );
+ Vec_VecPushInt( p->vReg2Value, f, Abc_Var2Lit( Aig_ObjCioId(pObjLi) - Saig_ManPoNum(p->pAig), Abc_LitIsCompl(Lit) ^ !pObjFrame->fPhase ) );
+ }
+ }
+ // print statistics
+ Vec_VecForEachLevelInt( p->vReg2Frame, vLevel, k )
+ {
+ vLevel2 = Vec_VecEntryInt( p->vReg2Value, k );
+ printf( "Level = %4d StateBits = %4d (%6.2f %%) CareBits = %4d (%6.2f %%)\n", k,
+ Vec_IntSize(vLevel)/2, 100.0 * (Vec_IntSize(vLevel)/2) / Aig_ManRegNum(p->pAig),
+ Vec_IntSize(vLevel2), 100.0 * Vec_IntSize(vLevel2) / Aig_ManRegNum(p->pAig) );
+ }
+ // try reducing the frames
+ pManNew = Saig_ManDupWithCubes( p->pAig, p->vReg2Value );
+// Ioa_WriteAiger( pManNew, "aigcube.aig", 0, 0 );
+ Aig_ManStop( pManNew );
+}
+
+static inline void Saig_ObjCexMinSet0( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 0; }
+static inline void Saig_ObjCexMinSet1( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; pObj->fMarkB = 1; }
+static inline void Saig_ObjCexMinSetX( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; pObj->fMarkB = 1; }
+
+static inline int Saig_ObjCexMinGet0( Aig_Obj_t * pObj ) { return pObj->fMarkA && !pObj->fMarkB; }
+static inline int Saig_ObjCexMinGet1( Aig_Obj_t * pObj ) { return !pObj->fMarkA && pObj->fMarkB; }
+static inline int Saig_ObjCexMinGetX( Aig_Obj_t * pObj ) { return pObj->fMarkA && pObj->fMarkB; }
+
+static inline int Saig_ObjCexMinGet0Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); }
+static inline int Saig_ObjCexMinGet1Fanin0( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin0(pObj)) && Aig_ObjFaninC0(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin0(pObj)) && !Aig_ObjFaninC0(pObj)); }
+
+static inline int Saig_ObjCexMinGet0Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); }
+static inline int Saig_ObjCexMinGet1Fanin1( Aig_Obj_t * pObj ) { return (Saig_ObjCexMinGet0(Aig_ObjFanin1(pObj)) && Aig_ObjFaninC1(pObj)) || (Saig_ObjCexMinGet1(Aig_ObjFanin1(pObj)) && !Aig_ObjFaninC1(pObj)); }
+
+static inline void Saig_ObjCexMinSim( Aig_Obj_t * pObj )
+{
+ if ( Aig_ObjIsAnd(pObj) )
+ {
+ if ( Saig_ObjCexMinGet0Fanin0(pObj) || Saig_ObjCexMinGet0Fanin1(pObj) )
+ Saig_ObjCexMinSet0( pObj );
+ else if ( Saig_ObjCexMinGet1Fanin0(pObj) && Saig_ObjCexMinGet1Fanin1(pObj) )
+ Saig_ObjCexMinSet1( pObj );
+ else
+ Saig_ObjCexMinSetX( pObj );
+ }
+ else if ( Aig_ObjIsCo(pObj) )
+ {
+ if ( Saig_ObjCexMinGet0Fanin0(pObj) )
+ Saig_ObjCexMinSet0( pObj );
+ else if ( Saig_ObjCexMinGet1Fanin0(pObj) )
+ Saig_ObjCexMinSet1( pObj );
+ else
+ Saig_ObjCexMinSetX( pObj );
+ }
+ else assert( 0 );
+}
+
+static inline void Saig_ObjCexMinPrint( Aig_Obj_t * pObj )
+{
+ if ( Saig_ObjCexMinGet0(pObj) )
+ printf( "0" );
+ else if ( Saig_ObjCexMinGet1(pObj) )
+ printf( "1" );
+ else if ( Saig_ObjCexMinGetX(pObj) )
+ printf( "X" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManCexVerifyUsingTernary( Aig_Man_t * pAig, Abc_Cex_t * pCex, Abc_Cex_t * pCare )
+{
+ Aig_Obj_t * pObj, * pObjRi, * pObjRo;
+ int i, f, iBit = 0;
+ assert( pCex->iFrame == pCare->iFrame );
+ assert( pCex->nBits == pCare->nBits );
+ assert( pCex->iPo < Saig_ManPoNum(pAig) );
+ Saig_ObjCexMinSet1( Aig_ManConst1(pAig) );
+ // set flops to the init state
+ Saig_ManForEachLo( pAig, pObj, i )
+ {
+ assert( !Abc_InfoHasBit(pCex->pData, iBit) );
+ assert( !Abc_InfoHasBit(pCare->pData, iBit) );
+// if ( Abc_InfoHasBit(pCare->pData, iBit++) )
+ Saig_ObjCexMinSet0( pObj );
+// else
+// Saig_ObjCexMinSetX( pObj );
+ }
+ iBit = pCex->nRegs;
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // init inputs
+ Saig_ManForEachPi( pAig, pObj, i )
+ {
+ if ( Abc_InfoHasBit(pCare->pData, iBit++) )
+ {
+ if ( Abc_InfoHasBit(pCex->pData, iBit-1) )
+ Saig_ObjCexMinSet1( pObj );
+ else
+ Saig_ObjCexMinSet0( pObj );
+ }
+ else
+ Saig_ObjCexMinSetX( pObj );
+ }
+ // simulate internal nodes
+ Aig_ManForEachNode( pAig, pObj, i )
+ Saig_ObjCexMinSim( pObj );
+ // simulate COs
+ Aig_ManForEachCo( pAig, pObj, i )
+ Saig_ObjCexMinSim( pObj );
+/*
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ Aig_ObjPrint(pAig, pObj);
+ printf( " Value = " );
+ Saig_ObjCexMinPrint( pObj );
+ printf( "\n" );
+ }
+*/
+ // transfer
+ Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, i )
+ pObjRo->fMarkA = pObjRi->fMarkA,
+ pObjRo->fMarkB = pObjRi->fMarkB;
+ }
+ assert( iBit == pCex->nBits );
+ return Saig_ObjCexMinGet1( Aig_ManCo( pAig, pCex->iPo ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [SAT-based refinement of the counter-example.]
+
+ Description [The first parameter (nInputs) indicates how many first
+ primary inputs to skip without considering as care candidates.]
+
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_ManCbaFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose )
+{
+ Saig_ManCba_t * p;
+ Vec_Int_t * vReasons;
+ Abc_Cex_t * pCare;
+ clock_t clk = clock();
+
+ clk = clock();
+ p = Saig_ManCbaStart( pAig, pCex, nInputs, fVerbose );
+
+// p->vReg2Frame = Vec_VecStart( pCex->iFrame );
+// p->vReg2Value = Vec_VecStart( pCex->iFrame );
+ p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, nInputs, &p->vMapPiF2A, &p->vReg2Frame );
+ vReasons = Saig_ManCbaFindReason( p );
+ if ( p->vReg2Frame )
+ Saig_ManCbaShrink( p );
+
+
+//if ( fVerbose )
+//Aig_ManPrintStats( p->pFrames );
+
+ if ( fVerbose )
+ {
+ Vec_Int_t * vRes = Saig_ManCbaReason2Inputs( p, vReasons );
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+ Vec_IntFree( vRes );
+ABC_PRT( "Time", clock() - clk );
+ }
+
+ pCare = Saig_ManCbaReason2Cex( p, vReasons );
+ Vec_IntFree( vReasons );
+ Saig_ManCbaStop( p );
+
+if ( fVerbose )
+{
+printf( "Real " );
+Abc_CexPrintStats( pCex );
+}
+if ( fVerbose )
+{
+printf( "Care " );
+Abc_CexPrintStats( pCare );
+}
+/*
+ // verify the reduced counter-example using ternary simulation
+ if ( !Saig_ManCexVerifyUsingTernary( pAig, pCex, pCare ) )
+ printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification has failed!!!\n" );
+ else if ( fVerbose )
+ printf( "Saig_ManCbaFindCexCareBits(): Minimized counter-example verification is successful.\n" );
+*/
+ Aig_ManCleanMarkAB( pAig );
+ return pCare;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of PIs for flops that should not be absracted.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManCbaFilterInputs( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose )
+{
+ Saig_ManCba_t * p;
+ Vec_Int_t * vRes, * vReasons;
+ clock_t clk;
+ if ( Saig_ManPiNum(pAig) != pCex->nPis )
+ {
+ printf( "Saig_ManCbaFilterInputs(): The PI count of AIG (%d) does not match that of cex (%d).\n",
+ Aig_ManCiNum(pAig), pCex->nPis );
+ return NULL;
+ }
+
+clk = clock();
+ p = Saig_ManCbaStart( pAig, pCex, iFirstFlopPi, fVerbose );
+ p->pFrames = Saig_ManCbaUnrollWithCex( pAig, pCex, iFirstFlopPi, &p->vMapPiF2A, &p->vReg2Frame );
+ vReasons = Saig_ManCbaFindReason( p );
+ vRes = Saig_ManCbaReason2Inputs( p, vReasons );
+ if ( fVerbose )
+ {
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+ABC_PRT( "Time", clock() - clk );
+ }
+
+ Vec_IntFree( vReasons );
+ Saig_ManCbaStop( p );
+ return vRes;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks the abstracted model for a counter-example.]
+
+ Description [Returns the array of abstracted flops that should be added
+ to the abstraction.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManCbaPerform( Aig_Man_t * pAbs, int nInputs, Saig_ParBmc_t * pPars )
+{
+ Vec_Int_t * vAbsFfsToAdd;
+ int RetValue;
+ clock_t clk = clock();
+// assert( pAbs->nRegs > 0 );
+ // perform BMC
+ RetValue = Saig_ManBmcScalable( pAbs, pPars );
+ if ( RetValue == -1 ) // time out - nothing to add
+ {
+ printf( "Resource limit is reached during BMC.\n" );
+ assert( pAbs->pSeqModel == NULL );
+ return Vec_IntAlloc( 0 );
+ }
+ if ( pAbs->pSeqModel == NULL )
+ {
+ printf( "BMC did not detect a CEX with the given depth.\n" );
+ return Vec_IntAlloc( 0 );
+ }
+ if ( pPars->fVerbose )
+ Abc_CexPrintStats( pAbs->pSeqModel );
+ // CEX is detected - refine the flops
+ vAbsFfsToAdd = Saig_ManCbaFilterInputs( pAbs, nInputs, pAbs->pSeqModel, pPars->fVerbose );
+ if ( Vec_IntSize(vAbsFfsToAdd) == 0 )
+ {
+ Vec_IntFree( vAbsFfsToAdd );
+ return NULL;
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Adding %d registers to the abstraction (total = %d). ",
+ Vec_IntSize(vAbsFfsToAdd), Aig_ManRegNum(pAbs)+Vec_IntSize(vAbsFfsToAdd) );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ return vAbsFfsToAdd;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absOldRef.c b/src/proof/abs/absOldRef.c
new file mode 100644
index 00000000..dee28cad
--- /dev/null
+++ b/src/proof/abs/absOldRef.c
@@ -0,0 +1,369 @@
+/**CFile****************************************************************
+
+ FileName [saigAbsStart.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Sequential AIG package.]
+
+ Synopsis [Counter-example-based abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: saigAbsStart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+#include "proof/ssw/ssw.h"
+#include "proof/fra/fra.h"
+#include "proof/bbr/bbr.h"
+#include "proof/pdr/pdr.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derive a new counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs )
+{
+ Abc_Cex_t * pCex;
+ Aig_Obj_t * pObj;
+ int i, f;
+ if ( !Saig_ManVerifyCex( pAbs, pCexAbs ) )
+ printf( "Saig_ManCexRemap(): The initial counter-example is invalid.\n" );
+// else
+// printf( "Saig_ManCexRemap(): The initial counter-example is correct.\n" );
+ // start the counter-example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 );
+ pCex->iFrame = pCexAbs->iFrame;
+ pCex->iPo = pCexAbs->iPo;
+ // copy the bit data
+ for ( f = 0; f <= pCexAbs->iFrame; f++ )
+ {
+ Saig_ManForEachPi( pAbs, pObj, i )
+ {
+ if ( i == Saig_ManPiNum(p) )
+ break;
+ if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) )
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + i );
+ }
+ }
+ // verify the counter example
+ if ( !Saig_ManVerifyCex( p, pCex ) )
+ {
+ printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" );
+ Abc_CexFree( pCex );
+ pCex = NULL;
+ }
+ else
+ {
+ Abc_Print( 1, "Counter-example verification is successful.\n" );
+ Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame );
+ }
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the first PI corresponding to the flop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManCexFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ assert( pAbs->vCiNumsOrig != NULL );
+ Aig_ManForEachCi( p, pObj, i )
+ {
+ if ( Vec_IntEntry(pAbs->vCiNumsOrig, i) >= Saig_ManPiNum(p) )
+ return i;
+ }
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction using one step.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 )
+{
+ Vec_Int_t * vFlopsNew;
+ int i, Entry, RetValue;
+ *piRetValue = -1;
+ if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 )
+ {
+/*
+ Fra_Sec_t SecPar, * pSecPar = &SecPar;
+ Fra_SecSetDefaultParams( pSecPar );
+ pSecPar->fVerbose = fVerbose;
+ RetValue = Fra_FraigSec( pAbs, pSecPar, NULL );
+*/
+ Abc_Cex_t * pCex = NULL;
+ Aig_Man_t * pAbsOrpos = Saig_ManDupOrpos( pAbs );
+ Pdr_Par_t Pars, * pPars = &Pars;
+ Pdr_ManSetDefaultParams( pPars );
+ pPars->nTimeOut = 10;
+ pPars->fVerbose = fVerbose;
+ if ( pPars->fVerbose )
+ printf( "Running property directed reachability...\n" );
+ RetValue = Pdr_ManSolve( pAbsOrpos, pPars, &pCex );
+ if ( pCex )
+ pCex->iPo = Saig_ManFindFailedPoCex( pAbs, pCex );
+ Aig_ManStop( pAbsOrpos );
+ pAbs->pSeqModel = pCex;
+ if ( RetValue )
+ *piRetValue = 1;
+
+ }
+ else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) )
+ {
+ 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;
+ RetValue = Aig_ManVerifyUsingBdds( pAbs, pPars );
+ if ( RetValue )
+ *piRetValue = 1;
+ }
+ else
+ {
+ Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 0, nConfMaxOne, 0, fVerbose, 0, pnFrames, 0 );
+ }
+ if ( pAbs->pSeqModel == NULL )
+ return NULL;
+ if ( pnUseStart )
+ *pnUseStart = pAbs->pSeqModel->iFrame;
+// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, 1, fVerbose );
+ vFlopsNew = Saig_ManExtendCounterExampleTest3( 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_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 (total = %d).\n\n", Vec_IntSize(vFlopsNew), Aig_ManRegNum(pAbs)+Vec_IntSize(vFlopsNew) );
+ // add to the abstraction
+ Vec_IntForEachEntry( vFlopsNew, Entry, i )
+ {
+ Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry);
+ assert( Entry >= Saig_ManPiNum(p) );
+ assert( Entry < Aig_ManCiNum(p) );
+ 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_ManDupAbstraction( p, vFlops );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction using one step.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vFlopClasses, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose )
+{
+ Aig_Man_t * pAbs;
+ Vec_Int_t * vFlopsNew;
+ int i, Entry;
+ clock_t clk = clock();
+ pAbs = Saig_ManDupAbstraction( p, vFlops );
+ if ( fSensePath )
+ vFlopsNew = Saig_ManExtendCounterExampleTest2( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose );
+ else
+// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fTryFour, fVerbose );
+ vFlopsNew = Saig_ManExtendCounterExampleTest3( 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_ManCiNum(pAbs), Aig_ManCiNum(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 (total = %d). ", Vec_IntSize(vFlopsNew), Aig_ManRegNum(p)+Vec_IntSize(vFlopsNew) );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ // vFlopsNew contains PI numbers that should be kept in pAbs
+ // select the most useful flops among those to be added
+ if ( nFfToAddMax > 0 && Vec_IntSize(vFlopsNew) > nFfToAddMax )
+ {
+ Vec_Int_t * vFlopsNewBest;
+ // shift the indices
+ Vec_IntForEachEntry( vFlopsNew, Entry, i )
+ Vec_IntAddToEntry( vFlopsNew, i, -Saig_ManPiNum(p) );
+ // create new flops
+ vFlopsNewBest = Saig_ManCbaFilterFlops( p, pCex, vFlopClasses, vFlopsNew, nFfToAddMax );
+ assert( Vec_IntSize(vFlopsNewBest) == nFfToAddMax );
+ printf( "Filtering flops based on cost (%d -> %d).\n", Vec_IntSize(vFlopsNew), Vec_IntSize(vFlopsNewBest) );
+ // update
+ Vec_IntFree( vFlopsNew );
+ vFlopsNew = vFlopsNewBest;
+ // shift the indices
+ Vec_IntForEachEntry( vFlopsNew, Entry, i )
+ Vec_IntAddToEntry( vFlopsNew, i, Saig_ManPiNum(p) );
+ }
+ // add to the abstraction
+ Vec_IntForEachEntry( vFlopsNew, Entry, i )
+ {
+ Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry);
+ assert( Entry >= Saig_ManPiNum(p) );
+ assert( Entry < Aig_ManCiNum(p) );
+ Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) );
+ }
+ Vec_IntFree( vFlopsNew );
+ Aig_ManStop( pAbs );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flop map into flop list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses )
+{
+ Vec_Int_t * vFlops;
+ int i, Entry;
+ vFlops = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vFlopClasses, Entry, i )
+ if ( Entry )
+ Vec_IntPush( vFlops, i );
+ return vFlops;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flop list into flop map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops )
+{
+ Vec_Int_t * vFlopClasses;
+ int i, Entry;
+ vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) );
+ Vec_IntForEachEntry( vFlops, Entry, i )
+ Vec_IntWriteEntry( vFlopClasses, Entry, 1 );
+ return vFlopClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction using the latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int nFfToAddMax, int fTryFour, int fSensePath, int fVerbose )
+{
+ Aig_Man_t * pNew;
+ Vec_Int_t * vFlops;
+ if ( pGia->vFlopClasses == NULL )
+ {
+ printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" );
+ return -1;
+ }
+ pNew = Gia_ManToAig( pGia, 0 );
+ vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses );
+ if ( !Saig_ManCexRefineStep( pNew, vFlops, pGia->vFlopClasses, pCex, nFfToAddMax, fTryFour, fSensePath, fVerbose ) )
+ {
+ pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
+ Vec_IntFree( vFlops );
+ Aig_ManStop( pNew );
+ return 0;
+ }
+ Vec_IntFree( pGia->vFlopClasses );
+ pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops );
+ Vec_IntFree( vFlops );
+ Aig_ManStop( pNew );
+ return -1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absOldSat.c b/src/proof/abs/absOldSat.c
new file mode 100644
index 00000000..14f59667
--- /dev/null
+++ b/src/proof/abs/absOldSat.c
@@ -0,0 +1,986 @@
+/**CFile****************************************************************
+
+ FileName [saigRefSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Sequential AIG package.]
+
+ Synopsis [SAT based refinement of a counter-example.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: saigRefSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// local manager
+typedef struct Saig_RefMan_t_ Saig_RefMan_t;
+struct Saig_RefMan_t_
+{
+ // user data
+ Aig_Man_t * pAig; // user's AIG
+ Abc_Cex_t * pCex; // user's CEX
+ int nInputs; // the number of first inputs to skip
+ int fVerbose; // verbose flag
+ // unrolling
+ Aig_Man_t * pFrames; // unrolled timeframes
+ Vec_Int_t * vMapPiF2A; // mapping of frame PIs into real PIs
+};
+
+// performs ternary simulation
+extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Maps array of frame PI IDs into array of original PI IDs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_RefManReason2Inputs( Saig_RefMan_t * p, Vec_Int_t * vReasons )
+{
+ Vec_Int_t * vOriginal, * vVisited;
+ int i, Entry;
+ vOriginal = Vec_IntAlloc( Saig_ManPiNum(p->pAig) );
+ vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) );
+ Vec_IntForEachEntry( vReasons, Entry, i )
+ {
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry );
+ assert( iInput >= 0 && iInput < Aig_ManCiNum(p->pAig) );
+ if ( Vec_IntEntry(vVisited, iInput) == 0 )
+ Vec_IntPush( vOriginal, iInput );
+ Vec_IntAddToEntry( vVisited, iInput, 1 );
+ }
+ Vec_IntFree( vVisited );
+ return vOriginal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_RefManReason2Cex( Saig_RefMan_t * p, Vec_Int_t * vReasons )
+{
+ Abc_Cex_t * pCare;
+ int i, Entry, iInput, iFrame;
+ pCare = Abc_CexDup( p->pCex, p->pCex->nRegs );
+ memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) );
+ Vec_IntForEachEntry( vReasons, Entry, i )
+ {
+ assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pFrames) );
+ iInput = Vec_IntEntry( p->vMapPiF2A, 2*Entry );
+ iFrame = Vec_IntEntry( p->vMapPiF2A, 2*Entry+1 );
+ Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput );
+ }
+ return pCare;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns reasons for the property to fail.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_RefManFindReason_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Int_t * vPrios, Vec_Int_t * vReasons )
+{
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Aig_ObjSetTravIdCurrent(p, pObj);
+ if ( Aig_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vReasons, Aig_ObjCioId(pObj) );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ if ( pObj->fPhase )
+ {
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ }
+ else
+ {
+ int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase;
+ int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase;
+ assert( !fPhase0 || !fPhase1 );
+ if ( !fPhase0 && fPhase1 )
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ else if ( fPhase0 && !fPhase1 )
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ else
+ {
+ int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) );
+ int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) );
+ if ( iPrio0 <= iPrio1 )
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ else
+ Saig_RefManFindReason_rec( p, Aig_ObjFanin1(pObj), vPrios, vReasons );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns reasons for the property to fail.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_RefManFindReason( Saig_RefMan_t * p )
+{
+ Aig_Obj_t * pObj;
+ Vec_Int_t * vPrios, * vPi2Prio, * vReasons;
+ int i, CountPrios;
+
+ vPi2Prio = Vec_IntStartFull( Saig_ManPiNum(p->pAig) );
+ vPrios = Vec_IntStartFull( Aig_ManObjNumMax(p->pFrames) );
+
+ // set PI values according to CEX
+ CountPrios = 0;
+ Aig_ManConst1(p->pFrames)->fPhase = 1;
+ Aig_ManForEachCi( p->pFrames, pObj, i )
+ {
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i );
+ int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 );
+ pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput );
+ // assign priority
+ if ( Vec_IntEntry(vPi2Prio, iInput) == ~0 )
+ Vec_IntWriteEntry( vPi2Prio, iInput, CountPrios++ );
+// Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Vec_IntEntry(vPi2Prio, iInput) );
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), i );
+ }
+// printf( "Priority numbers = %d.\n", CountPrios );
+ Vec_IntFree( vPi2Prio );
+
+ // traverse and set the priority
+ Aig_ManForEachNode( p->pFrames, pObj, i )
+ {
+ int fPhase0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFanin0(pObj)->fPhase;
+ int fPhase1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFanin1(pObj)->fPhase;
+ int iPrio0 = Vec_IntEntry( vPrios, Aig_ObjFaninId0(pObj) );
+ int iPrio1 = Vec_IntEntry( vPrios, Aig_ObjFaninId1(pObj) );
+ pObj->fPhase = fPhase0 && fPhase1;
+ if ( fPhase0 && fPhase1 ) // both are one
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MaxInt(iPrio0, iPrio1) );
+ else if ( !fPhase0 && fPhase1 )
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio0 );
+ else if ( fPhase0 && !fPhase1 )
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), iPrio1 );
+ else // both are zero
+ Vec_IntWriteEntry( vPrios, Aig_ObjId(pObj), Abc_MinInt(iPrio0, iPrio1) );
+ }
+ // check the property output
+ pObj = Aig_ManCo( p->pFrames, 0 );
+ assert( (int)Aig_ObjFanin0(pObj)->fPhase == Aig_ObjFaninC0(pObj) );
+
+ // select the reason
+ vReasons = Vec_IntAlloc( 100 );
+ Aig_ManIncrementTravId( p->pFrames );
+ if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
+ Saig_RefManFindReason_rec( p->pFrames, Aig_ObjFanin0(pObj), vPrios, vReasons );
+ Vec_IntFree( vPrios );
+ return vReasons;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes in the unrolled timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManUnrollCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vObjs, Vec_Int_t * vRoots )
+{
+ if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
+ return;
+ Aig_ObjSetTravIdCurrent(pAig, pObj);
+ if ( Aig_ObjIsCo(pObj) )
+ Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin0(pObj), vObjs, vRoots );
+ Saig_ManUnrollCollect_rec( pAig, Aig_ObjFanin1(pObj), vObjs, vRoots );
+ }
+ if ( vRoots && Saig_ObjIsLo( pAig, pObj ) )
+ Vec_IntPush( vRoots, Aig_ObjId( Saig_ObjLoToLi(pAig, pObj) ) );
+ Vec_IntPush( vObjs, Aig_ObjId(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive unrolled timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManUnrollWithCex( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, Vec_Int_t ** pvMapPiF2A )
+{
+ Aig_Man_t * pFrames; // unrolled timeframes
+ Vec_Vec_t * vFrameCos; // the list of COs per frame
+ Vec_Vec_t * vFrameObjs; // the list of objects per frame
+ Vec_Int_t * vRoots, * vObjs;
+ Aig_Obj_t * pObj;
+ int i, f;
+ // sanity checks
+ assert( Saig_ManPiNum(pAig) == pCex->nPis );
+ assert( Saig_ManRegNum(pAig) == pCex->nRegs );
+ assert( pCex->iPo >= 0 && pCex->iPo < Saig_ManPoNum(pAig) );
+
+ // map PIs of the unrolled frames into PIs of the original design
+ *pvMapPiF2A = Vec_IntAlloc( 1000 );
+
+ // collect COs and Objs visited in each frame
+ vFrameCos = Vec_VecStart( pCex->iFrame+1 );
+ vFrameObjs = Vec_VecStart( pCex->iFrame+1 );
+ // initialized the topmost frame
+ pObj = Aig_ManCo( pAig, pCex->iPo );
+ Vec_VecPushInt( vFrameCos, pCex->iFrame, Aig_ObjId(pObj) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ {
+ // collect nodes starting from the roots
+ Aig_ManIncrementTravId( pAig );
+ vRoots = Vec_VecEntryInt( vFrameCos, f );
+ Aig_ManForEachObjVec( vRoots, pAig, pObj, i )
+ Saig_ManUnrollCollect_rec( pAig, pObj,
+ Vec_VecEntryInt(vFrameObjs, f),
+ (Vec_Int_t *)(f ? Vec_VecEntry(vFrameCos, f-1) : NULL) );
+ }
+
+ // derive unrolled timeframes
+ pFrames = Aig_ManStart( 10000 );
+ pFrames->pName = Abc_UtilStrsav( pAig->pName );
+ pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec );
+ // initialize the flops
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, i) );
+ // iterate through the frames
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ // construct
+ vObjs = Vec_VecEntryInt( vFrameObjs, f );
+ Aig_ManForEachObjVec( vObjs, pAig, pObj, i )
+ {
+ if ( Aig_ObjIsNode(pObj) )
+ pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ else if ( Aig_ObjIsCo(pObj) )
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ else if ( Aig_ObjIsConst1(pObj) )
+ pObj->pData = Aig_ManConst1(pFrames);
+ else if ( Saig_ObjIsPi(pAig, pObj) )
+ {
+ if ( Aig_ObjCioId(pObj) < nInputs )
+ {
+ int iBit = pCex->nRegs + f * pCex->nPis + Aig_ObjCioId(pObj);
+ pObj->pData = Aig_NotCond( Aig_ManConst1(pFrames), !Abc_InfoHasBit(pCex->pData, iBit) );
+ }
+ else
+ {
+ pObj->pData = Aig_ObjCreateCi( pFrames );
+ Vec_IntPush( *pvMapPiF2A, Aig_ObjCioId(pObj) );
+ Vec_IntPush( *pvMapPiF2A, f );
+ }
+ }
+ }
+ if ( f == pCex->iFrame )
+ break;
+ // transfer
+ vRoots = Vec_VecEntryInt( vFrameCos, f );
+ Aig_ManForEachObjVec( vRoots, pAig, pObj, i )
+ Saig_ObjLiToLo( pAig, pObj )->pData = pObj->pData;
+ }
+ // create output
+ pObj = Aig_ManCo( pAig, pCex->iPo );
+ Aig_ObjCreateCo( pFrames, Aig_Not((Aig_Obj_t *)pObj->pData) );
+ Aig_ManSetRegNum( pFrames, 0 );
+ // cleanup
+ Vec_VecFree( vFrameCos );
+ Vec_VecFree( vFrameObjs );
+ // finallize
+ Aig_ManCleanup( pFrames );
+ // return
+ return pFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates refinement manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Saig_RefMan_t * Saig_RefManStart( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fVerbose )
+{
+ Saig_RefMan_t * p;
+ p = ABC_CALLOC( Saig_RefMan_t, 1 );
+ p->pAig = pAig;
+ p->pCex = pCex;
+ p->nInputs = nInputs;
+ p->fVerbose = fVerbose;
+ p->pFrames = Saig_ManUnrollWithCex( pAig, pCex, nInputs, &p->vMapPiF2A );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Destroys refinement manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_RefManStop( Saig_RefMan_t * p )
+{
+ Aig_ManStopP( &p->pFrames );
+ Vec_IntFreeP( &p->vMapPiF2A );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets phase bits in the timeframe AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_RefManSetPhases( Saig_RefMan_t * p, Abc_Cex_t * pCare, int fValue1 )
+{
+ Aig_Obj_t * pObj;
+ int i, iFrame, iInput;
+ Aig_ManConst1( p->pFrames )->fPhase = 1;
+ Aig_ManForEachCi( p->pFrames, pObj, i )
+ {
+ iInput = Vec_IntEntry( p->vMapPiF2A, 2*i );
+ iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 );
+ pObj->fPhase = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput );
+ // update value if it is a don't-care
+ if ( pCare && !Abc_InfoHasBit( pCare->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput ) )
+ pObj->fPhase = fValue1;
+ }
+ Aig_ManForEachNode( p->pFrames, pObj, i )
+ pObj->fPhase = ( Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fPhase ^ Aig_ObjFaninC1(pObj) );
+ Aig_ManForEachCo( p->pFrames, pObj, i )
+ pObj->fPhase = ( Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj) );
+ pObj = Aig_ManCo( p->pFrames, 0 );
+ return pObj->fPhase;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tries to remove literals from abstraction.]
+
+ Description [The literals are sorted more desirable first.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Vec_t * Saig_RefManOrderLiterals( Saig_RefMan_t * p, Vec_Int_t * vVar2PiId, Vec_Int_t * vAssumps )
+{
+ Vec_Vec_t * vLits;
+ Vec_Int_t * vVar2New;
+ int i, Entry, iInput, iFrame;
+ // collect literals
+ vLits = Vec_VecAlloc( 100 );
+ vVar2New = Vec_IntStartFull( Saig_ManPiNum(p->pAig) );
+ Vec_IntForEachEntry( vAssumps, Entry, i )
+ {
+ int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) );
+ assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) );
+ iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum );
+ iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 );
+// Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput );
+ if ( Vec_IntEntry( vVar2New, iInput ) == ~0 )
+ Vec_IntWriteEntry( vVar2New, iInput, Vec_VecSize(vLits) );
+ Vec_VecPushInt( vLits, Vec_IntEntry( vVar2New, iInput ), Entry );
+ }
+ Vec_IntFree( vVar2New );
+ return vLits;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Generate the care set using SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_RefManCreateCex( Saig_RefMan_t * p, Vec_Int_t * vVar2PiId, Vec_Int_t * vAssumps )
+{
+ Abc_Cex_t * pCare;
+ int i, Entry, iInput, iFrame;
+ // create counter-example
+ pCare = Abc_CexDup( p->pCex, p->pCex->nRegs );
+ memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) );
+ Vec_IntForEachEntry( vAssumps, Entry, i )
+ {
+ int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) );
+ assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) );
+ iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum );
+ iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 );
+ Abc_InfoSetBit( pCare->pData, pCare->nRegs + pCare->nPis * iFrame + iInput );
+ }
+ return pCare;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generate the care set using SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_RefManRunSat( Saig_RefMan_t * p, int fNewOrder )
+{
+ int nConfLimit = 1000000;
+ Abc_Cex_t * pCare;
+ Cnf_Dat_t * pCnf;
+ sat_solver * pSat;
+ Aig_Obj_t * pObj;
+ Vec_Vec_t * vLits = NULL;
+ Vec_Int_t * vAssumps, * vVar2PiId;
+ int i, k, Entry, RetValue;//, f = 0, Counter = 0;
+ int nCoreLits, * pCoreLits;
+ clock_t clk = clock();
+ // create CNF
+ assert( Aig_ManRegNum(p->pFrames) == 0 );
+// pCnf = Cnf_Derive( p->pFrames, 0 ); // too slow
+ pCnf = Cnf_DeriveSimple( p->pFrames, 0 );
+ RetValue = Saig_RefManSetPhases( p, NULL, 0 );
+ if ( RetValue )
+ {
+ printf( "Constructed frames are incorrect.\n" );
+ Cnf_DataFree( pCnf );
+ return NULL;
+ }
+ Cnf_DataTranformPolarity( pCnf, 0 );
+ // create SAT solver
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ if ( pSat == NULL )
+ {
+ Cnf_DataFree( pCnf );
+ return NULL;
+ }
+//Abc_PrintTime( 1, "Preparing", clock() - clk );
+ // look for a true counter-example
+ if ( p->nInputs > 0 )
+ {
+ RetValue = sat_solver_solve( pSat, NULL, NULL,
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( RetValue == l_False )
+ {
+ printf( "The problem is trivially UNSAT. The CEX is real.\n" );
+ // create counter-example
+ pCare = Abc_CexDup( p->pCex, p->pCex->nRegs );
+ memset( pCare->pData, 0, sizeof(unsigned) * Abc_BitWordNum(pCare->nBits) );
+ return pCare;
+ }
+ // the problem is SAT - it is expected
+ }
+ // create assumptions
+ vVar2PiId = Vec_IntStartFull( pCnf->nVars );
+ vAssumps = Vec_IntAlloc( Aig_ManCiNum(p->pFrames) );
+ Aig_ManForEachCi( p->pFrames, pObj, i )
+ {
+// RetValue = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput );
+// Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !RetValue ) );
+ Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 1 ) );
+ Vec_IntWriteEntry( vVar2PiId, pCnf->pVarNums[Aig_ObjId(pObj)], i );
+ }
+
+ // reverse the order of assumptions
+// if ( fNewOrder )
+// Vec_IntReverseOrder( vAssumps );
+
+ if ( fNewOrder )
+ {
+ // create literals
+ vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps );
+ // sort literals
+ Vec_VecSort( vLits, 1 );
+ // save literals
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ Vec_IntPush( vAssumps, Entry );
+
+ for ( i = 0; i < Vec_VecSize(vLits); i++ )
+ printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) );
+ printf( "\n" );
+
+ if ( p->fVerbose )
+ printf( "Total PIs = %d. Essential PIs = %d.\n",
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_VecSize(vLits) );
+ }
+
+ // solve
+clk = clock();
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+//Abc_PrintTime( 1, "Solving", clock() - clk );
+ if ( RetValue != l_False )
+ {
+ if ( RetValue == l_True )
+ printf( "Internal Error!!! The resulting problem is SAT.\n" );
+ else
+ printf( "Internal Error!!! SAT solver timed out.\n" );
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+ Vec_IntFree( vAssumps );
+ Vec_IntFree( vVar2PiId );
+ return NULL;
+ }
+ assert( RetValue == l_False ); // UNSAT
+
+ // get relevant SAT literals
+ nCoreLits = sat_solver_final( pSat, &pCoreLits );
+ assert( nCoreLits > 0 );
+ if ( p->fVerbose )
+ printf( "AnalizeFinal selected %d assumptions (out of %d). Conflicts = %d.\n",
+ nCoreLits, Vec_IntSize(vAssumps), (int)pSat->stats.conflicts );
+
+ // save literals
+ Vec_IntClear( vAssumps );
+ for ( i = 0; i < nCoreLits; i++ )
+ Vec_IntPush( vAssumps, pCoreLits[i] );
+
+
+ // create literals
+ vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps );
+ // sort literals
+// Vec_VecSort( vLits, 0 );
+ // save literals
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ Vec_IntPush( vAssumps, Entry );
+
+// for ( i = 0; i < Vec_VecSize(vLits); i++ )
+// printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) );
+// printf( "\n" );
+
+ if ( p->fVerbose )
+ printf( "Total PIs = %d. Essential PIs = %d.\n",
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_VecSize(vLits) );
+/*
+ // try assumptions in different order
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n",
+ Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts );
+
+ // create different sets of assumptions
+ Counter = Vec_VecSize(vLits);
+ for ( f = 0; f < Vec_VecSize(vLits); f++ )
+ {
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ if ( i != f )
+ Vec_IntPush( vAssumps, Entry );
+
+ // try the new assumptions
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n",
+ Vec_IntSize(vAssumps), RetValue == l_False ? "UNSAT" : "SAT", (int)pSat->stats.conflicts );
+ if ( RetValue != l_False )
+ continue;
+
+ // UNSAT - remove literals
+ Vec_IntClear( Vec_VecEntryInt(vLits, f) );
+ Counter--;
+ }
+
+ for ( i = 0; i < Vec_VecSize(vLits); i++ )
+ printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) );
+ printf( "\n" );
+
+ if ( p->fVerbose )
+ printf( "Total PIs = %d. Essential PIs = %d.\n",
+ Saig_ManPiNum(p->pAig) - p->nInputs, Counter );
+
+ // save literals
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ Vec_IntPush( vAssumps, Entry );
+*/
+ // create counter-example
+ pCare = Saig_RefManCreateCex( p, vVar2PiId, vAssumps );
+
+ // cleanup
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+ Vec_IntFree( vAssumps );
+ Vec_IntFree( vVar2PiId );
+ Vec_VecFreeP( &vLits );
+
+ // verify counter-example
+ RetValue = Saig_RefManSetPhases( p, pCare, 0 );
+ if ( RetValue )
+ printf( "Reduced CEX verification has failed.\n" );
+ RetValue = Saig_RefManSetPhases( p, pCare, 1 );
+ if ( RetValue )
+ printf( "Reduced CEX verification has failed.\n" );
+ return pCare;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_RefManRefineWithSat( Saig_RefMan_t * p, Vec_Int_t * vAigPis )
+{
+ int nConfLimit = 1000000;
+ Cnf_Dat_t * pCnf;
+ sat_solver * pSat;
+ Aig_Obj_t * pObj;
+ Vec_Vec_t * vLits;
+ Vec_Int_t * vReasons, * vAssumps, * vVisited, * vVar2PiId;
+ int i, k, f, Entry, RetValue, Counter;
+
+ // create CNF and SAT solver
+ pCnf = Cnf_DeriveSimple( p->pFrames, 0 );
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ if ( pSat == NULL )
+ {
+ Cnf_DataFree( pCnf );
+ return NULL;
+ }
+
+ // mark used AIG inputs
+ vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) );
+ Vec_IntForEachEntry( vAigPis, Entry, i )
+ {
+ assert( Entry >= 0 && Entry < Aig_ManCiNum(p->pAig) );
+ Vec_IntWriteEntry( vVisited, Entry, 1 );
+ }
+
+ // create assumptions
+ vVar2PiId = Vec_IntStartFull( pCnf->nVars );
+ vAssumps = Vec_IntAlloc( Aig_ManCiNum(p->pFrames) );
+ Aig_ManForEachCi( p->pFrames, pObj, i )
+ {
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*i );
+ int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*i+1 );
+ if ( Vec_IntEntry(vVisited, iInput) == 0 )
+ continue;
+ RetValue = Abc_InfoHasBit( p->pCex->pData, p->pCex->nRegs + p->pCex->nPis * iFrame + iInput );
+ Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !RetValue ) );
+// Vec_IntPush( vAssumps, toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 1 ) );
+ Vec_IntWriteEntry( vVar2PiId, pCnf->pVarNums[Aig_ObjId(pObj)], i );
+ }
+ Vec_IntFree( vVisited );
+
+ // try assumptions in different order
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n",
+ Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts );
+
+/*
+ // AnalizeFinal does not work because it implications propagate directly
+ // and SAT solver does not kick in (the number of conflicts in 0).
+
+ // count the number of lits in the unsat core
+ {
+ int nCoreLits, * pCoreLits;
+ nCoreLits = sat_solver_final( pSat, &pCoreLits );
+ assert( nCoreLits > 0 );
+
+ // count the number of flops
+ vVisited = Vec_IntStart( Saig_ManPiNum(p->pAig) );
+ for ( i = 0; i < nCoreLits; i++ )
+ {
+ int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(pCoreLits[i]) );
+ int iInput = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum );
+ int iFrame = Vec_IntEntry( p->vMapPiF2A, 2*iPiNum+1 );
+ Vec_IntWriteEntry( vVisited, iInput, 1 );
+ }
+ // count the number of entries
+ Counter = 0;
+ Vec_IntForEachEntry( vVisited, Entry, i )
+ Counter += Entry;
+ Vec_IntFree( vVisited );
+
+// if ( p->fVerbose )
+ printf( "AnalizeFinal: Assumptions %d (out of %d). Essential PIs = %d. Conflicts = %d.\n",
+ nCoreLits, Vec_IntSize(vAssumps), Counter, (int)pSat->stats.conflicts );
+ }
+*/
+
+ // derive literals
+ vLits = Saig_RefManOrderLiterals( p, vVar2PiId, vAssumps );
+ for ( i = 0; i < Vec_VecSize(vLits); i++ )
+ printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) );
+ printf( "\n" );
+
+ // create different sets of assumptions
+ Counter = Vec_VecSize(vLits);
+ for ( f = 0; f < Vec_VecSize(vLits); f++ )
+ {
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ if ( i != f )
+ Vec_IntPush( vAssumps, Entry );
+
+ // try the new assumptions
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n",
+ Vec_IntSize(vAssumps), RetValue == l_False ? "UNSAT" : "SAT", (int)pSat->stats.conflicts );
+ if ( RetValue != l_False )
+ continue;
+
+ // UNSAT - remove literals
+ Vec_IntClear( Vec_VecEntryInt(vLits, f) );
+ Counter--;
+ }
+
+ for ( i = 0; i < Vec_VecSize(vLits); i++ )
+ printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vLits, i) ) );
+ printf( "\n" );
+
+ // create assumptions
+ Vec_IntClear( vAssumps );
+ Vec_VecForEachEntryInt( vLits, Entry, i, k )
+ Vec_IntPush( vAssumps, Entry );
+
+ // try assumptions in different order
+ RetValue = sat_solver_solve( pSat, Vec_IntArray(vAssumps), Vec_IntArray(vAssumps) + Vec_IntSize(vAssumps),
+ (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ printf( "Assumpts = %2d. Intermediate instance is %5s. Conflicts = %2d.\n",
+ Vec_IntSize(vAssumps), (RetValue == l_False ? "UNSAT" : "SAT"), (int)pSat->stats.conflicts );
+
+// if ( p->fVerbose )
+// printf( "Total PIs = %d. Essential PIs = %d.\n",
+// Saig_ManPiNum(p->pAig) - p->nInputs, Counter );
+
+
+ // transform assumptions into reasons
+ vReasons = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vAssumps, Entry, i )
+ {
+ int iPiNum = Vec_IntEntry( vVar2PiId, lit_var(Entry) );
+ assert( iPiNum >= 0 && iPiNum < Aig_ManCiNum(p->pFrames) );
+ Vec_IntPush( vReasons, iPiNum );
+ }
+
+ // cleanup
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+ Vec_IntFree( vAssumps );
+ Vec_IntFree( vVar2PiId );
+ Vec_VecFreeP( &vLits );
+
+ return vReasons;
+}
+
+/**Function*************************************************************
+
+ Synopsis [SAT-based refinement of the counter-example.]
+
+ Description [The first parameter (nInputs) indicates how many first
+ primary inputs to skip without considering as care candidates.]
+
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Saig_ManFindCexCareBits( Aig_Man_t * pAig, Abc_Cex_t * pCex, int nInputs, int fNewOrder, int fVerbose )
+{
+ Saig_RefMan_t * p;
+ Vec_Int_t * vReasons;
+ Abc_Cex_t * pCare;
+ clock_t clk = clock();
+
+ clk = clock();
+ p = Saig_RefManStart( pAig, pCex, nInputs, fVerbose );
+ vReasons = Saig_RefManFindReason( p );
+
+if ( fVerbose )
+Aig_ManPrintStats( p->pFrames );
+
+// if ( fVerbose )
+ {
+ Vec_Int_t * vRes = Saig_RefManReason2Inputs( p, vReasons );
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+ABC_PRT( "Time", clock() - clk );
+
+ Vec_IntFree( vRes );
+
+/*
+ ////////////////////////////////////
+ Vec_IntFree( vReasons );
+ vReasons = Saig_RefManRefineWithSat( p, vRes );
+ ////////////////////////////////////
+
+ Vec_IntFree( vRes );
+ vRes = Saig_RefManReason2Inputs( p, vReasons );
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+
+ Vec_IntFree( vRes );
+ABC_PRT( "Time", clock() - clk );
+*/
+ }
+
+ pCare = Saig_RefManReason2Cex( p, vReasons );
+ Vec_IntFree( vReasons );
+ Saig_RefManStop( p );
+
+if ( fVerbose )
+Abc_CexPrintStats( pCex );
+if ( fVerbose )
+Abc_CexPrintStats( pCare );
+
+ return pCare;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of PIs for flops that should not be absracted.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManExtendCounterExampleTest3( Aig_Man_t * pAig, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose )
+{
+ Saig_RefMan_t * p;
+ Vec_Int_t * vRes, * vReasons;
+ clock_t clk;
+ if ( Saig_ManPiNum(pAig) != pCex->nPis )
+ {
+ printf( "Saig_ManExtendCounterExampleTest3(): The PI count of AIG (%d) does not match that of cex (%d).\n",
+ Aig_ManCiNum(pAig), pCex->nPis );
+ return NULL;
+ }
+
+clk = clock();
+
+ p = Saig_RefManStart( pAig, pCex, iFirstFlopPi, fVerbose );
+ vReasons = Saig_RefManFindReason( p );
+ vRes = Saig_RefManReason2Inputs( p, vReasons );
+
+// if ( fVerbose )
+ {
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+ABC_PRT( "Time", clock() - clk );
+ }
+
+/*
+ ////////////////////////////////////
+ Vec_IntFree( vReasons );
+ vReasons = Saig_RefManRefineWithSat( p, vRes );
+ ////////////////////////////////////
+
+ // derive new result
+ Vec_IntFree( vRes );
+ vRes = Saig_RefManReason2Inputs( p, vReasons );
+// if ( fVerbose )
+ {
+ printf( "Frame PIs = %4d (essential = %4d) AIG PIs = %4d (essential = %4d) ",
+ Aig_ManCiNum(p->pFrames), Vec_IntSize(vReasons),
+ Saig_ManPiNum(p->pAig) - p->nInputs, Vec_IntSize(vRes) );
+ABC_PRT( "Time", clock() - clk );
+ }
+*/
+
+ Vec_IntFree( vReasons );
+ Saig_RefManStop( p );
+ return vRes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absOldSim.c b/src/proof/abs/absOldSim.c
new file mode 100644
index 00000000..e5c1e938
--- /dev/null
+++ b/src/proof/abs/absOldSim.c
@@ -0,0 +1,477 @@
+/**CFile****************************************************************
+
+ FileName [saigSimExt2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Sequential AIG package.]
+
+ Synopsis [Extending simulation trace to contain ternary values.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: saigSimExt2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define SAIG_ZER 1
+#define SAIG_ONE 2
+#define SAIG_UND 3
+
+static inline int Saig_ManSimInfoNot( int Value )
+{
+ if ( Value == SAIG_ZER )
+ return SAIG_ONE;
+ if ( Value == SAIG_ONE )
+ return SAIG_ZER;
+ return SAIG_UND;
+}
+
+static inline int Saig_ManSimInfoAnd( int Value0, int Value1 )
+{
+ if ( Value0 == SAIG_ZER || Value1 == SAIG_ZER )
+ return SAIG_ZER;
+ if ( Value0 == SAIG_ONE && Value1 == SAIG_ONE )
+ return SAIG_ONE;
+ return SAIG_UND;
+}
+
+static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
+{
+ 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 = (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));
+}
+
+
+
+#define SAIG_ZER_NEW 0 // 0 not visited
+#define SAIG_ONE_NEW 1 // 1 not visited
+#define SAIG_ZER_OLD 2 // 0 visited
+#define SAIG_ONE_OLD 3 // 1 visited
+
+static inline int Saig_ManSimInfo2IsOld( int Value )
+{
+ return Value == SAIG_ZER_OLD || Value == SAIG_ONE_OLD;
+}
+
+static inline int Saig_ManSimInfo2SetOld( int Value )
+{
+ if ( Value == SAIG_ZER_NEW )
+ return SAIG_ZER_OLD;
+ if ( Value == SAIG_ONE_NEW )
+ return SAIG_ONE_OLD;
+ assert( 0 );
+ return 0;
+}
+
+static inline int Saig_ManSimInfo2Not( int Value )
+{
+ if ( Value == SAIG_ZER_NEW )
+ return SAIG_ONE_NEW;
+ if ( Value == SAIG_ONE_NEW )
+ return SAIG_ZER_NEW;
+ if ( Value == SAIG_ZER_OLD )
+ return SAIG_ONE_OLD;
+ if ( Value == SAIG_ONE_OLD )
+ return SAIG_ZER_OLD;
+ assert( 0 );
+ return 0;
+}
+
+static inline int Saig_ManSimInfo2And( int Value0, int Value1 )
+{
+ if ( Value0 == SAIG_ZER_NEW || Value1 == SAIG_ZER_NEW )
+ return SAIG_ZER_NEW;
+ if ( Value0 == SAIG_ONE_NEW && Value1 == SAIG_ONE_NEW )
+ return SAIG_ONE_NEW;
+ assert( 0 );
+ return 0;
+}
+
+static inline int Saig_ManSimInfo2Get( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
+ return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1));
+}
+
+static inline void Saig_ManSimInfo2Set( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value )
+{
+ unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
+ Value ^= Saig_ManSimInfo2Get( vSimInfo, pObj, iFrame );
+ pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1));
+}
+
+// performs ternary simulation
+//extern int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs ternary simulation for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
+{
+ int Value0, Value1, Value;
+ Value0 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin0(pObj), iFrame );
+ if ( Aig_ObjFaninC0(pObj) )
+ Value0 = Saig_ManSimInfoNot( Value0 );
+ if ( Aig_ObjIsCo(pObj) )
+ {
+ Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 );
+ return Value0;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ Value1 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin1(pObj), iFrame );
+ if ( Aig_ObjFaninC1(pObj) )
+ Value1 = Saig_ManSimInfoNot( Value1 );
+ Value = Saig_ManSimInfoAnd( Value0, Value1 );
+ Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value );
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs ternary simulation for one design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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;
+ Saig_ManForEachLo( p, pObj, i )
+ Saig_ManSimInfoSet( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ Saig_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE );
+ Saig_ManForEachPi( p, pObj, i )
+ Saig_ManSimInfoSet( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER );
+ if ( vRes )
+ Vec_IntForEachEntry( vRes, Entry, i )
+ Saig_ManSimInfoSet( vSimInfo, Aig_ManCi(p, Entry), f, SAIG_UND );
+ Aig_ManForEachNode( p, pObj, i )
+ Saig_ManExtendOneEval( vSimInfo, pObj, f );
+ Aig_ManForEachCo( p, pObj, i )
+ Saig_ManExtendOneEval( vSimInfo, pObj, f );
+ if ( f == pCex->iFrame )
+ break;
+ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
+ Saig_ManSimInfoSet( vSimInfo, pObjLo, f+1, Saig_ManSimInfoGet(vSimInfo, pObjLi, f) );
+ }
+ // make sure the output of the property failed
+ pObj = Aig_ManCo( p, pCex->iPo );
+ return Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs ternary simulation for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManExtendOneEval2( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
+{
+ int Value0, Value1, Value;
+ Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pObj), iFrame );
+ if ( Aig_ObjFaninC0(pObj) )
+ Value0 = Saig_ManSimInfo2Not( Value0 );
+ if ( Aig_ObjIsCo(pObj) )
+ {
+ Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value0 );
+ return Value0;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pObj), iFrame );
+ if ( Aig_ObjFaninC1(pObj) )
+ Value1 = Saig_ManSimInfo2Not( Value1 );
+ Value = Saig_ManSimInfo2And( Value0, Value1 );
+ Saig_ManSimInfo2Set( vSimInfo, pObj, iFrame, Value );
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs sensitization analysis for one design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManSimDataInit2( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, f, iBit = 0;
+ Saig_ManForEachLo( p, pObj, i )
+ Saig_ManSimInfo2Set( vSimInfo, pObj, 0, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ Saig_ManSimInfo2Set( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE_NEW );
+ Saig_ManForEachPi( p, pObj, i )
+ Saig_ManSimInfo2Set( vSimInfo, pObj, f, Abc_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE_NEW:SAIG_ZER_NEW );
+ Aig_ManForEachNode( p, pObj, i )
+ Saig_ManExtendOneEval2( vSimInfo, pObj, f );
+ Aig_ManForEachCo( p, pObj, i )
+ Saig_ManExtendOneEval2( vSimInfo, pObj, f );
+ if ( f == pCex->iFrame )
+ break;
+ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
+ Saig_ManSimInfo2Set( vSimInfo, pObjLo, f+1, Saig_ManSimInfo2Get(vSimInfo, pObjLi, f) );
+ }
+ // make sure the output of the property failed
+ pObj = Aig_ManCo( p, pCex->iPo );
+ return Saig_ManSimInfo2Get( vSimInfo, pObj, pCex->iFrame );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Drive implications of the given node towards primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo )
+{
+ Aig_Obj_t * pFanout;
+ int k, iFanout = -1, Value0, Value1;
+ int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f );
+ assert( !Saig_ManSimInfo2IsOld( Value ) );
+ Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) );
+ if ( (Aig_ObjIsCo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) )
+ return;
+ if ( Saig_ObjIsLi( p, pObj ) )
+ {
+ assert( f < fMax );
+ pFanout = Saig_ObjLiToLo(p, pObj);
+ Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 );
+ if ( !Saig_ManSimInfo2IsOld( Value ) )
+ Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo );
+ return;
+ }
+ assert( Aig_ObjIsCi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) );
+ Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k )
+ {
+ Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f );
+ if ( Saig_ManSimInfo2IsOld( Value ) )
+ continue;
+ if ( Aig_ObjIsCo(pFanout) )
+ {
+ Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo );
+ continue;
+ }
+ assert( Aig_ObjIsNode(pFanout) );
+ Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f );
+ Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f );
+ if ( Aig_ObjFaninC0(pFanout) )
+ Value0 = Saig_ManSimInfo2Not( Value0 );
+ if ( Aig_ObjFaninC1(pFanout) )
+ Value1 = Saig_ManSimInfo2Not( Value1 );
+ if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD ||
+ (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) )
+ Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs recursive sensetization analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManExplorePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo )
+{
+ int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f );
+ if ( Saig_ManSimInfo2IsOld( Value ) )
+ return;
+ Saig_ManSetAndDriveImplications_rec( p, pObj, f, fMax, vSimInfo );
+ assert( !Aig_ObjIsConst1(pObj) );
+ if ( Saig_ObjIsLo(p, pObj) && f == 0 )
+ return;
+ if ( Saig_ObjIsPi(p, pObj) )
+ {
+ // propagate implications of this assignment
+ int i, iPiNum = Aig_ObjCioId(pObj);
+ for ( i = fMax; i >= 0; i-- )
+ if ( i != f )
+ Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, iPiNum), i, fMax, vSimInfo );
+ return;
+ }
+ if ( Saig_ObjIsLo( p, pObj ) )
+ {
+ assert( f > 0 );
+ Saig_ManExplorePaths_rec( p, Saig_ObjLoToLi(p, pObj), f-1, fMax, vSimInfo );
+ return;
+ }
+ if ( Aig_ObjIsCo(pObj) )
+ {
+ Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ if ( Value == SAIG_ZER_OLD )
+ {
+// if ( (Aig_ObjId(pObj) & 1) == 0 )
+ Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
+// else
+// Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo );
+ }
+ else
+ {
+ Saig_ManExplorePaths_rec( p, Aig_ObjFanin0(pObj), f, fMax, vSimInfo );
+ Saig_ManExplorePaths_rec( p, Aig_ObjFanin1(pObj), f, fMax, vSimInfo );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of PIs for flops that should not be absracted.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManProcessCex( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose )
+{
+ Aig_Obj_t * pObj;
+ Vec_Int_t * vRes, * vResInv;
+ int i, f, Value;
+// assert( Aig_ManRegNum(p) > 0 );
+ assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Abc_BitWordNum(2*(pCex->iFrame+1)) );
+ // start simulation data
+ Value = Saig_ManSimDataInit2( p, pCex, vSimInfo );
+ assert( Value == SAIG_ONE_NEW );
+ // derive implications of constants and primary inputs
+ Saig_ManForEachLo( p, pObj, i )
+ Saig_ManSetAndDriveImplications_rec( p, pObj, 0, pCex->iFrame, vSimInfo );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ {
+ Saig_ManSetAndDriveImplications_rec( p, Aig_ManConst1(p), f, pCex->iFrame, vSimInfo );
+ for ( i = 0; i < iFirstFlopPi; i++ )
+ Saig_ManSetAndDriveImplications_rec( p, Aig_ManCi(p, i), f, pCex->iFrame, vSimInfo );
+ }
+ // recursively compute justification
+ Saig_ManExplorePaths_rec( p, Aig_ManCo(p, pCex->iPo), pCex->iFrame, pCex->iFrame, vSimInfo );
+ // select the result
+ vRes = Vec_IntAlloc( 1000 );
+ vResInv = Vec_IntAlloc( 1000 );
+ for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ {
+ Value = Saig_ManSimInfo2Get( vSimInfo, Aig_ManCi(p, i), f );
+ if ( Saig_ManSimInfo2IsOld( Value ) )
+ break;
+ }
+ if ( f >= 0 )
+ Vec_IntPush( vRes, i );
+ else
+ Vec_IntPush( vResInv, i );
+ }
+ // 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_ManExtendCounterExampleTest2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose )
+{
+ Vec_Int_t * vRes;
+ Vec_Ptr_t * vSimInfo;
+ clock_t clk;
+ if ( Saig_ManPiNum(p) != pCex->nPis )
+ {
+ printf( "Saig_ManExtendCounterExampleTest2(): The PI count of AIG (%d) does not match that of cex (%d).\n",
+ Aig_ManCiNum(p), pCex->nPis );
+ return NULL;
+ }
+ Aig_ManFanoutStart( p );
+ vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Abc_BitWordNum(2*(pCex->iFrame+1)) );
+ Vec_PtrCleanSimInfo( vSimInfo, 0, Abc_BitWordNum(2*(pCex->iFrame+1)) );
+
+clk = clock();
+ vRes = Saig_ManProcessCex( p, iFirstFlopPi, pCex, vSimInfo, fVerbose );
+ if ( fVerbose )
+ {
+ printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstFlopPi, Vec_IntSize(vRes) );
+ABC_PRT( "Time", clock() - clk );
+ }
+ Vec_PtrFree( vSimInfo );
+ Aig_ManFanoutStop( p );
+ return vRes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absOut.c b/src/proof/abs/absOut.c
new file mode 100644
index 00000000..c230acb4
--- /dev/null
+++ b/src/proof/abs/absOut.c
@@ -0,0 +1,458 @@
+/**CFile****************************************************************
+
+ FileName [absOut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Abstraction refinement outside of abstraction engines.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absOut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derive a new counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gia_ManCexRemap( Gia_Man_t * p, Abc_Cex_t * pCexAbs, Vec_Int_t * vPis )
+{
+ Abc_Cex_t * pCex;
+ int i, f, iPiNum;
+ assert( pCexAbs->iPo == 0 );
+ // start the counter-example
+ pCex = Abc_CexAlloc( Gia_ManRegNum(p), Gia_ManPiNum(p), pCexAbs->iFrame+1 );
+ pCex->iFrame = pCexAbs->iFrame;
+ pCex->iPo = pCexAbs->iPo;
+ // copy the bit data
+ for ( f = 0; f <= pCexAbs->iFrame; f++ )
+ for ( i = 0; i < Vec_IntSize(vPis); i++ )
+ {
+ if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) )
+ {
+ iPiNum = Gia_ObjCioId( Gia_ManObj(p, Vec_IntEntry(vPis, i)) );
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + iPiNum );
+ }
+ }
+ // verify the counter example
+ if ( !Gia_ManVerifyCex( p, pCex, 0 ) )
+ {
+ Abc_Print( 1, "Gia_ManCexRemap(): Counter-example is invalid.\n" );
+ Abc_CexFree( pCex );
+ pCex = NULL;
+ }
+ else
+ {
+ Abc_Print( 1, "Counter-example verification is successful.\n" );
+ Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame );
+ }
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines gate-level abstraction using the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManGlaRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int fMinCut, int fVerbose )
+{
+ extern void Nwk_ManDeriveMinCut( Gia_Man_t * p, int fVerbose );
+ int fAddOneLayer = 1;
+ Abc_Cex_t * pCexNew = NULL;
+ Gia_Man_t * pAbs;
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCare;
+ Vec_Int_t * vPis, * vPPis;
+ int f, i, iObjId;
+ clock_t clk = clock();
+ int nOnes = 0, Counter = 0;
+ if ( p->vGateClasses == NULL )
+ {
+ Abc_Print( 1, "Gia_ManGlaRefine(): Abstraction gate map is missing.\n" );
+ return -1;
+ }
+ // derive abstraction
+ pAbs = Gia_ManDupAbsGates( p, p->vGateClasses );
+ Gia_ManStop( pAbs );
+ pAbs = Gia_ManDupAbsGates( p, p->vGateClasses );
+ if ( Gia_ManPiNum(pAbs) != pCex->nPis )
+ {
+ Abc_Print( 1, "Gia_ManGlaRefine(): The PI counts in GLA and in CEX do not match.\n" );
+ Gia_ManStop( pAbs );
+ return -1;
+ }
+ if ( !Gia_ManVerifyCex( pAbs, pCex, 0 ) )
+ {
+ Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is invalid.\n" );
+// Gia_ManStop( pAbs );
+// return -1;
+ }
+// else
+// Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is correct.\n" );
+ // get inputs
+ Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, NULL, NULL );
+ assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) );
+ // add missing logic
+ if ( fAddOneLayer )
+ {
+ Gia_Obj_t * pObj;
+ // check if this is a real counter-example
+ Gia_ObjTerSimSet0( Gia_ManConst0(pAbs) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ {
+ Gia_ManForEachPi( pAbs, pObj, i )
+ {
+ if ( i >= Vec_IntSize(vPis) ) // PPIs
+ Gia_ObjTerSimSetX( pObj );
+ else if ( Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachRo( pAbs, pObj, i )
+ {
+ if ( f == 0 )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimRo( pAbs, pObj );
+ }
+ Gia_ManForEachAnd( pAbs, pObj, i )
+ Gia_ObjTerSimAnd( pObj );
+ Gia_ManForEachCo( pAbs, pObj, i )
+ Gia_ObjTerSimCo( pObj );
+ }
+ pObj = Gia_ManPo( pAbs, 0 );
+ if ( Gia_ObjTerSimGet1(pObj) )
+ {
+ pCexNew = Gia_ManCexRemap( p, pCex, vPis );
+ Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame );
+ }
+// else
+// Abc_Print( 1, "CEX is not real.\n" );
+ Gia_ManForEachObj( pAbs, pObj, i )
+ Gia_ObjTerSimSetC( pObj );
+ if ( pCexNew == NULL )
+ {
+ // grow one layer
+ Vec_IntForEachEntry( vPPis, iObjId, i )
+ {
+ assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 );
+ Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 );
+ }
+ if ( fVerbose )
+ {
+ Abc_Print( 1, "Additional objects = %d. ", Vec_IntSize(vPPis) );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ }
+ }
+ else
+ {
+ // minimize the CEX
+ pAig = Gia_ManToAigSimple( pAbs );
+ pCare = Saig_ManCbaFindCexCareBits( pAig, pCex, Vec_IntSize(vPis), fVerbose );
+ Aig_ManStop( pAig );
+ if ( pCare == NULL )
+ Abc_Print( 1, "Counter-example minimization has failed.\n" );
+ // add new objects to the map
+ iObjId = -1;
+ for ( f = 0; f <= pCare->iFrame; f++ )
+ for ( i = 0; i < pCare->nPis; i++ )
+ if ( Abc_InfoHasBit( pCare->pData, pCare->nRegs + f * pCare->nPis + i ) )
+ {
+ nOnes++;
+ assert( i >= Vec_IntSize(vPis) );
+ iObjId = Vec_IntEntry( vPPis, i - Vec_IntSize(vPis) );
+ assert( iObjId > 0 && iObjId < Gia_ManObjNum(p) );
+ if ( Vec_IntEntry( p->vGateClasses, iObjId ) > 0 )
+ continue;
+ assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 );
+ Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 );
+ // Abc_Print( 1, "Adding object %d.\n", iObjId );
+ // Gia_ObjPrint( p, Gia_ManObj(p, iObjId) );
+ Counter++;
+ }
+ Abc_CexFree( pCare );
+ if ( fVerbose )
+ {
+ Abc_Print( 1, "Essential bits = %d. Additional objects = %d. ", nOnes, Counter );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ // consider the case of SAT
+ if ( iObjId == -1 )
+ {
+ pCexNew = Gia_ManCexRemap( p, pCex, vPis );
+ Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame );
+ }
+ }
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPPis );
+ Gia_ManStop( pAbs );
+ if ( pCexNew )
+ {
+ ABC_FREE( p->pCexSeq );
+ p->pCexSeq = pCexNew;
+ return 0;
+ }
+ // extract abstraction to include min-cut
+ if ( fMinCut )
+ Nwk_ManDeriveMinCut( p, fVerbose );
+ return -1;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the counter-example and returns flop values.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManGetStateAndCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame )
+{
+ Vec_Int_t * vInit = Vec_IntAlloc( Gia_ManRegNum(pAig) );
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ int RetValue, i, k, iBit = 0;
+ assert( iFrame >= 0 && iFrame <= p->iFrame );
+ Gia_ManCleanMark0(pAig);
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++);
+ for ( i = 0, iBit = p->nRegs; i <= p->iFrame; i++ )
+ {
+ if ( i == iFrame )
+ {
+ Gia_ManForEachRo( pAig, pObjRo, k )
+ Vec_IntPush( vInit, pObjRo->fMark0 );
+ }
+ Gia_ManForEachPi( pAig, pObj, k )
+ pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++);
+ Gia_ManForEachAnd( pAig, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( pAig, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ if ( i == p->iFrame )
+ break;
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k )
+ pObjRo->fMark0 = pObjRi->fMark0;
+ }
+ assert( iBit == p->nBits );
+ RetValue = Gia_ManPo(pAig, p->iPo)->fMark0;
+ if ( RetValue != 1 )
+ Vec_IntFreeP( &vInit );
+ Gia_ManCleanMark0(pAig);
+ return vInit;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example starting in the given timeframe.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame )
+{
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ int RetValue, i, k, iBit = 0;
+ assert( iFrame >= 0 && iFrame <= p->iFrame );
+ Gia_ManCleanMark0(pAig);
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++);
+ for ( i = iFrame, iBit += p->nRegs + Gia_ManPiNum(pAig) * iFrame; i <= p->iFrame; i++ )
+ {
+ Gia_ManForEachPi( pAig, pObj, k )
+ pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++);
+ Gia_ManForEachAnd( pAig, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( pAig, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ if ( i == p->iFrame )
+ break;
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k )
+ pObjRo->fMark0 = pObjRi->fMark0;
+ }
+ assert( iBit == p->nBits );
+ RetValue = Gia_ManPo(pAig, p->iPo)->fMark0;
+ Gia_ManCleanMark0(pAig);
+ if ( RetValue == 1 )
+ printf( "Shortened CEX holds for the abstraction of the fast-forwarded model.\n" );
+ else
+ printf( "Shortened CEX does not hold for the abstraction of the fast-forwarded model.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManTransformFlops( Gia_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vInit )
+{
+ Vec_Bit_t * vInitNew;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i, iFlopId;
+ assert( Vec_IntSize(vInit) == Vec_IntSize(vFlops) );
+ vInitNew = Vec_BitStart( Gia_ManRegNum(p) );
+ Gia_ManForEachObjVec( vFlops, p, pObj, i )
+ {
+ assert( Gia_ObjIsRo(p, pObj) );
+ if ( Vec_IntEntry(vInit, i) == 0 )
+ continue;
+ iFlopId = Gia_ObjCioId(pObj) - Gia_ManPiNum(p);
+ assert( iFlopId >= 0 && iFlopId < Gia_ManRegNum(p) );
+ Vec_BitWriteEntry( vInitNew, iFlopId, 1 );
+ }
+ pNew = Gia_ManDupFlip( p, Vec_BitArray(vInitNew) );
+ Vec_BitFree( vInitNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManNewRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrameStart, int iFrameExtra, int fVerbose )
+{
+ Gia_Man_t * pAbs, * pNew;
+ Vec_Int_t * vFlops, * vInit;
+ Vec_Int_t * vCopy;
+// clock_t clk = clock();
+ int RetValue;
+ ABC_FREE( p->pCexSeq );
+ if ( p->vGateClasses == NULL )
+ {
+ Abc_Print( 1, "Gia_ManNewRefine(): Abstraction gate map is missing.\n" );
+ return -1;
+ }
+ vCopy = Vec_IntDup( p->vGateClasses );
+ Abc_Print( 1, "Refining with %d-frame CEX, starting in frame %d, with %d extra frames.\n", pCex->iFrame, iFrameStart, iFrameExtra );
+ // derive abstraction
+ pAbs = Gia_ManDupAbsGates( p, p->vGateClasses );
+ Gia_ManStop( pAbs );
+ pAbs = Gia_ManDupAbsGates( p, p->vGateClasses );
+ if ( Gia_ManPiNum(pAbs) != pCex->nPis )
+ {
+ Abc_Print( 1, "Gia_ManNewRefine(): The PI counts in GLA and in CEX do not match.\n" );
+ Gia_ManStop( pAbs );
+ Vec_IntFree( vCopy );
+ return -1;
+ }
+ // get the state in frame iFrameStart
+ vInit = Gia_ManGetStateAndCheckCex( pAbs, pCex, iFrameStart );
+ if ( vInit == NULL )
+ {
+ Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is invalid.\n" );
+ Gia_ManStop( pAbs );
+ Vec_IntFree( vCopy );
+ return -1;
+ }
+ if ( fVerbose )
+ Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is correct.\n" );
+ // get inputs
+ Gia_ManGlaCollect( p, p->vGateClasses, NULL, NULL, &vFlops, NULL );
+// assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) );
+ Gia_ManStop( pAbs );
+//Vec_IntPrint( vFlops );
+//Vec_IntPrint( vInit );
+ // transform the manager to have new init state
+ pNew = Gia_ManTransformFlops( p, vFlops, vInit );
+ Vec_IntFree( vFlops );
+ Vec_IntFree( vInit );
+ // verify abstraction
+ {
+ Gia_Man_t * pAbs = Gia_ManDupAbsGates( pNew, p->vGateClasses );
+ Gia_ManCheckCex( pAbs, pCex, iFrameStart );
+ Gia_ManStop( pAbs );
+ }
+ // transfer abstraction
+ assert( pNew->vGateClasses == NULL );
+ pNew->vGateClasses = Vec_IntDup( p->vGateClasses );
+ // perform abstraction for the new AIG
+ {
+ Abs_Par_t Pars, * pPars = &Pars;
+ Abs_ParSetDefaults( pPars );
+ pPars->nFramesMax = pCex->iFrame - iFrameStart + 1 + iFrameExtra;
+ pPars->fVerbose = fVerbose;
+ RetValue = Gia_ManPerformGla( pNew, pPars );
+ if ( RetValue == 0 ) // spurious SAT
+ {
+ Vec_IntFreeP( &pNew->vGateClasses );
+ pNew->vGateClasses = Vec_IntDup( vCopy );
+ }
+ }
+ // move the abstraction map
+ Vec_IntFreeP( &p->vGateClasses );
+ p->vGateClasses = pNew->vGateClasses;
+ pNew->vGateClasses = NULL;
+ // cleanup
+ Gia_ManStop( pNew );
+ Vec_IntFree( vCopy );
+ return -1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absPth.c b/src/proof/abs/absPth.c
new file mode 100644
index 00000000..73f76822
--- /dev/null
+++ b/src/proof/abs/absPth.c
@@ -0,0 +1,199 @@
+/**CFile****************************************************************
+
+ FileName [absPth.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Interface to pthreads.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absPth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/ioa/ioa.h"
+#include "proof/pdr/pdr.h"
+
+// uncomment this line to enable pthreads
+//#define ABC_USE_PTHREADS
+
+// to compile on Linux, modify Makefile as follows:
+// add -pthread to OPTFLAGS
+// add -lpthread to LIBS
+
+#ifdef ABC_USE_PTHREADS
+
+#ifdef WIN32
+#include "../lib/pthread.h"
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifndef ABC_USE_PTHREADS
+
+void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose ) {}
+void Gia_Ga2ProveCancel( int fVerbose ) {}
+int Gia_Ga2ProveCheck( int fVerbose ) { return 0; }
+
+#else // pthreads are used
+
+// information given to the thread
+typedef struct Abs_ThData_t_
+{
+ char * pFileName;
+ int fVerbose;
+ int RunId;
+} Abs_ThData_t;
+
+// mutext to control access to shared variables
+pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+static volatile int g_nRunIds = 0; // the number of the last prover instance
+static volatile int g_fAbstractionProved = 0; // set to 1 when prover successed to prove
+
+// call back procedure for PDR
+int Abs_CallBackToStop( int RunId ) { assert( RunId <= g_nRunIds ); return RunId < g_nRunIds; }
+
+// test procedure to replace PDR
+int Pdr_ManSolve_test( Aig_Man_t * pAig, Pdr_Par_t * pPars, Abc_Cex_t ** ppCex )
+{
+ char * p = ABC_ALLOC( char, 111 );
+ while ( 1 )
+ {
+ if ( pPars->pFuncStop && pPars->pFuncStop(pPars->RunId) )
+ break;
+ }
+ ABC_FREE( p );
+ return -1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Create one thread]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abs_ProverThread( void * pArg )
+{
+ Abs_ThData_t * pThData = (Abs_ThData_t *)pArg;
+ Pdr_Par_t Pars, * pPars = &Pars;
+ Aig_Man_t * pAig, * pTemp;
+ int RetValue, status;
+ pAig = Ioa_ReadAiger( pThData->pFileName, 0 );
+ if ( pAig == NULL )
+ Abc_Print( 1, "\nCannot open file \"%s\".\n", pThData->pFileName );
+ else
+ {
+ // synthesize abstraction
+ pAig = Aig_ManScl( pTemp = pAig, 1, 1, 0, -1, -1, 0, 0 );
+ Aig_ManStop( pTemp );
+ // call PDR
+ Pdr_ManSetDefaultParams( pPars );
+ pPars->fSilent = 1;
+ pPars->RunId = pThData->RunId;
+ pPars->pFuncStop = Abs_CallBackToStop;
+ RetValue = Pdr_ManSolve( pAig, pPars, NULL );
+// RetValue = Pdr_ManSolve_test( pAig, pPars, NULL );
+ // update the result
+ if ( RetValue == 1 )
+ {
+ status = pthread_mutex_lock(&g_mutex); assert( status == 0 );
+ g_fAbstractionProved = 1;
+ status = pthread_mutex_unlock(&g_mutex); assert( status == 0 );
+ }
+ // free memory
+ Aig_ManStop( pAig );
+ // quit this thread
+ if ( pThData->fVerbose )
+ {
+ if ( RetValue == 1 )
+ Abc_Print( 1, "\nProved abstraction %d.\n", pThData->RunId );
+ else if ( RetValue == 0 )
+ Abc_Print( 1, "\nDisproved abstraction %d.\n", pThData->RunId );
+ else if ( RetValue == -1 )
+ Abc_Print( 1, "\nCancelled abstraction %d.\n", pThData->RunId );
+ else assert( 0 );
+ }
+ }
+ ABC_FREE( pThData->pFileName );
+ ABC_FREE( pThData );
+ // quit this thread
+ pthread_exit( NULL );
+ assert(0);
+ return NULL;
+}
+void Gia_Ga2ProveAbsracted( char * pFileName, int fVerbose )
+{
+ Abs_ThData_t * pThData;
+ pthread_t ProverThread;
+ int status;
+ assert( pFileName != NULL );
+ // disable verbosity
+ fVerbose = 0;
+ // reset the proof
+ status = pthread_mutex_lock(&g_mutex); assert( status == 0 );
+ g_fAbstractionProved = 0;
+ status = pthread_mutex_unlock(&g_mutex); assert( status == 0 );
+ // collect thread data
+ pThData = ABC_CALLOC( Abs_ThData_t, 1 );
+ pThData->pFileName = Abc_UtilStrsav( (void *)pFileName );
+ pThData->fVerbose = fVerbose;
+ status = pthread_mutex_lock(&g_mutex); assert( status == 0 );
+ pThData->RunId = ++g_nRunIds;
+ status = pthread_mutex_unlock(&g_mutex); assert( status == 0 );
+ // create thread
+ if ( fVerbose ) Abc_Print( 1, "\nTrying to prove abstraction %d.\n", pThData->RunId );
+ status = pthread_create( &ProverThread, NULL, Abs_ProverThread, pThData );
+ assert( status == 0 );
+}
+void Gia_Ga2ProveCancel( int fVerbose )
+{
+ int status;
+ status = pthread_mutex_lock(&g_mutex); assert( status == 0 );
+ g_nRunIds++;
+ status = pthread_mutex_unlock(&g_mutex); assert( status == 0 );
+}
+int Gia_Ga2ProveCheck( int fVerbose )
+{
+ int status;
+ if ( g_fAbstractionProved == 0 )
+ return 0;
+ status = pthread_mutex_lock(&g_mutex); assert( status == 0 );
+ g_fAbstractionProved = 0;
+ status = pthread_mutex_unlock(&g_mutex); assert( status == 0 );
+ return 1;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absRef.c b/src/proof/abs/absRef.c
new file mode 100644
index 00000000..3aea96ee
--- /dev/null
+++ b/src/proof/abs/absRef.c
@@ -0,0 +1,1001 @@
+/**CFile****************************************************************
+
+ FileName [absRef.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Refinement manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sat/bsat/satSolver2.h"
+#include "abs.h"
+#include "absRef.h"
+
+ABC_NAMESPACE_IMPL_START
+
+/*
+ Description of the refinement manager
+
+ This refinement manager should be
+ * started by calling Rnm_ManStart()
+ this procedure takes one argument, the user's seq miter as a GIA manager
+ - the manager should have only one property output
+ - this manager should not change while the refinement manager is alive
+ - it cannot be used by external applications for any purpose
+ - when the refinement manager stop, GIA manager is the same as at the beginning
+ - in the meantime, it will have some data-structures attached to its nodes...
+ * stopped by calling Rnm_ManStop()
+ * between starting and stopping, refinements are obtained by calling Rnm_ManRefine()
+
+ Procedure Rnm_ManRefine() takes the following arguments:
+ * the refinement manager previously started by Rnm_ManStart()
+ * counter-example (CEX) obtained by abstracting some logic of GIA
+ * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager
+ - only PI, flop outputs, and internal AND nodes can be used in vMap
+ - the ordering of objects in vMap is not important
+ - however, the index of a non-PI object in vMap is used as its priority
+ (the smaller the index, the more likely this non-PI object apears in a refinement)
+ - only the logic between PO and the objects listed in vMap is traversed by the manager
+ (as a result, GIA can be arbitrarily large, but only objects used in the abstraction
+ and the pseudo-PI, that is, objects in the cut, will be visited by the manager)
+ * flag fPropFanout defines whether value propagation is done through the fanout
+ - it this flag is enabled, theoretically refinement should be better (the result smaller)
+ * flag fVerbose may print some statistics
+
+ The refinement manager returns a minimal-size array of integer IDs of GIA objects
+ which should be added to the abstraction to possibly prevent the given counter-example
+ - only flop output and internal AND nodes from vMap may appear in the resulting array
+ - if the resulting array is empty, the CEX is a true CEX
+ (in other words, non-PI objects are not needed to set the PO value to 1)
+
+ Verification of the selected refinement is performed by
+ - initializing all PI objects in vMap to value 0 or 1 they have in the CEX
+ - initializing all remaining objects in vMap to value X
+ - initializing objects used in the refiment to value 0 or 1 they have in the CEX
+ - simulating through as many timeframes as required by the CEX
+ - if the PO value in the last frame is 1, the refinement is correct
+ (however, the minimality of the refinement is not currently checked)
+
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Rnm_Obj_t_ Rnm_Obj_t; // refinement object
+struct Rnm_Obj_t_
+{
+ unsigned Value : 1; // binary value
+ unsigned fVisit : 1; // visited object
+ unsigned fVisit0 : 1; // visited object
+ unsigned fPPi : 1; // PPI object
+ unsigned Prio : 24; // priority (0 - highest)
+};
+
+struct Rnm_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package)
+ Abc_Cex_t * pCex; // counter-example
+ Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order)
+ int fPropFanout; // propagate fanouts
+ int fVerbose; // verbose flag
+ // traversing data
+ Vec_Int_t * vObjs; // internal objects used in value propagation
+ Vec_Str_t * vCounts; // fanin counters
+ Vec_Int_t * vFanins; // fanins
+ // SAT solver
+ sat_solver2 * pSat; // incremental SAT solver
+ Vec_Int_t * vSatVars; // SAT variables
+ Vec_Int_t * vSat2Ids; // mapping of SAT variables into object IDs
+ Vec_Int_t * vIsopMem; // memory for ISOP computation
+ // internal data
+ Rnm_Obj_t * pObjs; // refinement objects
+ int nObjs; // the number of used objects
+ int nObjsAlloc; // the number of allocated objects
+ int nObjsFrame; // the number of used objects in each frame
+ int nCalls; // total number of calls
+ int nRefines; // total refined objects
+ int nVisited; // visited during justification
+ // statistics
+ clock_t timeFwd; // forward propagation
+ clock_t timeBwd; // backward propagation
+ clock_t timeVer; // ternary simulation
+ clock_t timeTotal; // other time
+};
+
+// accessing the refinement object
+static inline Rnm_Obj_t * Rnm_ManObj( Rnm_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+ assert( Gia_ObjIsConst0(pObj) || pObj->Value );
+ assert( (int)pObj->Value < p->nObjsFrame );
+ assert( f >= 0 && f <= p->pCex->iFrame );
+ return p->pObjs + f * p->nObjsFrame + pObj->Value;
+}
+
+static inline int Ga2_ObjOffset( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Gia_ObjId(p, pObj)); }
+static inline int Ga2_ObjLeaveNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj)); }
+static inline int * Ga2_ObjLeavePtr( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntryP(p->vMapping, Ga2_ObjOffset(p, pObj) + 1); }
+static inline unsigned Ga2_ObjTruth( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 1); }
+static inline int Ga2_ObjRefNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (unsigned)Vec_IntEntry(p->vMapping, Ga2_ObjOffset(p, pObj) + Ga2_ObjLeaveNum(p, pObj) + 2); }
+static inline Vec_Int_t * Ga2_ObjLeaves( Gia_Man_t * p, Gia_Obj_t * pObj ) { static Vec_Int_t v; v.nSize = Ga2_ObjLeaveNum(p, pObj), v.pArray = Ga2_ObjLeavePtr(p, pObj); return &v; }
+
+static inline int Rnm_ObjCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_StrEntry( p->vCounts, Gia_ObjId(p->pGia, pObj) ); }
+static inline void Rnm_ObjSetCount( Rnm_Man_t * p, Gia_Obj_t * pObj, int c ) { Vec_StrWriteEntry( p->vCounts, Gia_ObjId(p->pGia, pObj), (char)c ); }
+static inline int Rnm_ObjAddToCount( Rnm_Man_t * p, Gia_Obj_t * pObj ) { int c = Rnm_ObjCount(p, pObj); if ( c < 16 ) Rnm_ObjSetCount(p, pObj, c+1); return c; }
+
+static inline int Rnm_ObjSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj) ); }
+static inline void Rnm_ObjSetSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj, int c) { Vec_IntWriteEntry( p->vSatVars, Gia_ObjId(p->pGia, pObj), c ); }
+static inline int Rnm_ObjFindOrAddSatVar( Rnm_Man_t * p, Gia_Obj_t * pObj) { if ( Rnm_ObjSatVar(p, pObj) == 0 ) { Rnm_ObjSetSatVar(p, pObj, Vec_IntSize(p->vSat2Ids)); Vec_IntPush(p->vSat2Ids, Gia_ObjId(p->pGia, pObj)); }; return 2*Rnm_ObjSatVar(p, pObj); }
+
+extern void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int * pLits, int iLitOut, int ProofId );
+
+extern Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs UNSAT-core-based refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rnm_ManRefineCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisited, Vec_Int_t * vFlops )
+{
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pFanin;
+ int k;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ if ( Gia_ObjIsRo(p, pObj) )
+ Vec_IntPush( vFlops, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ vLeaves = Ga2_ObjLeaves( p, pObj );
+ Gia_ManForEachObjVec( vLeaves, p, pFanin, k )
+ Rnm_ManRefineCollect_rec( p, pFanin, vVisited, vFlops );
+ Vec_IntPush( vVisited, Gia_ObjId(p, pObj) );
+}
+
+Vec_Int_t * Rnm_ManRefineUnsatCore( Rnm_Man_t * p, Vec_Int_t * vPPIs )
+{
+ Vec_Int_t * vCnf0, * vCnf1;
+ Vec_Int_t * vLeaves, * vLits, * vPpi2Map;
+ Vec_Int_t * vVisited, * vFlops, * vCore, * vCoreFinal;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, f, Status, Entry, pLits[5], iBit = p->pCex->nRegs;
+ // map PPIs into their positions in the map // CAN BE MADE FASTER
+ vPpi2Map = Vec_IntAlloc( Vec_IntSize(vPPIs) );
+ Vec_IntForEachEntry( vPPIs, Entry, i )
+ {
+ Entry = Vec_IntFind( p->vMap, Entry );
+ assert( Entry >= 0 );
+ Vec_IntPush( vPpi2Map, Entry );
+ }
+ // collect nodes between selected PPIs and CIs
+ vFlops = Vec_IntAlloc( 100 );
+ vVisited = Vec_IntAlloc( 100 );
+ Gia_ManIncrementTravId( p->pGia );
+ Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i )
+// if ( !Gia_ObjIsRo(p->pGia, pObj) ) // SKIP PPIs that are flops
+ Rnm_ManRefineCollect_rec( p->pGia, pObj, vVisited, vFlops );
+ // create SAT variables and SAT solver
+ Vec_IntFill( p->vSat2Ids, 1, -1 );
+ assert( p->pSat == NULL );
+ p->pSat = sat_solver2_new();
+ Vec_IntFill( p->vSatVars, Gia_ManObjNum(p->pGia), 0 ); // NO NEED TO CLEAN EACH TIME
+ // assign PPI variables
+ Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i )
+ Rnm_ObjFindOrAddSatVar( p, pObj );
+ // assign other variables
+ Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i )
+ {
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ pLits[k] = Rnm_ObjFindOrAddSatVar( p, pFanin );
+ vCnf0 = Ga2_ManCnfCompute( Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem );
+ vCnf1 = Ga2_ManCnfCompute( ~Ga2_ObjTruth(p->pGia, pObj), Vec_IntSize(vLeaves), p->vIsopMem );
+ Ga2_ManCnfAddStatic( p->pSat, vCnf0, vCnf1, pLits, Rnm_ObjFindOrAddSatVar(p, pObj), Rnm_ObjFindOrAddSatVar(p, pObj)/2 );
+ Vec_IntFree( vCnf0 );
+ Vec_IntFree( vCnf1 );
+ }
+
+// printf( "\n" );
+
+ p->pSat->pPrf2 = Prf_ManAlloc();
+ Prf_ManRestart( p->pSat->pPrf2, NULL, sat_solver2_nlearnts(p->pSat), Vec_IntSize(p->vSat2Ids) );
+
+ // iterate UNSAT core computation for each timeframe
+ vLits = Vec_IntAlloc( 100 );
+ vCoreFinal = Vec_IntAlloc( 100 );
+ for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis )
+ {
+ // collect values of PPIs in this timeframe
+ Vec_IntClear( vLits );
+ Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i )
+ {
+ Entry = Abc_InfoHasBit( p->pCex->pData, iBit + Vec_IntEntry(vPpi2Map, i) );
+ Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), !Entry ) );
+ }
+
+ // handle the first timeframe in a special vay
+ if ( f == 0 )
+ Gia_ManForEachObjVec( vFlops, p->pGia, pObj, i )
+ if ( Vec_IntFind( vPPIs, Gia_ObjId(p->pGia, pObj) ) == -1 )
+ Vec_IntPush( vLits, Abc_LitNotCond( Rnm_ObjFindOrAddSatVar(p, pObj), 1 ) );
+/*
+ // uniqify literals and detect special conflicts
+ Vec_IntUniqify( vLits );
+ Vec_IntForEachEntryStart( vLits, Entry, i, 1 )
+ if ( Vec_IntEntry(vLits, i-1) == Abc_LitNot(Entry) )
+ break;
+ if ( i < Vec_IntSize(vLits) )
+ printf( "triv_unsat " );
+ else
+*/
+
+ Status = sat_solver2_solve( p->pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( Status != l_False )
+ continue;
+ vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat );
+// vCore = Vec_IntAlloc( 0 );
+ // add to the UNSAT core
+ Vec_IntAppend( vCoreFinal, vCore );
+
+// printf( "Frame %d : ", f );
+// Vec_IntPrint( vCore );
+ Vec_IntFree( vCore );
+ }
+ assert( iBit == p->pCex->nBits );
+ Vec_IntUniqify( vCoreFinal );
+ Vec_IntFree( vLits );
+ Prf_ManStopP( &p->pSat->pPrf2 );
+ sat_solver2_delete( p->pSat );
+ p->pSat = NULL;
+
+ // translate from entry into ID
+ Vec_IntForEachEntry( vCoreFinal, Entry, i )
+ {
+ assert( Vec_IntEntry(p->vSat2Ids, Entry) >= 0 );
+ assert( Vec_IntEntry(p->vSat2Ids, Entry) < Gia_ManObjNum(p->pGia) );
+ Vec_IntWriteEntry( vCoreFinal, i, Vec_IntEntry(p->vSat2Ids, Entry) );
+ }
+ // if there are flop outputs, add them
+ Gia_ManForEachObjVec( vPPIs, p->pGia, pObj, i )
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ Vec_IntPush( vCoreFinal, Gia_ObjId(p->pGia, pObj) );
+ Vec_IntUniqify( vCoreFinal );
+
+// printf( "\n" );
+// Vec_IntPrint( vPPIs );
+// Vec_IntPrint( vCoreFinal );
+
+// printf( "\n" );
+
+ // clean SAT variable numbers
+ Gia_ManForEachObjVec( vVisited, p->pGia, pObj, i )
+ {
+ Rnm_ObjSetSatVar( p, pObj, 0 );
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ Rnm_ObjSetSatVar( p, pFanin, 0 );
+ }
+ Vec_IntFree( vFlops );
+ Vec_IntFree( vVisited );
+ Vec_IntFree( vPpi2Map );
+ return vCoreFinal;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia )
+{
+ Rnm_Man_t * p;
+ assert( Gia_ManPoNum(pGia) == 1 );
+ p = ABC_CALLOC( Rnm_Man_t, 1 );
+ p->pGia = pGia;
+ p->vObjs = Vec_IntAlloc( 100 );
+ p->vCounts = Vec_StrStart( Gia_ManObjNum(pGia) );
+ p->vFanins = Vec_IntAlloc( 1000 );
+ p->vSatVars = Vec_IntAlloc( 0 );
+ p->vSat2Ids = Vec_IntAlloc( 1000 );
+ p->vIsopMem = Vec_IntAlloc( 0 );
+ p->nObjsAlloc = 10000;
+ p->pObjs = ABC_ALLOC( Rnm_Obj_t, p->nObjsAlloc );
+ if ( p->pGia->vFanout == NULL )
+ Gia_ManStaticFanoutStart( p->pGia );
+ Gia_ManCleanValue(pGia);
+ Gia_ManCleanMark0(pGia);
+ Gia_ManCleanMark1(pGia);
+ return p;
+}
+void Rnm_ManStop( Rnm_Man_t * p, int fProfile )
+{
+ if ( !p ) return;
+ // print runtime statistics
+ if ( fProfile && p->nCalls )
+ {
+ double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc;
+ double MemOther = sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs);
+ clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer;
+ printf( "Abstraction refinement runtime statistics:\n" );
+ ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal );
+ ABC_PRTP( "Justification", p->timeBwd, p->timeTotal );
+ ABC_PRTP( "Verification ", p->timeVer, p->timeTotal );
+ ABC_PRTP( "Other ", timeOther, p->timeTotal );
+ ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
+ printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n",
+ p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) );
+ }
+
+ Gia_ManCleanMark0(p->pGia);
+ Gia_ManCleanMark1(p->pGia);
+ Gia_ManStaticFanoutStop(p->pGia);
+// Gia_ManSetPhase(p->pGia);
+ Vec_IntFree( p->vIsopMem );
+ Vec_IntFree( p->vSatVars );
+ Vec_IntFree( p->vSat2Ids );
+ Vec_StrFree( p->vCounts );
+ Vec_IntFree( p->vFanins );
+ Vec_IntFree( p->vObjs );
+ ABC_FREE( p->pObjs );
+ ABC_FREE( p );
+}
+double Rnm_ManMemoryUsage( Rnm_Man_t * p )
+{
+ return (double)(sizeof(Rnm_Man_t) + sizeof(Rnm_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs));
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect internal objects to be used in value propagation.]
+
+ Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rnm_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs, int nAddOn )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCo(pObj) )
+ Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Rnm_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs, nAddOn );
+ Rnm_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs, nAddOn );
+ }
+ else if ( !Gia_ObjIsRo(p, pObj) )
+ assert( 0 );
+ pObj->Value = Vec_IntSize(vObjs) + nAddOn;
+ Vec_IntPush( vObjs, Gia_ObjId(p, pObj) );
+}
+void Rnm_ManCollect( Rnm_Man_t * p )
+{
+ Gia_Obj_t * pObj = NULL;
+ int i;
+ // mark const/PIs/PPIs
+ Gia_ManIncrementTravId( p->pGia );
+ Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) );
+ Gia_ManConst0(p->pGia)->Value = 0;
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ Gia_ObjSetTravIdCurrent( p->pGia, pObj );
+ pObj->Value = 1 + i;
+ }
+ // collect objects
+ Vec_IntClear( p->vObjs );
+ Rnm_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs, 1 + Vec_IntSize(p->vMap) );
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ Rnm_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs, 1 + Vec_IntSize(p->vMap) );
+ // the last object should be a CO
+ assert( Gia_ObjIsCo(pObj) );
+ assert( (int)pObj->Value == Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) );
+}
+void Rnm_ManCleanValues( Rnm_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ pObj->Value = 0;
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ pObj->Value = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs sensitization analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rnm_ManSensitize( Rnm_Man_t * p )
+{
+ Rnm_Obj_t * pRnm, * pRnm0, * pRnm1;
+ Gia_Obj_t * pObj;
+ int f, i, iBit = p->pCex->nRegs;
+ // const0 is initialized automatically in all timeframes
+ for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis )
+ {
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ pRnm = Rnm_ManObj( p, pObj, f );
+ pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i );
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ {
+ assert( pObj->Value > 0 );
+ pRnm->Prio = pObj->Value;
+ pRnm->fPPi = 1;
+ }
+ }
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) );
+ pRnm = Rnm_ManObj( p, pObj, f );
+ assert( !pRnm->fPPi );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f == 0 )
+ continue;
+ pRnm0 = Rnm_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 );
+ pRnm->Value = pRnm0->Value;
+ pRnm->Prio = pRnm0->Prio;
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f );
+ pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj));
+ pRnm->Prio = pRnm0->Prio;
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f );
+ pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f );
+ pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj));
+ if ( pRnm->Value == 1 )
+ pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio );
+ else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice
+ else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 )
+ pRnm->Prio = pRnm0->Prio;
+ else
+ pRnm->Prio = pRnm1->Prio;
+ }
+ }
+ assert( iBit == p->pCex->nBits );
+ pRnm = Rnm_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame );
+ if ( pRnm->Value != 1 )
+ printf( "Output value is incorrect.\n" );
+ return pRnm->Prio;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Drive implications of the given node towards primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rnm_ManJustifyPropFanout_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect )
+{
+ Rnm_Obj_t * pRnm0, * pRnm1, * pRnm = Rnm_ManObj( p, pObj, f );
+ Gia_Obj_t * pFanout = NULL;
+ int i, k;//, Id = Gia_ObjId(p->pGia, pObj);
+ assert( pRnm->fVisit == 0 );
+ pRnm->fVisit = 1;
+ if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 )
+ {
+ Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1;
+ p->nVisited++;
+ }
+ if ( pRnm->fPPi )
+ {
+ assert( (int)pRnm->Prio > 0 );
+ for ( i = p->pCex->iFrame; i >= 0; i-- )
+ if ( !Rnm_ManObj(p, pObj, i)->fVisit )
+ Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect );
+ Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) );
+ return;
+ }
+ if ( (Gia_ObjIsCo(pObj) && f == p->pCex->iFrame) || Gia_ObjIsPo(p->pGia, pObj) )
+ return;
+ if ( Gia_ObjIsRi(p->pGia, pObj) )
+ {
+ pFanout = Gia_ObjRiToRo(p->pGia, pObj);
+ if ( !Rnm_ManObj(p, pFanout, f+1)->fVisit )
+ Rnm_ManJustifyPropFanout_rec( p, pFanout, f+1, vSelect );
+ return;
+ }
+ assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
+ Gia_ObjForEachFanoutStatic( p->pGia, pObj, pFanout, k )
+ {
+ Rnm_Obj_t * pRnmF;
+ if ( pFanout->Value == 0 )
+ continue;
+ pRnmF = Rnm_ManObj(p, pFanout, f);
+ if ( pRnmF->fPPi || pRnmF->fVisit )
+ continue;
+ if ( Gia_ObjIsCo(pFanout) )
+ {
+ Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect );
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pFanout) );
+ pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pFanout), f );
+ pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pFanout), f );
+ if ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 0 && pRnm0->fVisit) ||
+ ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 0 && pRnm1->fVisit) ||
+ ( ((pRnm0->Value ^ Gia_ObjFaninC0(pFanout)) == 1 && pRnm0->fVisit) &&
+ ((pRnm1->Value ^ Gia_ObjFaninC1(pFanout)) == 1 && pRnm1->fVisit) ) )
+ Rnm_ManJustifyPropFanout_rec( p, pFanout, f, vSelect );
+ }
+}
+void Rnm_ManJustify_rec( Rnm_Man_t * p, Gia_Obj_t * pObj, int f, Vec_Int_t * vSelect )
+{
+ Rnm_Obj_t * pRnm = Rnm_ManObj( p, pObj, f );
+ int i;//, Id = Gia_ObjId(p->pGia, pObj);
+ if ( pRnm->fVisit )
+ return;
+ if ( p->fPropFanout )
+ Rnm_ManJustifyPropFanout_rec( p, pObj, f, vSelect );
+ else
+ {
+ pRnm->fVisit = 1;
+ if ( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 )
+ {
+ Rnm_ManObj( p, pObj, 0 )->fVisit0 = 1;
+ p->nVisited++;
+ }
+ }
+ if ( pRnm->fPPi )
+ {
+ assert( (int)pRnm->Prio > 0 );
+ if ( p->fPropFanout )
+ {
+ for ( i = p->pCex->iFrame; i >= 0; i-- )
+ if ( !Rnm_ManObj(p, pObj, i)->fVisit )
+ Rnm_ManJustifyPropFanout_rec( p, pObj, i, vSelect );
+ }
+ else
+ {
+ Vec_IntPush( vSelect, Gia_ObjId(p->pGia, pObj) );
+// for ( i = p->pCex->iFrame; i >= 0; i-- )
+// Rnm_ManObj(p, pObj, i)->fVisit = 1;
+ }
+ return;
+ }
+ if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) )
+ return;
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ObjRoToRi(p->pGia, pObj)), f-1, vSelect );
+ return;
+ }
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Rnm_Obj_t * pRnm0 = Rnm_ManObj( p, Gia_ObjFanin0(pObj), f );
+ Rnm_Obj_t * pRnm1 = Rnm_ManObj( p, Gia_ObjFanin1(pObj), f );
+ if ( pRnm->Value == 1 )
+ {
+ if ( pRnm0->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect );
+ if ( pRnm1->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect );
+ }
+ else // select one value
+ {
+ if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ {
+ if ( pRnm0->Prio <= pRnm1->Prio ) // choice
+ {
+ if ( pRnm0->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect );
+ }
+ else
+ {
+ if ( pRnm1->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect );
+ }
+ }
+ else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 )
+ {
+ if ( pRnm0->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin0(pObj), f, vSelect );
+ }
+ else if ( (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ {
+ if ( pRnm1->Prio > 0 )
+ Rnm_ManJustify_rec( p, Gia_ObjFanin1(pObj), f, vSelect );
+ }
+ else assert( 0 );
+ }
+ }
+ else assert( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rnm_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj;
+ int i, f, iBit = pCex->nRegs;
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis )
+ {
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ {
+ pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i );
+ if ( !Gia_ObjIsPi(p, pObj) )
+ Gia_ObjTerSimSetX( pObj );
+ else if ( pObj->Value )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap
+ {
+ if ( pObj->Value )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjTerSimCo( pObj );
+ else if ( Gia_ObjIsAnd(pObj) )
+ Gia_ObjTerSimAnd( pObj );
+ else if ( f == 0 )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimRo( p, pObj );
+ }
+ }
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ pObj->Value = 0;
+ pObj = Gia_ManPo( p, 0 );
+ if ( !Gia_ObjTerSimGet1(pObj) )
+ Abc_Print( 1, "\nRefinement verification has failed!!!\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rnm_ManPrintSelected( Rnm_Man_t * p, Vec_Int_t * vSelected )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ {
+ if ( Vec_IntFind(vSelected, Gia_ObjId(p->pGia, pObj)) >= 0 )
+ printf( "1" ), Counter++;
+ else
+ printf( "0" );
+ }
+ else
+ printf( "-" );
+ }
+ printf( " %3d\n", Counter );
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Perform structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ga2_StructAnalize( Gia_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInter, Vec_Int_t * vSelect )
+{
+ Vec_Int_t * vLeaves;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k;
+ // clean labels
+ Gia_ManForEachObj( p, pObj, i )
+ pObj->fMark0 = pObj->fMark1 = 0;
+ // label frontier
+ Gia_ManForEachObjVec( vFront, p, pObj, i )
+ pObj->fMark0 = 1, pObj->fMark1 = 0;
+ // label objects
+ Gia_ManForEachObjVec( vInter, p, pObj, i )
+ pObj->fMark1 = 0, pObj->fMark1 = 1;
+ // label selected
+ Gia_ManForEachObjVec( vSelect, p, pObj, i )
+ pObj->fMark1 = 1, pObj->fMark1 = 1;
+ // explore selected
+ printf( "\n" );
+ Gia_ManForEachObjVec( vSelect, p, pObj, i )
+ {
+ printf( "Selected %6d : ", Gia_ObjId(p, pObj) );
+ printf( "\n" );
+ vLeaves = Ga2_ObjLeaves( p, pObj );
+ Gia_ManForEachObjVec( vLeaves, p, pFanin, k )
+ {
+ printf( " " );
+ printf( "%6d ", Gia_ObjId(p, pFanin) );
+ if ( pFanin->fMark0 && pFanin->fMark1 )
+ printf( "select" );
+ else if ( pFanin->fMark0 && !pFanin->fMark1 )
+ printf( "front" );
+ else if ( !pFanin->fMark0 && pFanin->fMark1 )
+ printf( "internal" );
+ else if ( !pFanin->fMark0 && !pFanin->fMark1 )
+ printf( "new" );
+ printf( "\n" );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Finds essential objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ga2_FilterSelected( Rnm_Man_t * p, Vec_Int_t * vSelect )
+{
+ Vec_Int_t * vNew, * vLeaves;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, RetValue;//, Counters[3] = {0};
+/*
+ // check that selected are not visited
+ Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i )
+ assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 1 );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ if ( Vec_IntFind(vSelect, Gia_ObjId(p->pGia, pObj)) == -1 )
+ assert( Rnm_ManObj( p, pObj, 0 )->fVisit0 == 0 );
+*/
+
+ // verify
+// Gia_ManForEachObj( p->pGia, pObj, i )
+// assert( Rnm_ObjCount(p, pObj) == 0 );
+
+ // increment fanin counters
+ Vec_IntClear( p->vFanins );
+ Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i )
+ {
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ if ( Rnm_ObjAddToCount(p, pFanin) == 0 )
+ Vec_IntPush( p->vFanins, Gia_ObjId(p->pGia, pFanin) );
+ }
+
+ // find selected objects, which create potential constraints
+ // - flop objects
+ // - objects whose fanin belongs to the justified area
+ // - objects whose fanins overlap
+ // (these do not guantee reconvergence, but may potentially have it)
+ // (other objects cannot have reconvergence, even if they are added)
+ vNew = Vec_IntAlloc( 100 );
+ Gia_ManForEachObjVec( vSelect, p->pGia, pObj, i )
+ {
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) );
+ continue;
+ }
+ vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
+ Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+ {
+ if ( Gia_ObjIsConst0(pFanin)
+ || (pFanin->Value && Rnm_ManObj(p, pFanin, 0)->fVisit0 == 1)
+ || Rnm_ObjCount(p, pFanin) > 1
+ )
+ {
+ Vec_IntPush( vNew, Gia_ObjId(p->pGia, pObj) );
+ break;
+ }
+ }
+// Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
+// {
+// Counters[1] += (pFanin->Value && Rnm_ManObj( p, pFanin, 0 )->fVisit0 == 1);
+// Counters[2] += (Rnm_ObjCount(p, pFanin) > 1);
+// }
+ }
+ RetValue = Vec_IntUniqify( vNew );
+ assert( RetValue == 0 );
+
+// printf( "\n*** Select = %5d. New = %5d. Flops = %5d. Visited = %5d. Fanins = %5d.\n",
+// Vec_IntSize(vSelect), Vec_IntSize(vNew), Counters[0], Counters[1], Counters[2] );
+
+ // clear fanin counters
+ Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i )
+ Rnm_ObjSetCount( p, pObj, 0 );
+ return vNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the refinement for a given counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose )
+{
+ int fVerify = 0;
+// int fPostProcess = 1;
+ Vec_Int_t * vSelected = Vec_IntAlloc( 100 );
+ Vec_Int_t * vNew;
+ clock_t clk, clk2 = clock();
+ int RetValue;
+ p->nCalls++;
+// Gia_ManCleanValue( p->pGia );
+ // initialize
+ p->pCex = pCex;
+ p->vMap = vMap;
+ p->fPropFanout = fPropFanout;
+ p->fVerbose = fVerbose;
+ // collects used objects
+ Rnm_ManCollect( p );
+ // initialize datastructure
+ p->nObjsFrame = 1 + Vec_IntSize(vMap) + Vec_IntSize(p->vObjs);
+ p->nObjs = p->nObjsFrame * (pCex->iFrame + 1);
+ if ( p->nObjs > p->nObjsAlloc )
+ p->pObjs = ABC_REALLOC( Rnm_Obj_t, p->pObjs, (p->nObjsAlloc = p->nObjs + 10000) );
+ memset( p->pObjs, 0, sizeof(Rnm_Obj_t) * p->nObjs );
+ // propagate priorities
+ clk = clock();
+ if ( Rnm_ManSensitize( p ) ) // the CEX is not a true CEX
+ {
+ p->timeFwd += clock() - clk;
+ // select refinement
+ clk = clock();
+ p->nVisited = 0;
+ Rnm_ManJustify_rec( p, Gia_ObjFanin0(Gia_ManPo(p->pGia, 0)), pCex->iFrame, vSelected );
+ RetValue = Vec_IntUniqify( vSelected );
+// assert( RetValue == 0 );
+ p->timeBwd += clock() - clk;
+ }
+
+ if ( fPostProcess )
+ {
+ vNew = Ga2_FilterSelected( p, vSelected );
+ if ( Vec_IntSize(vNew) > 0 )
+ {
+ Vec_IntFree( vSelected );
+ vSelected = vNew;
+ }
+ else
+ {
+ Vec_IntFree( vNew );
+ // printf( "\nBig refinement.\n" );
+ }
+ }
+ else
+ {
+/*
+ vNew = Rnm_ManRefineUnsatCore( p, vSelected );
+ if ( Vec_IntSize(vNew) > 0 )
+ {
+ Vec_IntFree( vSelected );
+ vSelected = vNew;
+// Vec_IntFree( vNew );
+ }
+ else
+ {
+ Vec_IntFree( vNew );
+ // printf( "\nBig refinement.\n" );
+ }
+*/
+ }
+
+ // clean values
+ Rnm_ManCleanValues( p );
+
+ // verify (empty) refinement
+ if ( fVerify )
+ {
+ clk = clock();
+ Rnm_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected );
+ p->timeVer += clock() - clk;
+ }
+
+// printf( "\nOriginal (%d): \n", Vec_IntSize(p->vMap) );
+// Rnm_ManPrintSelected( p, vSelected );
+
+// Ga2_StructAnalize( p->pGia, vMap, p->vObjs, vSelected );
+// printf( "\nObjects = %5d. Visited = %5d.\n", Vec_IntSize(p->vObjs), p->nVisited );
+
+// Vec_IntReverseOrder( vSelected );
+ p->timeTotal += clock() - clk2;
+ p->nRefines += Vec_IntSize(vSelected);
+ return vSelected;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absRef.h b/src/proof/abs/absRef.h
new file mode 100644
index 00000000..ca46c776
--- /dev/null
+++ b/src/proof/abs/absRef.h
@@ -0,0 +1,67 @@
+/**CFile****************************************************************
+
+ FileName [absRef.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Refinement manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absRef.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__proof_abs__AbsRef_h
+#define ABC__proof_abs__AbsRef_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Rnm_Man_t_ Rnm_Man_t; // refinement manager
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== giaAbsRef.c ===========================================================*/
+extern Rnm_Man_t * Rnm_ManStart( Gia_Man_t * pGia );
+extern void Rnm_ManStop( Rnm_Man_t * p, int fProfile );
+extern double Rnm_ManMemoryUsage( Rnm_Man_t * p );
+extern Vec_Int_t * Rnm_ManRefine( Rnm_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fPostProcess, int fVerbose );
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/abs/absRef2.c b/src/proof/abs/absRef2.c
new file mode 100644
index 00000000..7fb26e5a
--- /dev/null
+++ b/src/proof/abs/absRef2.c
@@ -0,0 +1,916 @@
+/**CFile****************************************************************
+
+ FileName [absRef2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Refinement manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absRef2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+#include "absRef2.h"
+
+ABC_NAMESPACE_IMPL_START
+
+/*
+ Description of the refinement manager
+
+ This refinement manager should be
+ * started by calling Rf2_ManStart()
+ this procedure takes one argument, the user's seq miter as a GIA manager
+ - the manager should have only one property output
+ - this manager should not change while the refinement manager is alive
+ - it cannot be used by external applications for any purpose
+ - when the refinement manager stop, GIA manager is the same as at the beginning
+ - in the meantime, it will have some data-structures attached to its nodes...
+ * stopped by calling Rf2_ManStop()
+ * between starting and stopping, refinements are obtained by calling Rf2_ManRefine()
+
+ Procedure Rf2_ManRefine() takes the following arguments:
+ * the refinement manager previously started by Rf2_ManStart()
+ * counter-example (CEX) obtained by abstracting some logic of GIA
+ * mapping (vMap) of inputs of the CEX into the object IDs of the GIA manager
+ - only PI, flop outputs, and internal AND nodes can be used in vMap
+ - the ordering of objects in vMap is not important
+ - however, the index of a non-PI object in vMap is used as its priority
+ (the smaller the index, the more likely this non-PI object apears in a refinement)
+ - only the logic between PO and the objects listed in vMap is traversed by the manager
+ (as a result, GIA can be arbitrarily large, but only objects used in the abstraction
+ and the pseudo-PI, that is, objects in the cut, will be visited by the manager)
+ * flag fPropFanout defines whether value propagation is done through the fanout
+ - it this flag is enabled, theoretically refinement should be better (the result smaller)
+ * flag fVerbose may print some statistics
+
+ The refinement manager returns a minimal-size array of integer IDs of GIA objects
+ which should be added to the abstraction to possibly prevent the given counter-example
+ - only flop output and internal AND nodes from vMap may appear in the resulting array
+ - if the resulting array is empty, the CEX is a true CEX
+ (in other words, non-PI objects are not needed to set the PO value to 1)
+
+ Verification of the selected refinement is performed by
+ - initializing all PI objects in vMap to value 0 or 1 they have in the CEX
+ - initializing all remaining objects in vMap to value X
+ - initializing objects used in the refiment to value 0 or 1 they have in the CEX
+ - simulating through as many timeframes as required by the CEX
+ - if the PO value in the last frame is 1, the refinement is correct
+ (however, the minimality of the refinement is not currently checked)
+
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Rf2_Obj_t_ Rf2_Obj_t; // refinement object
+struct Rf2_Obj_t_
+{
+ unsigned Value : 1; // binary value
+ unsigned fVisit : 1; // visited object
+ unsigned fPPi : 1; // PPI object
+ unsigned Prio : 24; // priority (0 - highest)
+};
+
+struct Rf2_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia; // working AIG manager (it is completely owned by this package)
+ Abc_Cex_t * pCex; // counter-example
+ Vec_Int_t * vMap; // mapping of CEX inputs into objects (PI + PPI, in any order)
+ int fPropFanout; // propagate fanouts
+ int fVerbose; // verbose flag
+ // traversing data
+ Vec_Int_t * vObjs; // internal objects used in value propagation
+ Vec_Int_t * vFanins; // fanins of the PPI nodes
+ Vec_Int_t * pvVecs; // vectors of integers for each object
+ Vec_Vec_t * vGrp2Ppi; // for each node, the set of PPIs to include
+ int nMapWords;
+ // internal data
+ Rf2_Obj_t * pObjs; // refinement objects
+ int nObjs; // the number of used objects
+ int nObjsAlloc; // the number of allocated objects
+ int nObjsFrame; // the number of used objects in each frame
+ int nCalls; // total number of calls
+ int nRefines; // total refined objects
+ // statistics
+ clock_t timeFwd; // forward propagation
+ clock_t timeBwd; // backward propagation
+ clock_t timeVer; // ternary simulation
+ clock_t timeTotal; // other time
+};
+
+// accessing the refinement object
+static inline Rf2_Obj_t * Rf2_ManObj( Rf2_Man_t * p, Gia_Obj_t * pObj, int f )
+{
+ assert( Gia_ObjIsConst0(pObj) || pObj->Value );
+ assert( (int)pObj->Value < p->nObjsFrame );
+ assert( f >= 0 && f <= p->pCex->iFrame );
+ return p->pObjs + f * p->nObjsFrame + pObj->Value;
+}
+
+static inline Vec_Int_t * Rf2_ObjVec( Rf2_Man_t * p, Gia_Obj_t * pObj )
+{
+ return p->pvVecs + Gia_ObjId(p->pGia, pObj);
+}
+
+
+static inline unsigned * Rf2_ObjA( Rf2_Man_t * p, Gia_Obj_t * pObj )
+{
+ return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj));
+}
+static inline unsigned * Rf2_ObjN( Rf2_Man_t * p, Gia_Obj_t * pObj )
+{
+ return (unsigned *)Vec_IntArray(Rf2_ObjVec(p, pObj)) + p->nMapWords;
+}
+static inline void Rf2_ObjClear( Rf2_Man_t * p, Gia_Obj_t * pObj )
+{
+ Vec_IntFill( Rf2_ObjVec(p, pObj), 2*p->nMapWords, 0 );
+}
+static inline void Rf2_ObjStart( Rf2_Man_t * p, Gia_Obj_t * pObj, int i )
+{
+ Vec_Int_t * vVec = Rf2_ObjVec(p, pObj);
+ int w;
+ Vec_IntClear( vVec );
+ for ( w = 0; w < p->nMapWords; w++ )
+ Vec_IntPush( vVec, 0 );
+ for ( w = 0; w < p->nMapWords; w++ )
+ Vec_IntPush( vVec, ~0 );
+ Abc_InfoSetBit( Rf2_ObjA(p, pObj), i );
+ Abc_InfoXorBit( Rf2_ObjN(p, pObj), i );
+}
+static inline void Rf2_ObjCopy( Rf2_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin )
+{
+ assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords );
+ memcpy( Rf2_ObjA(p, pObj), Rf2_ObjA(p, pFanin), sizeof(unsigned) * 2 * p->nMapWords );
+}
+static inline void Rf2_ObjDeriveAnd( Rf2_Man_t * p, Gia_Obj_t * pObj, int One )
+{
+ unsigned * pInfo, * pInfo0, * pInfo1;
+ int i;
+ assert( Gia_ObjIsAnd(pObj) );
+ assert( One == (int)pObj->fMark0 );
+ assert( One == (int)(Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) );
+ assert( One == (int)(Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) );
+ assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 2*p->nMapWords );
+
+ pInfo = Rf2_ObjA( p, pObj );
+ pInfo0 = Rf2_ObjA( p, Gia_ObjFanin0(pObj) );
+ pInfo1 = Rf2_ObjA( p, Gia_ObjFanin1(pObj) );
+ for ( i = 0; i < p->nMapWords; i++ )
+ pInfo[i] = One ? (pInfo0[i] & pInfo1[i]) : (pInfo0[i] | pInfo1[i]);
+
+ pInfo = Rf2_ObjN( p, pObj );
+ pInfo0 = Rf2_ObjN( p, Gia_ObjFanin0(pObj) );
+ pInfo1 = Rf2_ObjN( p, Gia_ObjFanin1(pObj) );
+ for ( i = 0; i < p->nMapWords; i++ )
+ pInfo[i] = One ? (pInfo0[i] | pInfo1[i]) : (pInfo0[i] & pInfo1[i]);
+}
+static inline void Rf2_ObjPrint( Rf2_Man_t * p, Gia_Obj_t * pRoot )
+{
+ Gia_Obj_t * pObj;
+ unsigned * pInfo;
+ int i;
+ pInfo = Rf2_ObjA( p, pRoot );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ printf( "%d", Abc_InfoHasBit(pInfo, i) );
+ printf( "\n" );
+ pInfo = Rf2_ObjN( p, pRoot );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ printf( "%d", !Abc_InfoHasBit(pInfo, i) );
+ printf( "\n" );
+
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia )
+{
+ Rf2_Man_t * p;
+ assert( Gia_ManPoNum(pGia) == 1 );
+ p = ABC_CALLOC( Rf2_Man_t, 1 );
+ p->pGia = pGia;
+ p->vObjs = Vec_IntAlloc( 1000 );
+ p->vFanins = Vec_IntAlloc( 1000 );
+ p->pvVecs = ABC_CALLOC( Vec_Int_t, Gia_ManObjNum(pGia) );
+ p->vGrp2Ppi = Vec_VecStart( 100 );
+ Gia_ManCleanMark0(pGia);
+ Gia_ManCleanMark1(pGia);
+ return p;
+}
+void Rf2_ManStop( Rf2_Man_t * p, int fProfile )
+{
+ if ( !p ) return;
+ // print runtime statistics
+ if ( fProfile && p->nCalls )
+ {
+ double MemGia = sizeof(Gia_Man_t) + sizeof(Gia_Obj_t) * p->pGia->nObjsAlloc + sizeof(int) * p->pGia->nTravIdsAlloc;
+ double MemOther = sizeof(Rf2_Man_t) + sizeof(Rf2_Obj_t) * p->nObjsAlloc + sizeof(int) * Vec_IntCap(p->vObjs);
+ clock_t timeOther = p->timeTotal - p->timeFwd - p->timeBwd - p->timeVer;
+ printf( "Abstraction refinement runtime statistics:\n" );
+ ABC_PRTP( "Sensetization", p->timeFwd, p->timeTotal );
+ ABC_PRTP( "Justification", p->timeBwd, p->timeTotal );
+ ABC_PRTP( "Verification ", p->timeVer, p->timeTotal );
+ ABC_PRTP( "Other ", timeOther, p->timeTotal );
+ ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
+ printf( "Total calls = %d. Average refine = %.1f. GIA mem = %.3f MB. Other mem = %.3f MB.\n",
+ p->nCalls, 1.0*p->nRefines/p->nCalls, MemGia/(1<<20), MemOther/(1<<20) );
+ }
+ Vec_IntFree( p->vObjs );
+ Vec_IntFree( p->vFanins );
+ Vec_VecFree( p->vGrp2Ppi );
+ ABC_FREE( p->pvVecs );
+ ABC_FREE( p );
+}
+double Rf2_ManMemoryUsage( Rf2_Man_t * p )
+{
+ return (double)(sizeof(Rf2_Man_t) + sizeof(Vec_Int_t) * Gia_ManObjNum(p->pGia));
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect internal objects to be used in value propagation.]
+
+ Description [Resulting array vObjs contains RO, AND, PO/RI in a topo order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rf2_ManCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCo(pObj) )
+ Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Rf2_ManCollect_rec( p, Gia_ObjFanin0(pObj), vObjs );
+ Rf2_ManCollect_rec( p, Gia_ObjFanin1(pObj), vObjs );
+ }
+ else if ( !Gia_ObjIsRo(p, pObj) )
+ assert( 0 );
+ Vec_IntPush( vObjs, Gia_ObjId(p, pObj) );
+}
+void Rf2_ManCollect( Rf2_Man_t * p )
+{
+ Gia_Obj_t * pObj = NULL;
+ int i;
+ // mark const/PIs/PPIs
+ Gia_ManIncrementTravId( p->pGia );
+ Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ Gia_ObjSetTravIdCurrent( p->pGia, pObj );
+ }
+ // collect objects
+ Vec_IntClear( p->vObjs );
+ Rf2_ManCollect_rec( p->pGia, Gia_ManPo(p->pGia, 0), p->vObjs );
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ Rf2_ManCollect_rec( p->pGia, Gia_ObjRoToRi(p->pGia, pObj), p->vObjs );
+ // the last object should be a CO
+ assert( Gia_ObjIsCo(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs sensitization analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rf2_ManSensitize( Rf2_Man_t * p )
+{
+ Rf2_Obj_t * pRnm, * pRnm0, * pRnm1;
+ Gia_Obj_t * pObj;
+ int f, i, iBit = p->pCex->nRegs;
+ // const0 is initialized automatically in all timeframes
+ for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis )
+ {
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ pRnm = Rf2_ManObj( p, pObj, f );
+ pRnm->Value = Abc_InfoHasBit( p->pCex->pData, iBit + i );
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ {
+ assert( pObj->Value > 0 );
+ pRnm->Prio = pObj->Value;
+ pRnm->fPPi = 1;
+ }
+ }
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) );
+ pRnm = Rf2_ManObj( p, pObj, f );
+ assert( !pRnm->fPPi );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f == 0 )
+ continue;
+ pRnm0 = Rf2_ManObj( p, Gia_ObjRoToRi(p->pGia, pObj), f-1 );
+ pRnm->Value = pRnm0->Value;
+ pRnm->Prio = pRnm0->Prio;
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f );
+ pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj));
+ pRnm->Prio = pRnm0->Prio;
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pRnm0 = Rf2_ManObj( p, Gia_ObjFanin0(pObj), f );
+ pRnm1 = Rf2_ManObj( p, Gia_ObjFanin1(pObj), f );
+ pRnm->Value = (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) & (pRnm1->Value ^ Gia_ObjFaninC1(pObj));
+ if ( pRnm->Value == 1 )
+ pRnm->Prio = Abc_MaxInt( pRnm0->Prio, pRnm1->Prio );
+ else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 && (pRnm1->Value ^ Gia_ObjFaninC1(pObj)) == 0 )
+ pRnm->Prio = Abc_MinInt( pRnm0->Prio, pRnm1->Prio ); // choice
+ else if ( (pRnm0->Value ^ Gia_ObjFaninC0(pObj)) == 0 )
+ pRnm->Prio = pRnm0->Prio;
+ else
+ pRnm->Prio = pRnm1->Prio;
+ }
+ }
+ assert( iBit == p->pCex->nBits );
+ pRnm = Rf2_ManObj( p, Gia_ManPo(p->pGia, 0), p->pCex->iFrame );
+ if ( pRnm->Value != 1 )
+ printf( "Output value is incorrect.\n" );
+ return pRnm->Prio;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs refinement.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rf2_ManVerifyUsingTerSim( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, Vec_Int_t * vObjs, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj;
+ int i, f, iBit = pCex->nRegs;
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ for ( f = 0; f <= pCex->iFrame; f++, iBit += pCex->nPis )
+ {
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ {
+ pObj->Value = Abc_InfoHasBit( pCex->pData, iBit + i );
+ if ( !Gia_ObjIsPi(p, pObj) )
+ Gia_ObjTerSimSetX( pObj );
+ else if ( pObj->Value )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachObjVec( vRes, p, pObj, i ) // vRes is subset of vMap
+ {
+ if ( pObj->Value )
+ Gia_ObjTerSimSet1( pObj );
+ else
+ Gia_ObjTerSimSet0( pObj );
+ }
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjTerSimCo( pObj );
+ else if ( Gia_ObjIsAnd(pObj) )
+ Gia_ObjTerSimAnd( pObj );
+ else if ( f == 0 )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimRo( p, pObj );
+ }
+ }
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ pObj->Value = 0;
+ pObj = Gia_ManPo( p, 0 );
+ if ( !Gia_ObjTerSimGet1(pObj) )
+ Abc_Print( 1, "\nRefinement verification has failed!!!\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the refinement for a given counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rf2_ManGatherFanins_rec( Rf2_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vFanins, int Depth, int RootId, int fFirst )
+{
+ if ( Gia_ObjIsTravIdCurrent(p->pGia, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p->pGia, pObj);
+ if ( pObj->fPhase && !fFirst )
+ {
+ Vec_Int_t * vVec = Rf2_ObjVec( p, pObj );
+// if ( Vec_IntEntry( vVec, 0 ) == 0 )
+// return;
+ if ( Vec_IntSize(vVec) == 0 )
+ Vec_IntPush( vFanins, Gia_ObjId(p->pGia, pObj) );
+ Vec_IntPushUnique( vVec, RootId );
+ if ( Depth == 0 )
+ return;
+ }
+ if ( Gia_ObjIsPi(p->pGia, pObj) || Gia_ObjIsConst0(pObj) )
+ return;
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ assert( pObj->fPhase );
+ pObj = Gia_ObjRoToRi(p->pGia, pObj);
+ Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - 1, RootId, 0 );
+ }
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Rf2_ManGatherFanins_rec( p, Gia_ObjFanin0(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 );
+ Rf2_ManGatherFanins_rec( p, Gia_ObjFanin1(pObj), vFanins, Depth - pObj->fPhase, RootId, 0 );
+ }
+ else assert( 0 );
+}
+void Rf2_ManGatherFanins( Rf2_Man_t * p, int Depth )
+{
+ Vec_Int_t * vUsed;
+ Vec_Int_t * vVec;
+ Gia_Obj_t * pObj;
+ int i, k, Entry;
+ // mark PPIs
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ vVec = Rf2_ObjVec( p, pObj );
+ assert( Vec_IntSize(vVec) == 0 );
+ Vec_IntPush( vVec, 0 );
+ }
+ // collect internal
+ Vec_IntClear( p->vFanins );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ if ( Gia_ObjIsPi(p->pGia, pObj) )
+ continue;
+ Gia_ManIncrementTravId( p->pGia );
+ Rf2_ManGatherFanins_rec( p, pObj, p->vFanins, Depth, i, 1 );
+ }
+
+ vUsed = Vec_IntStart( Vec_IntSize(p->vMap) );
+
+ // evaluate collected
+ printf( "\nMap (%d): ", Vec_IntSize(p->vMap) );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ vVec = Rf2_ObjVec( p, pObj );
+ if ( Vec_IntSize(vVec) > 1 )
+ printf( "%d=%d ", i, Vec_IntSize(vVec) - 1 );
+ Vec_IntForEachEntryStart( vVec, Entry, k, 1 )
+ Vec_IntAddToEntry( vUsed, Entry, 1 );
+ Vec_IntClear( vVec );
+ }
+ printf( "\n" );
+ // evaluate internal
+ printf( "Int (%d): ", Vec_IntSize(p->vFanins) );
+ Gia_ManForEachObjVec( p->vFanins, p->pGia, pObj, i )
+ {
+ vVec = Rf2_ObjVec( p, pObj );
+ if ( Vec_IntSize(vVec) > 1 )
+ printf( "%d=%d ", i, Vec_IntSize(vVec) );
+ if ( Vec_IntSize(vVec) > 1 )
+ Vec_IntForEachEntry( vVec, Entry, k )
+ Vec_IntAddToEntry( vUsed, Entry, 1 );
+ Vec_IntClear( vVec );
+ }
+ printf( "\n" );
+ // evaluate PPIs
+ Vec_IntForEachEntry( vUsed, Entry, k )
+ printf( "%d ", Entry );
+ printf( "\n" );
+
+ Vec_IntFree( vUsed );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Sort, make dup- and containment-free, and filter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Rf2_ManCountPpis( Rf2_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ Counter++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sort, make dup- and containment-free, and filter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Rf2_ManPrintVector( Vec_Int_t * p, int Num )
+{
+ int i, k, Entry;
+ Vec_IntForEachEntry( p, Entry, i )
+ {
+ for ( k = 0; k < Num; k++ )
+ printf( "%c", '0' + ((Entry>>k) & 1) );
+ printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sort, make dup- and containment-free, and filter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Rf2_ManProcessVector( Vec_Int_t * p, int Limit )
+{
+// int Start = Vec_IntSize(p);
+ int Start = 0;
+ int i, j, k, Entry, Entry2;
+// printf( "%d", Vec_IntSize(p) );
+ if ( Start > 5 )
+ {
+ printf( "Before: \n" );
+ Rf2_ManPrintVector( p, 31 );
+ }
+
+ k = 0;
+ Vec_IntForEachEntry( p, Entry, i )
+ if ( Gia_WordCountOnes((unsigned)Entry) <= Limit )
+ Vec_IntWriteEntry( p, k++, Entry );
+ Vec_IntShrink( p, k );
+ Vec_IntSort( p, 0 );
+ k = 0;
+ Vec_IntForEachEntry( p, Entry, i )
+ {
+ Vec_IntForEachEntryStop( p, Entry2, j, i )
+ if ( (Entry2 & Entry) == Entry2 ) // Entry2 is a subset of Entry
+ break;
+ if ( j == i ) // Entry is not contained in any Entry2
+ Vec_IntWriteEntry( p, k++, Entry );
+ }
+ Vec_IntShrink( p, k );
+// printf( "->%d ", Vec_IntSize(p) );
+ if ( Start > 5 )
+ {
+ printf( "After: \n" );
+ Rf2_ManPrintVector( p, 31 );
+ k = 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns a unique justifification ID for each PPI.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rf2_ManAssignJustIds( Rf2_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int nPpis = Rf2_ManCountPpis( p );
+ int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0);
+ int i, k = 0;
+ Vec_VecClear( p->vGrp2Ppi );
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ Vec_VecPushInt( p->vGrp2Ppi, (k++ / nGroupSize), i );
+ printf( "Considering %d PPIs combined into %d groups of size %d.\n", k, (k-1)/nGroupSize+1, nGroupSize );
+ return (k-1)/nGroupSize+1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sort, make dup- and containment-free, and filter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Rf2_ManPrintVectorSpecial( Rf2_Man_t * p, Vec_Int_t * vVec )
+{
+ Gia_Obj_t * pObj;
+ int nPpis = Rf2_ManCountPpis( p );
+ int nGroupSize = (nPpis / 30) + (nPpis % 30 > 0);
+ int s, i, k, Entry, Counter;
+
+ Vec_IntForEachEntry( vVec, Entry, s )
+ {
+ k = 0;
+ Counter = 0;
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ if ( !Gia_ObjIsPi(p->pGia, pObj) ) // this is PPI
+ {
+ if ( (Entry >> (k++ / nGroupSize)) & 1 )
+ printf( "1" ), Counter++;
+ else
+ printf( "0" );
+ }
+ else
+ printf( "-" );
+ }
+ printf( " %3d \n", Counter );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs justification propagation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Rf2_ManPropagate( Rf2_Man_t * p, int Limit )
+{
+ Vec_Int_t * vVec, * vVec0, * vVec1;
+ Gia_Obj_t * pObj;
+ int f, i, k, j, Entry, Entry2, iBit = p->pCex->nRegs;
+ // init constant
+ pObj = Gia_ManConst0(p->pGia);
+ pObj->fMark0 = 0;
+ Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 );
+ // iterate through the timeframes
+ for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis )
+ {
+ // initialize frontier values and init justification sets
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i );
+ Vec_IntFill( Rf2_ObjVec(p, pObj), 1, 0 );
+ }
+ // assign justification sets for PPis
+ Vec_VecForEachLevelInt( p->vGrp2Ppi, vVec, i )
+ Vec_IntForEachEntry( vVec, Entry, k )
+ {
+ assert( i < 31 );
+ pObj = Gia_ManObj( p->pGia, Vec_IntEntry(p->vMap, Entry) );
+ assert( Vec_IntSize(Rf2_ObjVec(p, pObj)) == 1 );
+ Vec_IntAddToEntry( Rf2_ObjVec(p, pObj), 0, (1 << i) );
+ }
+ // propagate internal nodes
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ {
+ pObj->fMark0 = 0;
+ vVec = Rf2_ObjVec(p, pObj);
+ Vec_IntClear( vVec );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f == 0 )
+ {
+ Vec_IntPush( vVec, 0 );
+ continue;
+ }
+ pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0;
+ vVec0 = Rf2_ObjVec( p, Gia_ObjRoToRi(p->pGia, pObj) );
+ Vec_IntAppend( vVec, vVec0 );
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj));
+ vVec0 = Rf2_ObjVec( p, Gia_ObjFanin0(pObj) );
+ Vec_IntAppend( vVec, vVec0 );
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ vVec0 = Rf2_ObjVec(p, Gia_ObjFanin0(pObj));
+ vVec1 = Rf2_ObjVec(p, Gia_ObjFanin1(pObj));
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ if ( pObj->fMark0 == 1 )
+ {
+ Vec_IntForEachEntry( vVec0, Entry, k )
+ Vec_IntForEachEntry( vVec1, Entry2, j )
+ Vec_IntPush( vVec, Entry | Entry2 );
+ Rf2_ManProcessVector( vVec, Limit );
+ }
+ else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 )
+ {
+ Vec_IntAppend( vVec, vVec0 );
+ Vec_IntAppend( vVec, vVec1 );
+ Rf2_ManProcessVector( vVec, Limit );
+ }
+ else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 )
+ Vec_IntAppend( vVec, vVec0 );
+ else
+ Vec_IntAppend( vVec, vVec1 );
+ }
+ }
+ assert( iBit == p->pCex->nBits );
+ if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 )
+ printf( "Output value is incorrect.\n" );
+ return Rf2_ObjVec(p, Gia_ManPo(p->pGia, 0));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs justification propagation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rf2_ManBounds( Rf2_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int f, i, iBit = p->pCex->nRegs;
+ // init constant
+ pObj = Gia_ManConst0(p->pGia);
+ pObj->fMark0 = 0;
+ Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) );
+ // iterate through the timeframes
+ for ( f = 0; f <= p->pCex->iFrame; f++, iBit += p->pCex->nPis )
+ {
+ // initialize frontier values and init justification sets
+ Gia_ManForEachObjVec( p->vMap, p->pGia, pObj, i )
+ {
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ pObj->fMark0 = Abc_InfoHasBit( p->pCex->pData, iBit + i );
+ Rf2_ObjStart( p, pObj, i );
+ }
+ // propagate internal nodes
+ Gia_ManForEachObjVec( p->vObjs, p->pGia, pObj, i )
+ {
+ pObj->fMark0 = 0;
+ Rf2_ObjClear( p, pObj );
+ if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( f == 0 )
+ {
+ Rf2_ObjStart( p, pObj, Vec_IntSize(p->vMap) + i );
+ continue;
+ }
+ pObj->fMark0 = Gia_ObjRoToRi(p->pGia, pObj)->fMark0;
+ Rf2_ObjCopy( p, pObj, Gia_ObjRoToRi(p->pGia, pObj) );
+ continue;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj));
+ Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) );
+ continue;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ if ( pObj->fMark0 == 1 )
+ Rf2_ObjDeriveAnd( p, pObj, 1 );
+ else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 && (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)) == 0 )
+ Rf2_ObjDeriveAnd( p, pObj, 0 );
+ else if ( (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) == 0 )
+ Rf2_ObjCopy( p, pObj, Gia_ObjFanin0(pObj) );
+ else
+ Rf2_ObjCopy( p, pObj, Gia_ObjFanin1(pObj) );
+ }
+ }
+ assert( iBit == p->pCex->nBits );
+ if ( Gia_ManPo(p->pGia, 0)->fMark0 != 1 )
+ printf( "Output value is incorrect.\n" );
+
+ printf( "Bounds: \n" );
+ Rf2_ObjPrint( p, Gia_ManPo(p->pGia, 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the refinement for a given counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose )
+{
+ Vec_Int_t * vJusts;
+// Vec_Int_t * vSelected = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSelected = NULL;
+ clock_t clk, clk2 = clock();
+ int nGroups;
+ p->nCalls++;
+ // initialize
+ p->pCex = pCex;
+ p->vMap = vMap;
+ p->fPropFanout = fPropFanout;
+ p->fVerbose = fVerbose;
+ // collects used objects
+ Rf2_ManCollect( p );
+ // collect reconvergence points
+// Rf2_ManGatherFanins( p, 2 );
+ // propagate justification IDs
+ nGroups = Rf2_ManAssignJustIds( p );
+ vJusts = Rf2_ManPropagate( p, 32 );
+
+// printf( "\n" );
+// Rf2_ManPrintVector( vJusts, nGroups );
+ Rf2_ManPrintVectorSpecial( p, vJusts );
+ if ( Vec_IntSize(vJusts) == 0 )
+ {
+ printf( "Empty set of justifying subsets.\n" );
+ return NULL;
+ }
+
+// p->nMapWords = Abc_BitWordNum( Vec_IntSize(p->vMap) + Vec_IntSize(p->vObjs) + 1 ); // Map + Flops + Const
+// Rf2_ManBounds( p );
+
+ // select the result
+// Abc_PrintTime( 1, "Time", clock() - clk2 );
+
+ // verify (empty) refinement
+ clk = clock();
+// Rf2_ManVerifyUsingTerSim( p->pGia, p->pCex, p->vMap, p->vObjs, vSelected );
+// Vec_IntUniqify( vSelected );
+// Vec_IntReverseOrder( vSelected );
+ p->timeVer += clock() - clk;
+ p->timeTotal += clock() - clk2;
+// p->nRefines += Vec_IntSize(vSelected);
+ return vSelected;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absRef2.h b/src/proof/abs/absRef2.h
new file mode 100644
index 00000000..df7774c0
--- /dev/null
+++ b/src/proof/abs/absRef2.h
@@ -0,0 +1,67 @@
+/**CFile****************************************************************
+
+ FileName [absRef2.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Refinement manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absRef2.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__proof_abs__AbsRef2_h
+#define ABC__proof_abs__AbsRef2_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Rf2_Man_t_ Rf2_Man_t; // refinement manager
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== giaAbsRef.c ===========================================================*/
+extern Rf2_Man_t * Rf2_ManStart( Gia_Man_t * pGia );
+extern void Rf2_ManStop( Rf2_Man_t * p, int fProfile );
+extern double Rf2_ManMemoryUsage( Rf2_Man_t * p );
+extern Vec_Int_t * Rf2_ManRefine( Rf2_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vMap, int fPropFanout, int fVerbose );
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/abs/absUtil.c b/src/proof/abs/absUtil.c
new file mode 100644
index 00000000..60429496
--- /dev/null
+++ b/src/proof/abs/absUtil.c
@@ -0,0 +1,257 @@
+/**CFile****************************************************************
+
+ FileName [absUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Interface to pthreads.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abs_ParSetDefaults( Abs_Par_t * p )
+{
+ memset( p, 0, sizeof(Abs_Par_t) );
+ p->nFramesMax = 0; // maximum frames
+ p->nFramesStart = 0; // starting frame
+ p->nFramesPast = 4; // overlap frames
+ p->nConfLimit = 0; // conflict limit
+ p->nLearnedMax = 1000; // max number of learned clauses
+ p->nLearnedStart = 1000; // max number of learned clauses
+ p->nLearnedDelta = 200; // max number of learned clauses
+ p->nLearnedPerce = 70; // max number of learned clauses
+ p->nTimeOut = 0; // timeout in seconds
+ p->nRatioMin = 0; // stop when less than this % of object is abstracted
+ p->nRatioMax = 30; // restart when more than this % of object is abstracted
+ p->fUseTermVars = 0; // use terminal variables
+ p->fUseRollback = 0; // use rollback to the starting number of frames
+ p->fPropFanout = 1; // propagate fanouts during refinement
+ p->fVerbose = 0; // verbose flag
+ p->iFrame = -1; // the number of frames covered
+ p->iFrameProved = -1; // the number of frames proved
+ p->nFramesNoChangeLim = 1; // the number of frames without change to dump abstraction
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting VTA vector to GLA vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_VtaConvertToGla( Gia_Man_t * p, Vec_Int_t * vVta )
+{
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vGla;
+ int nObjMask, nObjs = Gia_ManObjNum(p);
+ int i, Entry, nFrames = Vec_IntEntry( vVta, 0 );
+ assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) );
+ // get the bitmask
+ nObjMask = (1 << Abc_Base2Log(nObjs)) - 1;
+ assert( nObjs <= nObjMask );
+ // go through objects
+ vGla = Vec_IntStart( nObjs );
+ Vec_IntForEachEntryStart( vVta, Entry, i, nFrames+2 )
+ {
+ pObj = Gia_ManObj( p, (Entry & nObjMask) );
+ assert( Gia_ObjIsRo(p, pObj) || Gia_ObjIsAnd(pObj) || Gia_ObjIsConst0(pObj) );
+ Vec_IntAddToEntry( vGla, (Entry & nObjMask), 1 );
+ }
+ Vec_IntWriteEntry( vGla, 0, nFrames );
+ return vGla;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting GLA vector to VTA vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_VtaConvertFromGla( Gia_Man_t * p, Vec_Int_t * vGla, int nFrames )
+{
+ Vec_Int_t * vVta;
+ int nObjBits, nObjMask, nObjs = Gia_ManObjNum(p);
+ int i, k, j, Entry, Counter, nGlaSize;
+ //. get the GLA size
+ nGlaSize = Vec_IntSum(vGla);
+ // get the bitmask
+ nObjBits = Abc_Base2Log(nObjs);
+ nObjMask = (1 << Abc_Base2Log(nObjs)) - 1;
+ assert( nObjs <= nObjMask );
+ // go through objects
+ vVta = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vVta, nFrames );
+ Counter = nFrames + 2;
+ for ( i = 0; i <= nFrames; i++, Counter += i * nGlaSize )
+ Vec_IntPush( vVta, Counter );
+ for ( i = 0; i < nFrames; i++ )
+ for ( k = 0; k <= i; k++ )
+ Vec_IntForEachEntry( vGla, Entry, j )
+ if ( Entry )
+ Vec_IntPush( vVta, (k << nObjBits) | j );
+ Counter = Vec_IntEntry(vVta, nFrames+1);
+ assert( Vec_IntEntry(vVta, nFrames+1) == Vec_IntSize(vVta) );
+ return vVta;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting GLA vector to FLA vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_FlaConvertToGla_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vGla )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Vec_IntWriteEntry( vGla, Gia_ObjId(p, pObj), 1 );
+ if ( Gia_ObjIsRo(p, pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla );
+ Gia_FlaConvertToGla_rec( p, Gia_ObjFanin1(pObj), vGla );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting FLA vector to GLA vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_FlaConvertToGla( Gia_Man_t * p, Vec_Int_t * vFla )
+{
+ Vec_Int_t * vGla;
+ Gia_Obj_t * pObj;
+ int i;
+ // mark const0 and relevant CI objects
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p));
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManForEachRo( p, pObj, i )
+ if ( !Vec_IntEntry(vFla, i) )
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ // label all objects reachable from the PO and selected flops
+ vGla = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_IntWriteEntry( vGla, 0, 1 );
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla );
+ Gia_ManForEachRi( p, pObj, i )
+ if ( Vec_IntEntry(vFla, i) )
+ Gia_FlaConvertToGla_rec( p, Gia_ObjFanin0(pObj), vGla );
+ return vGla;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting GLA vector to FLA vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_GlaConvertToFla( Gia_Man_t * p, Vec_Int_t * vGla )
+{
+ Vec_Int_t * vFla;
+ Gia_Obj_t * pObj;
+ int i;
+ vFla = Vec_IntStart( Gia_ManRegNum(p) );
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) )
+ Vec_IntWriteEntry( vFla, i, 1 );
+ return vFla;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_GlaCountFlops( Gia_Man_t * p, Vec_Int_t * vGla )
+{
+ Gia_Obj_t * pObj;
+ int i, Count = 0;
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) )
+ Count++;
+ return Count;
+}
+int Gia_GlaCountNodes( Gia_Man_t * p, Vec_Int_t * vGla )
+{
+ Gia_Obj_t * pObj;
+ int i, Count = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_IntEntry(vGla, Gia_ObjId(p, pObj)) )
+ Count++;
+ return Count;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/absVta.c b/src/proof/abs/absVta.c
new file mode 100644
index 00000000..7e85c661
--- /dev/null
+++ b/src/proof/abs/absVta.c
@@ -0,0 +1,1765 @@
+/**CFile****************************************************************
+
+ FileName [absVta.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Abstraction package.]
+
+ Synopsis [Variable time-frame abstraction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: absVta.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sat/bsat/satSolver2.h"
+#include "base/main/main.h"
+#include "abs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+#define VTA_LARGE 0xFFFFFFF
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vta_Obj_t_ Vta_Obj_t; // object
+struct Vta_Obj_t_
+{
+ int iObj;
+ int iFrame;
+ int iNext;
+ unsigned Prio : 28; // related to VTA_LARGE
+ unsigned Value : 2;
+ unsigned fAdded : 1;
+ unsigned fVisit : 1;
+};
+
+typedef struct Vta_Man_t_ Vta_Man_t; // manager
+struct Vta_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia; // AIG manager
+ Abs_Par_t * pPars; // parameters
+ // internal data
+ int nObjs; // the number of objects
+ int nObjsAlloc; // the number of objects allocated
+ int nBins; // number of hash table entries
+ int * pBins; // hash table bins
+ Vta_Obj_t * pObjs; // storage for objects
+ Vec_Int_t * vOrder; // objects in DPS order
+ // abstraction
+ int nObjBits; // the number of bits to represent objects
+ unsigned nObjMask; // object mask
+ Vec_Ptr_t * vFrames; // start abstraction for each frame
+ int nWords; // the number of words in the record
+ int nCexes; // the number of CEXes
+ int nObjAdded; // objects added to the abstraction
+ Vec_Int_t * vSeens; // seen objects
+ Vec_Bit_t * vSeenGla; // seen objects in all frames
+ int nSeenGla; // seen objects in all frames
+ int nSeenAll; // seen objects in all frames
+ // other data
+ Vec_Ptr_t * vCores; // unsat core for each frame
+ sat_solver2 * pSat; // incremental SAT solver
+ Vec_Int_t * vAddedNew; // the IDs of variables added to the solver
+ // statistics
+ clock_t timeSat;
+ clock_t timeUnsat;
+ clock_t timeCex;
+ clock_t timeOther;
+};
+
+
+// ternary simulation
+
+#define VTA_VAR0 1
+#define VTA_VAR1 2
+#define VTA_VARX 3
+
+static inline int Vta_ValIs0( Vta_Obj_t * pThis, int fCompl )
+{
+ if ( pThis->Value == VTA_VAR1 && fCompl )
+ return 1;
+ if ( pThis->Value == VTA_VAR0 && !fCompl )
+ return 1;
+ return 0;
+}
+static inline int Vta_ValIs1( Vta_Obj_t * pThis, int fCompl )
+{
+ if ( pThis->Value == VTA_VAR0 && fCompl )
+ return 1;
+ if ( pThis->Value == VTA_VAR1 && !fCompl )
+ return 1;
+ return 0;
+}
+
+static inline Vta_Obj_t * Vta_ManObj( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; }
+static inline int Vta_ObjId( Vta_Man_t * p, Vta_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; }
+
+#define Vta_ManForEachObj( p, pObj, i ) \
+ for ( i = 1; (i < p->nObjs) && ((pObj) = Vta_ManObj(p, i)); i++ )
+#define Vta_ManForEachObjObj( p, pObjVta, pObjGia, i ) \
+ for ( i = 1; (i < p->nObjs) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ )
+#define Vta_ManForEachObjObjReverse( p, pObjVta, pObjGia, i ) \
+ for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ )
+
+#define Vta_ManForEachObjVec( vVec, p, pObj, i ) \
+ for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Vta_ManForEachObjVecReverse( vVec, p, pObj, i ) \
+ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i-- )
+
+#define Vta_ManForEachObjObjVec( vVec, p, pObj, pObjG, i ) \
+ for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i++ )
+#define Vta_ManForEachObjObjVecReverse( vVec, p, pObj, pObjG, i ) \
+ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i-- )
+
+
+// abstraction is given as an array of integers:
+// - the first entry is the number of timeframes (F)
+// - the next (F+1) entries give the beginning position of each timeframe
+// - the following entries give the object IDs
+// invariant: assert( vec[vec[0]+1] == size(vec) );
+
+extern void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Converting from one array to per-frame arrays.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Gia_VtaAbsToFrames( Vec_Int_t * vAbs )
+{
+ Vec_Ptr_t * vFrames;
+ Vec_Int_t * vFrame;
+ int i, k, Entry, iStart, iStop = -1;
+ int nFrames = Vec_IntEntry( vAbs, 0 );
+ assert( Vec_IntEntry(vAbs, nFrames+1) == Vec_IntSize(vAbs) );
+ vFrames = Vec_PtrAlloc( nFrames );
+ for ( i = 0; i < nFrames; i++ )
+ {
+ iStart = Vec_IntEntry( vAbs, i+1 );
+ iStop = Vec_IntEntry( vAbs, i+2 );
+ vFrame = Vec_IntAlloc( iStop - iStart );
+ Vec_IntForEachEntryStartStop( vAbs, Entry, k, iStart, iStop )
+ Vec_IntPush( vFrame, Entry );
+ Vec_PtrPush( vFrames, vFrame );
+ }
+ assert( iStop == Vec_IntSize(vAbs) );
+ return vFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting from per-frame arrays to one integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_VtaFramesToAbs( Vec_Vec_t * vFrames )
+{
+ Vec_Int_t * vOne, * vAbs;
+ int i, k, Entry, nSize;
+ vAbs = Vec_IntAlloc( 2 + Vec_VecSize(vFrames) + Vec_VecSizeSize(vFrames) );
+ Vec_IntPush( vAbs, Vec_VecSize(vFrames) );
+ nSize = Vec_VecSize(vFrames) + 2;
+ Vec_VecForEachLevelInt( vFrames, vOne, i )
+ {
+ Vec_IntPush( vAbs, nSize );
+ nSize += Vec_IntSize( vOne );
+ }
+ Vec_IntPush( vAbs, nSize );
+ assert( Vec_IntSize(vAbs) == Vec_VecSize(vFrames) + 2 );
+ Vec_VecForEachLevelInt( vFrames, vOne, i )
+ Vec_IntForEachEntry( vOne, Entry, k )
+ Vec_IntPush( vAbs, Entry );
+ assert( Vec_IntEntry(vAbs, Vec_IntEntry(vAbs,0)+1) == Vec_IntSize(vAbs) );
+ return vAbs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Detects how many frames are completed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vta_ManDeriveAbsAll( Vec_Int_t * p, int nWords )
+{
+ Vec_Int_t * vRes;
+ unsigned * pThis;
+ int i, w, nObjs = Vec_IntSize(p) / nWords;
+ assert( Vec_IntSize(p) % nWords == 0 );
+ vRes = Vec_IntAlloc( nObjs );
+ for ( i = 0; i < nObjs; i++ )
+ {
+ pThis = (unsigned *)Vec_IntEntryP( p, nWords * i );
+ for ( w = 0; w < nWords; w++ )
+ if ( pThis[w] )
+ break;
+ Vec_IntPush( vRes, (int)(w < nWords) );
+ }
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes/flops involved in different timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vec_IntDoubleWidth( Vec_Int_t * p, int nWords )
+{
+ int * pArray = ABC_CALLOC( int, Vec_IntSize(p) * 2 );
+ int i, w, nObjs = Vec_IntSize(p) / nWords;
+ assert( Vec_IntSize(p) % nWords == 0 );
+ for ( i = 0; i < nObjs; i++ )
+ for ( w = 0; w < nWords; w++ )
+ pArray[2 * nWords * i + w] = p->pArray[nWords * i + w];
+ ABC_FREE( p->pArray );
+ p->pArray = pArray;
+ p->nSize *= 2;
+ p->nCap = p->nSize;
+ return 2 * nWords;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vga_ManHash( int iObj, int iFrame, int nBins )
+{
+ return ((unsigned)((iObj + iFrame)*(iObj + iFrame + 1))) % nBins;
+}
+static inline int * Vga_ManLookup( Vta_Man_t * p, int iObj, int iFrame )
+{
+ Vta_Obj_t * pThis;
+ int * pPlace = p->pBins + Vga_ManHash( iObj, iFrame, p->nBins );
+ for ( pThis = Vta_ManObj(p, *pPlace);
+ pThis; pPlace = &pThis->iNext,
+ pThis = Vta_ManObj(p, *pPlace) )
+ if ( pThis->iObj == iObj && pThis->iFrame == iFrame )
+ break;
+ return pPlace;
+}
+static inline Vta_Obj_t * Vga_ManFind( Vta_Man_t * p, int iObj, int iFrame )
+{
+ int * pPlace = Vga_ManLookup( p, iObj, iFrame );
+ return Vta_ManObj(p, *pPlace);
+}
+static inline Vta_Obj_t * Vga_ManFindOrAdd( Vta_Man_t * p, int iObj, int iFrame )
+{
+ Vta_Obj_t * pThis;
+ int i, * pPlace;
+ assert( iObj >= 0 && iFrame >= -1 );
+ if ( p->nObjs == p->nObjsAlloc )
+ {
+ // resize objects
+ p->pObjs = ABC_REALLOC( Vta_Obj_t, p->pObjs, 2 * p->nObjsAlloc );
+ memset( p->pObjs + p->nObjsAlloc, 0, p->nObjsAlloc * sizeof(Vta_Obj_t) );
+ p->nObjsAlloc *= 2;
+ // rehash entries in the table
+ ABC_FREE( p->pBins );
+ p->nBins = Abc_PrimeCudd( 2 * p->nBins );
+ p->pBins = ABC_CALLOC( int, p->nBins );
+ Vta_ManForEachObj( p, pThis, i )
+ {
+ pThis->iNext = 0;
+ pPlace = Vga_ManLookup( p, pThis->iObj, pThis->iFrame );
+ assert( *pPlace == 0 );
+ *pPlace = i;
+ }
+ }
+ pPlace = Vga_ManLookup( p, iObj, iFrame );
+ if ( *pPlace )
+ return Vta_ManObj(p, *pPlace);
+ *pPlace = p->nObjs++;
+ pThis = Vta_ManObj(p, *pPlace);
+ pThis->iObj = iObj;
+ pThis->iFrame = iFrame;
+ return pThis;
+}
+static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame )
+{
+ int * pPlace = Vga_ManLookup( p, iObj, iFrame );
+ Vta_Obj_t * pThis = Vta_ManObj(p, *pPlace);
+ assert( pThis != NULL );
+ *pPlace = pThis->iNext;
+ pThis->iNext = -1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example using current assignments.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Vga_ManDeriveCex( Vta_Man_t * p )
+{
+ Abc_Cex_t * pCex;
+ Vta_Obj_t * pThis;
+ Gia_Obj_t * pObj;
+ int i;
+ pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
+ pCex->iPo = 0;
+ pCex->iFrame = p->pPars->iFrame;
+ Vta_ManForEachObjObj( p, pThis, pObj, i )
+ if ( Gia_ObjIsPi(p->pGia, pObj) && sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) )
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) );
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Remaps core into frame/node pairs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vta_ManUnsatCoreRemap( Vta_Man_t * p, Vec_Int_t * vCore )
+{
+ Vta_Obj_t * pThis;
+ int i, Entry;
+ Vec_IntForEachEntry( vCore, Entry, i )
+ {
+ pThis = Vta_ManObj( p, Entry );
+ Entry = (pThis->iFrame << p->nObjBits) | pThis->iObj;
+ Vec_IntWriteEntry( vCore, i, Entry );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares two objects by their distance.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vta_ManComputeDepthIncrease( Vta_Obj_t ** pp1, Vta_Obj_t ** pp2 )
+{
+ int Diff = (*pp1)->Prio - (*pp2)->Prio;
+ if ( Diff < 0 )
+ return -1;
+ if ( Diff > 0 )
+ return 1;
+ Diff = (*pp1) - (*pp2);
+ if ( Diff < 0 )
+ return -1;
+ if ( Diff > 0 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the object is already used.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj )
+{
+ int i;
+ unsigned * pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj );
+ for ( i = 0; i < p->nWords; i++ )
+ if ( pInfo[i] )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds predecessors of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vta_ObjPreds( Vta_Man_t * p, Vta_Obj_t * pThis, Gia_Obj_t * pObj, Vta_Obj_t ** ppThis0, Vta_Obj_t ** ppThis1 )
+{
+ *ppThis0 = NULL;
+ *ppThis1 = NULL;
+// if ( !pThis->fAdded )
+// return;
+ assert( !Gia_ObjIsPi(p->pGia, pObj) );
+ if ( Gia_ObjIsConst0(pObj) || (Gia_ObjIsCi(pObj) && pThis->iFrame == 0) )
+ return;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
+ *ppThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
+// assert( *ppThis0 && *ppThis1 );
+ return;
+ }
+ assert( Gia_ObjIsRo(p->pGia, pObj) && pThis->iFrame > 0 );
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ *ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
+// assert( *ppThis0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect const/PI/RO/AND in a topological order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vta_ManCollectNodes_rec( Vta_Man_t * p, Vta_Obj_t * pThis, Vec_Int_t * vOrder )
+{
+ Gia_Obj_t * pObj;
+ Vta_Obj_t * pThis0, * pThis1;
+ if ( pThis->fVisit )
+ return;
+ pThis->fVisit = 1;
+ pObj = Gia_ManObj( p->pGia, pThis->iObj );
+ if ( pThis->fAdded )
+ {
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ if ( pThis0 ) Vta_ManCollectNodes_rec( p, pThis0, vOrder );
+ if ( pThis1 ) Vta_ManCollectNodes_rec( p, pThis1, vOrder );
+ }
+ Vec_IntPush( vOrder, Vta_ObjId(p, pThis) );
+}
+Vec_Int_t * Vta_ManCollectNodes( Vta_Man_t * p, int f )
+{
+ Vta_Obj_t * pThis;
+ Gia_Obj_t * pObj;
+ Vec_IntClear( p->vOrder );
+ pObj = Gia_ManPo( p->pGia, 0 );
+ pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f );
+ assert( pThis != NULL );
+ assert( !pThis->fVisit );
+ Vta_ManCollectNodes_rec( p, pThis, p->vOrder );
+ assert( pThis->fVisit );
+ return p->vOrder;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vta_ManSatVerify( Vta_Man_t * p )
+{
+ Vta_Obj_t * pThis, * pThis0, * pThis1;
+ Gia_Obj_t * pObj;
+ int i;
+ Vta_ManForEachObj( p, pThis, i )
+ pThis->Value = (sat_solver2_var_value(p->pSat, i) ? VTA_VAR1 : VTA_VAR0);
+ Vta_ManForEachObjObj( p, pThis, pObj, i )
+ {
+ if ( !pThis->fAdded )
+ continue;
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ if ( pThis->Value == VTA_VAR1 )
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) );
+ else if ( pThis->Value == VTA_VAR0 )
+ assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) );
+ else assert( 0 );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ if ( pThis->iFrame == 0 )
+ assert( pThis->Value == VTA_VAR0 );
+ else if ( pThis->Value == VTA_VAR0 )
+ assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) );
+ else if ( pThis->Value == VTA_VAR1 )
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) );
+ else assert( 0 );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vta_ManProfileAddition( Vta_Man_t * p, Vec_Int_t * vTermsToAdd )
+{
+ Vta_Obj_t * pThis;
+ Gia_Obj_t * pObj;
+ // profile the added ones
+ int i, * pCounters = ABC_CALLOC( int, p->pPars->iFrame+1 );
+ Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i )
+ pCounters[pThis->iFrame]++;
+ for ( i = 0; i <= p->pPars->iFrame; i++ )
+ Abc_Print( 1, "%2d", pCounters[i] );
+ Abc_Print( 1, "***\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p, int f )
+{
+ int fVerify = 0;
+ Abc_Cex_t * pCex = NULL;
+ Vec_Int_t * vOrder, * vTermsToAdd;
+ Vec_Ptr_t * vTermsUsed, * vTermsUnused;
+ Vta_Obj_t * pThis, * pThis0, * pThis1, * pTop;
+ Gia_Obj_t * pObj;
+ int i, Counter;
+
+ if ( fVerify )
+ Vta_ManSatVerify( p );
+
+ // collect nodes in a topological order
+ vOrder = Vta_ManCollectNodes( p, f );
+ Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
+ {
+ pThis->Prio = VTA_LARGE;
+ pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0;
+ pThis->fVisit = 0;
+ }
+
+ // verify
+ if ( fVerify )
+ Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
+ {
+ if ( !pThis->fAdded )
+ continue;
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ if ( pThis->Value == VTA_VAR1 )
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) );
+ else if ( pThis->Value == VTA_VAR0 )
+ assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) );
+ else assert( 0 );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ if ( pThis->iFrame == 0 )
+ assert( pThis->Value == VTA_VAR0 );
+ else if ( pThis->Value == VTA_VAR0 )
+ assert( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) );
+ else if ( pThis->Value == VTA_VAR1 )
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) );
+ else assert( 0 );
+ }
+ }
+
+ // compute distance in reverse order
+ pThis = Vta_ManObj( p, Vec_IntEntryLast(vOrder) );
+ pThis->Prio = 1;
+ // collect used and unused terms
+ vTermsUsed = Vec_PtrAlloc( 1015 );
+ vTermsUnused = Vec_PtrAlloc( 1016 );
+ Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i )
+ {
+ // there is no unreachable states
+ assert( pThis->Prio < VTA_LARGE );
+ // skip constants and PIs
+ if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) )
+ {
+ pThis->Prio = 0; // set highest priority
+ continue;
+ }
+ // collect terminals
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
+ if ( !pThis->fAdded )
+ {
+ assert( pThis->Prio > 0 );
+ if ( Vta_ManObjIsUsed(p, pThis->iObj) )
+ Vec_PtrPush( vTermsUsed, pThis );
+ else
+ Vec_PtrPush( vTermsUnused, pThis );
+ continue;
+ }
+ // propagate
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ if ( pThis0 )
+ pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 );
+ if ( pThis1 )
+ pThis1->Prio = Abc_MinInt( pThis1->Prio, pThis->Prio + 1 );
+ }
+
+/*
+ Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i )
+ if ( pThis->Prio > 0 )
+ pThis->Prio = 10;
+*/
+/*
+ // update priorities according to reconvergence counters
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
+ {
+ Vta_Obj_t * pThis0, * pThis1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj );
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ pThis->Prio += 10000000;
+ if ( pThis0 )
+ pThis->Prio -= 1000000 * pThis0->fAdded;
+ if ( pThis1 )
+ pThis->Prio -= 1000000 * pThis1->fAdded;
+ }
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i )
+ {
+ Vta_Obj_t * pThis0, * pThis1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, pThis->iObj );
+ Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
+ pThis->Prio += 10000000;
+ if ( pThis0 )
+ pThis->Prio -= 1000000 * pThis0->fAdded;
+ if ( pThis1 )
+ pThis->Prio -= 1000000 * pThis1->fAdded;
+ }
+*/
+
+
+ // update priorities according to reconvergence counters
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
+ pThis->Prio = pThis->iObj;
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i )
+ pThis->Prio = pThis->iObj;
+
+
+ // objects with equal distance should receive priority based on number
+ // those objects whose prototypes have been added in other timeframes
+ // should have higher priority than the current object
+ Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease );
+ Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease );
+ if ( Vec_PtrSize(vTermsUsed) > 1 )
+ {
+ pThis0 = (Vta_Obj_t *)Vec_PtrEntry(vTermsUsed, 0);
+ pThis1 = (Vta_Obj_t *)Vec_PtrEntryLast(vTermsUsed);
+ assert( pThis0->Prio <= pThis1->Prio );
+ }
+ // assign the priority based on these orders
+ Counter = 1;
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
+ pThis->Prio = Counter++;
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i )
+ pThis->Prio = Counter++;
+// Abc_Print( 1, "Used %d Unused %d\n", Vec_PtrSize(vTermsUsed), Vec_PtrSize(vTermsUnused) );
+
+
+ // propagate in the direct order
+ Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
+ {
+ assert( pThis->fVisit == 0 );
+ assert( pThis->Prio < VTA_LARGE );
+ // skip terminal objects
+ if ( !pThis->fAdded )
+ continue;
+ // assumes that values are assigned!!!
+ assert( pThis->Value != 0 );
+ // propagate
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
+ pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
+ assert( pThis0 && pThis1 );
+ if ( pThis->Value == VTA_VAR1 )
+ {
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) );
+ pThis->Prio = Abc_MaxInt( pThis0->Prio, pThis1->Prio );
+ }
+ else if ( pThis->Value == VTA_VAR0 )
+ {
+ if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
+ pThis->Prio = Abc_MinInt( pThis0->Prio, pThis1->Prio ); // choice!!!
+ else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) )
+ pThis->Prio = pThis0->Prio;
+ else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
+ pThis->Prio = pThis1->Prio;
+ else assert( 0 );
+ }
+ else assert( 0 );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( pThis->iFrame > 0 )
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
+ assert( pThis0 );
+ pThis->Prio = pThis0->Prio;
+ }
+ else
+ pThis->Prio = 0;
+ }
+ else if ( Gia_ObjIsConst0(pObj) )
+ pThis->Prio = 0;
+ else
+ assert( 0 );
+ }
+
+ // select important values
+ pTop = Vta_ManObj( p, Vec_IntEntryLast(vOrder) );
+ pTop->fVisit = 1;
+ vTermsToAdd = Vec_IntAlloc( 100 );
+ Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i )
+ {
+ if ( !pThis->fVisit )
+ continue;
+ pThis->fVisit = 0;
+ assert( pThis->Prio >= 0 && pThis->Prio <= pTop->Prio );
+ // skip terminal objects
+ if ( !pThis->fAdded )
+ {
+ assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) );
+ Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) );
+ continue;
+ }
+ // assumes that values are assigned!!!
+ assert( pThis->Value != 0 );
+ // propagate
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
+ pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
+ assert( pThis0 && pThis1 );
+ if ( pThis->Value == VTA_VAR1 )
+ {
+ assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) );
+ assert( pThis0->Prio <= pThis->Prio );
+ assert( pThis1->Prio <= pThis->Prio );
+ pThis0->fVisit = 1;
+ pThis1->fVisit = 1;
+ }
+ else if ( pThis->Value == VTA_VAR0 )
+ {
+ if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
+ {
+ if ( pThis0->fVisit )
+ {
+ }
+ else if ( pThis1->fVisit )
+ {
+ }
+ else if ( pThis0->Prio <= pThis1->Prio ) // choice!!!
+ {
+ pThis0->fVisit = 1;
+ assert( pThis0->Prio == pThis->Prio );
+ }
+ else
+ {
+ pThis1->fVisit = 1;
+ assert( pThis1->Prio == pThis->Prio );
+ }
+ }
+ else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) )
+ {
+ pThis0->fVisit = 1;
+ assert( pThis0->Prio == pThis->Prio );
+ }
+ else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
+ {
+ pThis1->fVisit = 1;
+ assert( pThis1->Prio == pThis->Prio );
+ }
+ else assert( 0 );
+ }
+ else assert( 0 );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( pThis->iFrame > 0 )
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
+ assert( pThis0 );
+ pThis0->fVisit = 1;
+ assert( pThis0->Prio == pThis->Prio );
+ }
+ }
+ else if ( !Gia_ObjIsConst0(pObj) )
+ assert( 0 );
+ }
+
+ if ( p->pPars->fAddLayer )
+ {
+ // mark those currently included
+ Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i )
+ {
+ assert( pThis->fVisit == 0 );
+ pThis->fVisit = 1;
+ }
+ // add used terms, which have close relationship
+ Counter = Vec_IntSize(vTermsToAdd);
+ Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
+ {
+ if ( pThis->fVisit )
+ continue;
+ // Vta_ObjPreds( p, pThis, Gia_ManObj(p->pGia, pThis->iObj), &pThis0, &pThis1 );
+ // if ( (pThis0 && (pThis0->fAdded || pThis0->fVisit)) || (pThis1 && (pThis1->fAdded || pThis1->fVisit)) )
+ Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) );
+ }
+ // remove those currenty included
+ Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i )
+ pThis->fVisit = 0;
+ }
+// printf( "\n%d -> %d\n", Counter, Vec_IntSize(vTermsToAdd) );
+//Vec_IntReverseOrder( vTermsToAdd );
+//Vec_IntSort( vTermsToAdd, 1 );
+
+
+ // cleanup
+ Vec_PtrFree( vTermsUsed );
+ Vec_PtrFree( vTermsUnused );
+
+
+ if ( fVerify )
+ {
+ // verify
+ Vta_ManForEachObjVec( vOrder, p, pThis, i )
+ pThis->Value = VTA_VARX;
+ Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i )
+ {
+ assert( !pThis->fAdded );
+ pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0;
+ }
+ // simulate
+ Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
+ {
+ assert( pThis->fVisit == 0 );
+ if ( !pThis->fAdded )
+ continue;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
+ pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
+ assert( pThis0 && pThis1 );
+ if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) )
+ pThis->Value = VTA_VAR1;
+ else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) || Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
+ pThis->Value = VTA_VAR0;
+ else
+ pThis->Value = VTA_VARX;
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( pThis->iFrame > 0 )
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
+ assert( pThis0 );
+ if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) )
+ pThis->Value = VTA_VAR0;
+ else if ( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) )
+ pThis->Value = VTA_VAR1;
+ else
+ pThis->Value = VTA_VARX;
+ }
+ else
+ {
+ pThis->Value = VTA_VAR0;
+ }
+ }
+ else if ( Gia_ObjIsConst0(pObj) )
+ {
+ pThis->Value = VTA_VAR0;
+ }
+ else assert( 0 );
+ // double check the solver
+ assert( pThis->Value == VTA_VARX || (int)pThis->Value == (sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0) );
+ }
+
+ // check the output
+ if ( !Vta_ValIs1(pTop, Gia_ObjFaninC0(Gia_ManPo(p->pGia, 0))) )
+ Abc_Print( 1, "Vta_ManRefineAbstraction(): Terminary simulation verification failed!\n" );
+// else
+// Abc_Print( 1, "Verification OK.\n" );
+ }
+
+
+ // produce true counter-example
+ if ( pTop->Prio == 0 )
+ pCex = Vga_ManDeriveCex( p );
+ else
+ {
+// Vta_ManProfileAddition( p, vTermsToAdd );
+
+ Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i )
+ if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ Vga_ManAddClausesOne( p, pThis->iObj, pThis->iFrame );
+ sat_solver2_simplify( p->pSat );
+ }
+ p->nObjAdded += Vec_IntSize(vTermsToAdd);
+ Vec_IntFree( vTermsToAdd );
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vta_Man_t * Vga_ManStart( Gia_Man_t * pGia, Abs_Par_t * pPars )
+{
+ Vta_Man_t * p;
+ p = ABC_CALLOC( Vta_Man_t, 1 );
+ p->pGia = pGia;
+ p->pPars = pPars;
+ // internal data
+ p->nObjsAlloc = (1 << 18);
+ p->pObjs = ABC_CALLOC( Vta_Obj_t, p->nObjsAlloc );
+ p->nObjs = 1;
+ p->nBins = Abc_PrimeCudd( 2*p->nObjsAlloc );
+ p->pBins = ABC_CALLOC( int, p->nBins );
+ p->vOrder = Vec_IntAlloc( 1013 );
+ // abstraction
+ p->nObjBits = Abc_Base2Log( Gia_ManObjNum(pGia) );
+ p->nObjMask = (1 << p->nObjBits) - 1;
+ assert( Gia_ManObjNum(pGia) <= (int)p->nObjMask );
+ p->nWords = 1;
+ p->vSeens = Vec_IntStart( Gia_ManObjNum(pGia) * p->nWords );
+ p->vSeenGla = Vec_BitStart( Gia_ManObjNum(pGia) );
+ p->nSeenGla = 1;
+ p->nSeenAll = 1;
+ // other data
+ p->vCores = Vec_PtrAlloc( 100 );
+ p->pSat = sat_solver2_new();
+ p->pSat->pPrf1 = Vec_SetAlloc( 20 );
+// p->pSat->fVerbose = p->pPars->fVerbose;
+// sat_solver2_set_learntmax( p->pSat, pPars->nLearnedMax );
+ p->pSat->nLearntStart = p->pPars->nLearnedStart;
+ p->pSat->nLearntDelta = p->pPars->nLearnedDelta;
+ p->pSat->nLearntRatio = p->pPars->nLearnedPerce;
+ p->pSat->nLearntMax = p->pSat->nLearntStart;
+ // start the abstraction
+ assert( pGia->vObjClasses != NULL );
+ p->vFrames = Gia_VtaAbsToFrames( pGia->vObjClasses );
+ p->vAddedNew = Vec_IntAlloc( 1000 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Delete manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vga_ManStop( Vta_Man_t * p )
+{
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "SAT solver: Var = %d Cla = %d Conf = %d Lrn = %d Reduce = %d Cex = %d Objs+ = %d\n",
+ sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), sat_solver2_nconflicts(p->pSat),
+ sat_solver2_nlearnts(p->pSat), p->pSat->nDBreduces, p->nCexes, p->nObjAdded );
+ Vec_VecFreeP( (Vec_Vec_t **)&p->vCores );
+ Vec_VecFreeP( (Vec_Vec_t **)&p->vFrames );
+ Vec_BitFreeP( &p->vSeenGla );
+ Vec_IntFreeP( &p->vSeens );
+ Vec_IntFreeP( &p->vOrder );
+ Vec_IntFreeP( &p->vAddedNew );
+ sat_solver2_delete( p->pSat );
+ ABC_FREE( p->pBins );
+ ABC_FREE( p->pObjs );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the output literal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f )
+{
+ Gia_Obj_t * pObj = Gia_ManPo(p->pGia, 0);
+ Vta_Obj_t * pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f );
+ assert( pThis != NULL && pThis->fAdded );
+ if ( f == 0 && Gia_ObjIsRo(p->pGia, Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) )
+ return -Vta_ObjId(p, pThis);
+ return Abc_Var2Lit( Vta_ObjId(p, pThis), Gia_ObjFaninC0(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds the set of clauses involved in the UNSAT core.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Vta_ManUnsatCore( int iLit, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls )
+{
+ clock_t clk = clock();
+ Vec_Int_t * vCore;
+ int RetValue, nConfPrev = pSat->stats.conflicts;
+ if ( piRetValue )
+ *piRetValue = 1;
+ // consider special case when PO points to the flop
+ // this leads to immediate conflict in the first timeframe
+ if ( iLit < 0 )
+ {
+ vCore = Vec_IntAlloc( 1 );
+ Vec_IntPush( vCore, -iLit );
+ return vCore;
+ }
+ // solve the problem
+ RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( pnConfls )
+ *pnConfls = (int)pSat->stats.conflicts - nConfPrev;
+ if ( RetValue == l_Undef )
+ {
+ if ( piRetValue )
+ *piRetValue = -1;
+ return NULL;
+ }
+ if ( RetValue == l_True )
+ {
+ if ( piRetValue )
+ *piRetValue = 0;
+ return NULL;
+ }
+ if ( fVerbose )
+ {
+// Abc_Print( 1, "%6d", (int)pSat->stats.conflicts - nConfPrev );
+// Abc_Print( 1, "UNSAT after %7d conflicts. ", pSat->stats.conflicts );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ assert( RetValue == l_False );
+ // derive the UNSAT core
+ clk = clock();
+ vCore = (Vec_Int_t *)Sat_ProofCore( pSat );
+ if ( fVerbose )
+ {
+// Abc_Print( 1, "Core is %8d vars (out of %8d). ", Vec_IntSize(vCore), sat_solver2_nvars(pSat) );
+// Abc_PrintTime( 1, "Time", clock() - clk );
+ }
+ return vCore;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames, int nConfls, int nCexes, clock_t Time, int fVerbose )
+{
+ unsigned * pInfo;
+ int * pCountAll = NULL, * pCountUni = NULL;
+ int i, iFrame, iObj, Entry, fChanges = 0;
+ // print info about frames
+ if ( vCore )
+ {
+ pCountAll = ABC_CALLOC( int, nFrames + 1 );
+ pCountUni = ABC_CALLOC( int, nFrames + 1 );
+ Vec_IntForEachEntry( vCore, Entry, i )
+ {
+ iObj = (Entry & p->nObjMask);
+ iFrame = (Entry >> p->nObjBits);
+ assert( iFrame < nFrames );
+ pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj );
+ if ( !Abc_InfoHasBit(pInfo, iFrame) )
+ {
+ Abc_InfoSetBit( pInfo, iFrame );
+ pCountUni[iFrame+1]++;
+ pCountUni[0]++;
+ p->nSeenAll++;
+ }
+ pCountAll[iFrame+1]++;
+ pCountAll[0]++;
+ if ( !Vec_BitEntry(p->vSeenGla, iObj) )
+ {
+ Vec_BitWriteEntry(p->vSeenGla, iObj, 1);
+ p->nSeenGla++;
+ fChanges = 1;
+ }
+ }
+ }
+ if ( !fVerbose )
+ {
+ ABC_FREE( pCountAll );
+ ABC_FREE( pCountUni );
+ return fChanges;
+ }
+
+ if ( Abc_FrameIsBatchMode() && !vCore )
+ return fChanges;
+
+// Abc_Print( 1, "%5d%5d", pCountAll[0], pCountUni[0] );
+ Abc_Print( 1, "%4d :", nFrames-1 );
+ Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenGla / (Gia_ManRegNum(p->pGia) + Gia_ManAndNum(p->pGia) + 1)) );
+ Abc_Print( 1, "%6d", p->nSeenGla );
+ Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * p->nSeenAll / (p->nSeenGla * nFrames)) );
+ Abc_Print( 1, "%8d", nConfls );
+ if ( nCexes == 0 )
+ Abc_Print( 1, "%5c", '-' );
+ else
+ Abc_Print( 1, "%5d", nCexes );
+// Abc_Print( 1, " %9d", sat_solver2_nvars(p->pSat) );
+ Abc_PrintInt( sat_solver2_nvars(p->pSat) );
+ Abc_PrintInt( sat_solver2_nclauses(p->pSat) );
+ Abc_PrintInt( sat_solver2_nlearnts(p->pSat) );
+ if ( vCore == NULL )
+ {
+ Abc_Print( 1, " ..." );
+// for ( k = 0; k < 7; k++ )
+// Abc_Print( 1, " " );
+ Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC );
+ Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) );
+ Abc_Print( 1, "\r" );
+ }
+ else
+ {
+ Abc_PrintInt( pCountAll[0] );
+/*
+ if ( nFrames > 7 )
+ {
+ for ( k = 0; k < 3; k++ )
+ Abc_Print( 1, "%5d", pCountAll[k+1] );
+ Abc_Print( 1, " ..." );
+ for ( k = nFrames-3; k < nFrames; k++ )
+ Abc_Print( 1, "%5d", pCountAll[k+1] );
+ }
+ else
+ {
+ for ( k = 0; k < nFrames; k++ )
+ Abc_Print( 1, "%5d", pCountAll[k+1] );
+ for ( k = nFrames; k < 7; k++ )
+ Abc_Print( 1, " " );
+ }
+*/
+ Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC );
+ Abc_Print( 1, "%5.1f GB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<30) );
+ Abc_Print( 1, "\n" );
+ }
+ fflush( stdout );
+
+ if ( vCore )
+ {
+ ABC_FREE( pCountAll );
+ ABC_FREE( pCountUni );
+ }
+ return fChanges;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vga_ManAddClausesOne( Vta_Man_t * p, int iObj, int iFrame )
+{
+ Vta_Obj_t * pThis0, * pThis1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj );
+ Vta_Obj_t * pThis = Vga_ManFindOrAdd( p, iObj, iFrame );
+ int iThis0, iMainVar = Vta_ObjId(p, pThis);
+ assert( pThis->iObj == iObj && pThis->iFrame == iFrame );
+ if ( pThis->fAdded )
+ return;
+ pThis->fAdded = 1;
+ Vec_IntPush( p->vAddedNew, iMainVar );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame );
+ iThis0 = Vta_ObjId(p, pThis0);
+ pThis1 = Vga_ManFindOrAdd( p, Gia_ObjFaninId1p(p->pGia, pObj), iFrame );
+ sat_solver2_add_and( p->pSat, iMainVar, iThis0, Vta_ObjId(p, pThis1),
+ Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0, iMainVar );
+ }
+ else if ( Gia_ObjIsRo(p->pGia, pObj) )
+ {
+ if ( iFrame == 0 )
+ {
+ if ( p->pPars->fUseTermVars )
+ {
+ pThis0 = Vga_ManFindOrAdd( p, iObj, -1 );
+ sat_solver2_add_constraint( p->pSat, iMainVar, Vta_ObjId(p, pThis0), 1, 0, iMainVar );
+ }
+ else
+ {
+ sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar );
+ }
+ }
+ else
+ {
+ pObj = Gia_ObjRoToRi( p->pGia, pObj );
+ pThis0 = Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), iFrame-1 );
+ sat_solver2_add_buffer( p->pSat, iMainVar, Vta_ObjId(p, pThis0), Gia_ObjFaninC0(pObj), 0, iMainVar );
+ }
+ }
+ else if ( Gia_ObjIsConst0(pObj) )
+ {
+ sat_solver2_add_const( p->pSat, iMainVar, 1, 0, iMainVar );
+ }
+ else //if ( !Gia_ObjIsPi(p->pGia, pObj) )
+ assert( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vga_ManLoadSlice( Vta_Man_t * p, Vec_Int_t * vOne, int Lift )
+{
+ int i, Entry;
+ Vec_IntForEachEntry( vOne, Entry, i )
+ Vga_ManAddClausesOne( p, Entry & p->nObjMask, (Entry >> p->nObjBits) + Lift );
+ sat_solver2_simplify( p->pSat );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vga_ManPrintCore( Vta_Man_t * p, Vec_Int_t * vCore, int Lift )
+{
+ int i, Entry, iObj, iFrame;
+ Vec_IntForEachEntry( vCore, Entry, i )
+ {
+ iObj = (Entry & p->nObjMask);
+ iFrame = (Entry >> p->nObjBits);
+ Abc_Print( 1, "%d*%d ", iObj, iFrame+Lift );
+ }
+ Abc_Print( 1, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vga_ManRollBack( Vta_Man_t * p, int nObjOld )
+{
+ Vta_Obj_t * pThis = p->pObjs + nObjOld;
+ Vta_Obj_t * pLimit = p->pObjs + p->nObjs;
+ int i, Entry;
+ for ( ; pThis < pLimit; pThis++ )
+ Vga_ManDelete( p, pThis->iObj, pThis->iFrame );
+ memset( p->pObjs + nObjOld, 0, sizeof(Vta_Obj_t) * (p->nObjs - nObjOld) );
+ p->nObjs = nObjOld;
+ Vec_IntForEachEntry( p->vAddedNew, Entry, i )
+ if ( Entry < p->nObjs )
+ {
+ pThis = Vta_ManObj(p, Entry);
+ assert( pThis->fAdded == 1 );
+ pThis->fAdded = 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_VtaSendAbsracted( Vta_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p );
+ Gia_Man_t * pAbs;
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Sending abstracted model...\n" );
+ // create obj classes
+ Vec_IntFreeP( &p->pGia->vObjClasses );
+ p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores );
+ // create gate classes
+ Vec_IntFreeP( &p->pGia->vGateClasses );
+ p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses );
+ Vec_IntFreeP( &p->pGia->vObjClasses );
+ // create abstrated model
+ pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses );
+ Vec_IntFreeP( &p->pGia->vGateClasses );
+ // send it out
+ Gia_ManToBridgeAbsNetlist( stdout, pAbs );
+ Gia_ManStop( pAbs );
+}
+void Gia_VtaSendCancel( Vta_Man_t * p, int fVerbose )
+{
+ extern int Gia_ManToBridgeBadAbs( FILE * pFile );
+ assert( Abc_FrameIsBridgeMode() );
+// if ( fVerbose )
+// Abc_Print( 1, "Cancelling previously sent model...\n" );
+ Gia_ManToBridgeBadAbs( stdout );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Send abstracted model or send cancel.]
+
+ Description [Counter-example will be sent automatically when &vta terminates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_VtaDumpAbsracted( Vta_Man_t * p, int fVerbose )
+{
+ char * pFileNameDef = "vabs.aig";
+ char * pFileName = p->pPars->pFileVabs ? p->pPars->pFileVabs : pFileNameDef;
+ Gia_Man_t * pAbs;
+ if ( fVerbose )
+ Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName );
+ // create obj classes
+ Vec_IntFreeP( &p->pGia->vObjClasses );
+ p->pGia->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores );
+ // create gate classes
+ Vec_IntFreeP( &p->pGia->vGateClasses );
+ p->pGia->vGateClasses = Gia_VtaConvertToGla( p->pGia, p->pGia->vObjClasses );
+ Vec_IntFreeP( &p->pGia->vObjClasses );
+ // create abstrated model
+ pAbs = Gia_ManDupAbsGates( p->pGia, p->pGia->vGateClasses );
+ Vec_IntFreeP( &p->pGia->vGateClasses );
+ // send it out
+ Gia_WriteAiger( pAbs, pFileName, 0, 0 );
+ Gia_ManStop( pAbs );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Print memory report.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_VtaPrintMemory( Vta_Man_t * p )
+{
+ double memTot = 0;
+ double memAig = Gia_ManObjNum(p->pGia) * sizeof(Gia_Obj_t);
+ double memSat = sat_solver2_memory( p->pSat, 1 );
+ double memPro = sat_solver2_memory_proof( p->pSat );
+ double memMap = p->nObjsAlloc * sizeof(Vta_Obj_t) + p->nBins * sizeof(int);
+ double memOth = sizeof(Vta_Man_t);
+ memOth += Vec_IntCap(p->vOrder) * sizeof(int);
+ memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vFrames );
+ memOth += Vec_BitCap(p->vSeenGla) * sizeof(int);
+ memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCores );
+ memOth += Vec_IntCap(p->vAddedNew) * sizeof(int);
+ memTot = memAig + memSat + memPro + memMap + memOth;
+ ABC_PRMP( "Memory: AIG ", memAig, memTot );
+ ABC_PRMP( "Memory: SAT ", memSat, memTot );
+ ABC_PRMP( "Memory: Proof ", memPro, memTot );
+ ABC_PRMP( "Memory: Map ", memMap, memTot );
+ ABC_PRMP( "Memory: Other ", memOth, memTot );
+ ABC_PRMP( "Memory: TOTAL ", memTot, memTot );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes/flops involved in different timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_VtaPerformInt( Gia_Man_t * pAig, Abs_Par_t * pPars )
+{
+ Vta_Man_t * p;
+ Vec_Int_t * vCore;
+ Abc_Cex_t * pCex = NULL;
+ int i, f, nConfls, Status, nObjOld, RetValue = -1, nCountNoChange = 0, fOneIsSent = 0;
+ clock_t clk = clock(), clk2;
+ // preconditions
+ assert( Gia_ManPoNum(pAig) == 1 );
+ assert( pPars->nFramesMax == 0 || pPars->nFramesStart <= pPars->nFramesMax );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) )
+ {
+ if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) )
+ {
+ printf( "Sequential miter is trivially UNSAT.\n" );
+ return 1;
+ }
+ ABC_FREE( pAig->pCexSeq );
+ pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 );
+ printf( "Sequential miter is trivially SAT.\n" );
+ return 0;
+ }
+
+ // compute intial abstraction
+ if ( pAig->vObjClasses == NULL )
+ {
+ pAig->vObjClasses = Vec_IntAlloc( 5 );
+ Vec_IntPush( pAig->vObjClasses, 1 );
+ Vec_IntPush( pAig->vObjClasses, 3 );
+ Vec_IntPush( pAig->vObjClasses, 4 );
+ Vec_IntPush( pAig->vObjClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)) );
+ }
+ // start the manager
+ p = Vga_ManStart( pAig, pPars );
+ // set runtime limit
+ if ( p->pPars->nTimeOut )
+ sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + clock() );
+ // perform initial abstraction
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "Running variable-timeframe abstraction (VTA) with the following parameters:\n" );
+ Abc_Print( 1, "FramePast = %d FrameMax = %d ConfMax = %d Timeout = %d RatioMin = %d %%\n",
+ pPars->nFramesPast, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin );
+ Abc_Print( 1, "LearnStart = %d LearnDelta = %d LearnRatio = %d %%.\n",
+ pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce );
+// Abc_Print( 1, "Frame %% Abs %% Confl Cex SatVar Core F0 F1 F2 ...\n" );
+ Abc_Print( 1, " Frame %% Abs %% Confl Cex Vars Clas Lrns Core Time Mem\n" );
+ }
+ assert( Vec_PtrSize(p->vFrames) > 0 );
+ for ( f = i = 0; !p->pPars->nFramesMax || f < p->pPars->nFramesMax; f++ )
+ {
+ int nConflsBeg = sat_solver2_nconflicts(p->pSat);
+ p->pPars->iFrame = f;
+ // realloc storage for abstraction marks
+ if ( f == p->nWords * 32 )
+ p->nWords = Vec_IntDoubleWidth( p->vSeens, p->nWords );
+
+ // create bookmark to be used for rollback
+ nObjOld = p->nObjs;
+ sat_solver2_bookmark( p->pSat );
+ Vec_IntClear( p->vAddedNew );
+
+ // load new timeframe
+ Vga_ManAddClausesOne( p, 0, f );
+ if ( f < Vec_PtrSize(p->vFrames) )
+ Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vFrames, f), 0 );
+ else
+ {
+ for ( i = 1; i <= Abc_MinInt(p->pPars->nFramesPast, f); i++ )
+ Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vCores, f-i), i );
+ }
+
+ // iterate as long as there are counter-examples
+ for ( i = 0; ; i++ )
+ {
+ clk2 = clock();
+ vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, &nConfls );
+ assert( (vCore != NULL) == (Status == 1) );
+ if ( Status == -1 ) // resource limit is reached
+ {
+ Vga_ManRollBack( p, nObjOld );
+ goto finish;
+ }
+ // check timeout
+ if ( p->pSat->nRuntimeLimit && clock() > p->pSat->nRuntimeLimit )
+ {
+ Vga_ManRollBack( p, nObjOld );
+ goto finish;
+ }
+ if ( vCore != NULL )
+ {
+ p->timeUnsat += clock() - clk2;
+ break;
+ }
+ p->timeSat += clock() - clk2;
+ assert( Status == 0 );
+ p->nCexes++;
+ // perform the refinement
+ clk2 = clock();
+ pCex = Vta_ManRefineAbstraction( p, f );
+ p->timeCex += clock() - clk2;
+ if ( pCex != NULL )
+ goto finish;
+ // print the result (do not count it towards change)
+ Vta_ManAbsPrintFrame( p, NULL, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose );
+ }
+ assert( Status == 1 );
+ // valid core is obtained
+ Vta_ManUnsatCoreRemap( p, vCore );
+ Vec_IntSort( vCore, 1 );
+ // update the SAT solver
+ sat_solver2_rollback( p->pSat );
+ // update storage
+ Vga_ManRollBack( p, nObjOld );
+ // load this timeframe
+ Vga_ManLoadSlice( p, vCore, 0 );
+ Vec_IntFree( vCore );
+
+ // run SAT solver
+ clk2 = clock();
+ vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls );
+ p->timeUnsat += clock() - clk2;
+ assert( (vCore != NULL) == (Status == 1) );
+ if ( Status == -1 ) // resource limit is reached
+ break;
+ if ( Status == 0 )
+ {
+ Vta_ManSatVerify( p );
+ // make sure, there was no initial abstraction (otherwise, it was invalid)
+ assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart );
+ pCex = Vga_ManDeriveCex( p );
+ break;
+ }
+ // add the core
+ Vta_ManUnsatCoreRemap( p, vCore );
+ // add in direct topological order
+ Vec_IntSort( vCore, 1 );
+ Vec_PtrPush( p->vCores, vCore );
+ // print the result
+ if ( Vta_ManAbsPrintFrame( p, vCore, f+1, sat_solver2_nconflicts(p->pSat)-nConflsBeg, i, clock() - clk, p->pPars->fVerbose ) )
+ {
+ // reset the counter of frames without change
+ nCountNoChange = 1;
+ p->pPars->nFramesNoChange = 0;
+ }
+ else if ( ++nCountNoChange == 2 ) // time to send
+ {
+ p->pPars->nFramesNoChange++;
+ if ( Abc_FrameIsBridgeMode() )
+ {
+ // cancel old one if it was sent
+ if ( fOneIsSent )
+ Gia_VtaSendCancel( p, pPars->fVerbose );
+ // send new one
+ Gia_VtaSendAbsracted( p, pPars->fVerbose );
+ fOneIsSent = 1;
+ }
+ }
+ // dump the model
+ if ( p->pPars->fDumpVabs && (f & 1) )
+ {
+ char Command[1000];
+ Abc_FrameSetStatus( -1 );
+ Abc_FrameSetCex( NULL );
+ Abc_FrameSetNFrames( f+1 );
+ sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((p->pPars->pFileVabs ? p->pPars->pFileVabs : "vtabs.aig"), ".status") );
+ Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
+ Gia_VtaDumpAbsracted( p, pPars->fVerbose );
+ }
+ // check if the number of objects is below limit
+ if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 )
+ {
+ Status = -1;
+ break;
+ }
+ }
+finish:
+ // analize the results
+ if ( pCex == NULL )
+ {
+ if ( p->pPars->fVerbose && Status == -1 )
+ printf( "\n" );
+ if ( Vec_PtrSize(p->vCores) == 0 )
+ Abc_Print( 1, "Abstraction is not produced because first frame is not solved. " );
+ else
+ {
+ assert( Vec_PtrSize(p->vCores) > 0 );
+// if ( pAig->vObjClasses != NULL )
+// Abc_Print( 1, "Replacing the old abstraction by a new one.\n" );
+ Vec_IntFreeP( &pAig->vObjClasses );
+ pAig->vObjClasses = Gia_VtaFramesToAbs( (Vec_Vec_t *)p->vCores );
+ if ( Status == -1 )
+ {
+ if ( p->pPars->nTimeOut && clock() >= p->pSat->nRuntimeLimit )
+ Abc_Print( 1, "Timeout %d sec in frame %d with a %d-stable abstraction. ", p->pPars->nTimeOut, f, p->pPars->nFramesNoChange );
+ else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit )
+ Abc_Print( 1, "Exceeded %d conflicts in frame %d with a %d-stable abstraction. ", pPars->nConfLimit, f, p->pPars->nFramesNoChange );
+ else if ( p->nSeenGla >= Gia_ManCandNum(pAig) * (100-pPars->nRatioMin) / 100 )
+ Abc_Print( 1, "The ratio of abstracted objects is less than %d %% in frame %d. ", pPars->nRatioMin, f );
+ else
+ Abc_Print( 1, "Abstraction stopped for unknown reason in frame %d. ", f );
+ }
+ else
+ {
+ p->pPars->iFrame++;
+ Abc_Print( 1, "VTA completed %d frames with a %d-stable abstraction. ", f, p->pPars->nFramesNoChange );
+ }
+ }
+ }
+ else
+ {
+ if ( p->pPars->fVerbose )
+ printf( "\n" );
+ ABC_FREE( p->pGia->pCexSeq );
+ p->pGia->pCexSeq = pCex;
+ if ( !Gia_ManVerifyCex( p->pGia, pCex, 0 ) )
+ Abc_Print( 1, " Gia_VtaPerform(): CEX verification has failed!\n" );
+ Abc_Print( 1, "Counter-example detected in frame %d. ", f );
+ p->pPars->iFrame = pCex->iFrame - 1;
+ Vec_IntFreeP( &pAig->vObjClasses );
+ RetValue = 0;
+ }
+ Abc_PrintTime( 1, "Time", clock() - clk );
+
+ if ( p->pPars->fVerbose )
+ {
+ p->timeOther = (clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex;
+ ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat, clock() - clk );
+ ABC_PRTP( "Runtime: Solver SAT ", p->timeSat, clock() - clk );
+ ABC_PRTP( "Runtime: Refinement ", p->timeCex, clock() - clk );
+ ABC_PRTP( "Runtime: Other ", p->timeOther, clock() - clk );
+ ABC_PRTP( "Runtime: TOTAL ", clock() - clk, clock() - clk );
+ Gia_VtaPrintMemory( p );
+ }
+
+ Vga_ManStop( p );
+ fflush( stdout );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes/flops involved in different timeframes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_VtaPerform( Gia_Man_t * pAig, Abs_Par_t * pPars )
+{
+ int RetValue = -1;
+ if ( pAig->vObjClasses == NULL && pPars->fUseRollback )
+ {
+ int nFramesMaxOld = pPars->nFramesMax;
+ pPars->nFramesMax = pPars->nFramesStart;
+ RetValue = Gia_VtaPerformInt( pAig, pPars );
+ pPars->nFramesMax = nFramesMaxOld;
+ }
+ if ( RetValue == 0 )
+ return RetValue;
+ return Gia_VtaPerformInt( pAig, pPars );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/abs/module.make b/src/proof/abs/module.make
new file mode 100644
index 00000000..4e652afd
--- /dev/null
+++ b/src/proof/abs/module.make
@@ -0,0 +1,15 @@
+SRC += src/proof/abs/abs.c \
+ src/proof/abs/absDup.c \
+ src/proof/abs/absGla.c \
+ src/proof/abs/absGlaOld.c \
+ src/proof/abs/absIter.c \
+ src/proof/abs/absOldCex.c \
+ src/proof/abs/absOldRef.c \
+ src/proof/abs/absOldSat.c \
+ src/proof/abs/absOldSim.c \
+ src/proof/abs/absOut.c \
+ src/proof/abs/absPth.c \
+ src/proof/abs/absRef.c \
+ src/proof/abs/absRef2.c \
+ src/proof/abs/absVta.c \
+ src/proof/abs/absUtil.c