summaryrefslogtreecommitdiffstats
path: root/src/aig/saig/saigBmc.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2010-11-01 01:35:04 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2010-11-01 01:35:04 -0700
commit6130e39b18b5f53902e4eab14f6d5cdde5219563 (patch)
tree0db0628479a1b750e9af1f66cb8379ebd0913d31 /src/aig/saig/saigBmc.c
parentf0e77f6797c0504b0da25a56152b707d3357f386 (diff)
downloadabc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.gz
abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.bz2
abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.zip
initial commit of public abc
Diffstat (limited to 'src/aig/saig/saigBmc.c')
-rw-r--r--src/aig/saig/saigBmc.c917
1 files changed, 215 insertions, 702 deletions
diff --git a/src/aig/saig/saigBmc.c b/src/aig/saig/saigBmc.c
index ac1cbe5b..8aa3af80 100644
--- a/src/aig/saig/saigBmc.c
+++ b/src/aig/saig/saigBmc.c
@@ -19,375 +19,72 @@
***********************************************************************/
#include "saig.h"
+#include "fra.h"
#include "cnf.h"
#include "satStore.h"
-#include "ssw.h"
+
+ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-#define AIG_VISITED ((Aig_Obj_t *)(ABC_PTRUINT_T)1)
-
-typedef struct Saig_Bmc_t_ Saig_Bmc_t;
-struct Saig_Bmc_t_
-{
- // parameters
- int nFramesMax; // the max number of timeframes to consider
- int nNodesMax; // the max number of nodes to add
- int nConfMaxOne; // the max number of conflicts at a target
- int nConfMaxAll; // the max number of conflicts for all targets
- int fVerbose; // enables verbose output
- // AIG managers
- Aig_Man_t * pAig; // the user's AIG manager
- Aig_Man_t * pFrm; // Frames manager
- Vec_Ptr_t * vVisited; // nodes visited in Frames
- // node mapping
- int nObjs; // the largest number of an AIG object
- Vec_Ptr_t * vAig2Frm; // mapping of AIG nodees into Frames nodes
-// Vec_Str_t * vAig2Frm2; // mapping of AIG nodees into Frames nodes
- // SAT solver
- sat_solver * pSat; // SAT solver
- int nSatVars; // the number of used SAT variables
- Vec_Int_t * vObj2Var; // mapping of frames objects in CNF variables
- // subproblems
- Vec_Ptr_t * vTargets; // targets to be solved in this interval
- int iFramePrev; // previous frame
- int iFrameLast; // last frame
- int iOutputLast; // last output
- int iFrameFail; // failed frame
- int iOutputFail; // failed output
-};
-
-static inline int Saig_BmcSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vObj2Var, pObj->Id ); }
-static inline void Saig_BmcSetSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vObj2Var, pObj->Id, Num); }
-
-static inline Aig_Obj_t * Saig_BmcObjFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { return Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); }
-static inline void Saig_BmcObjSetFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); }
-
-static inline Aig_Obj_t * Saig_BmcObjChild0( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)); }
-static inline Aig_Obj_t * Saig_BmcObjChild1( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)); }
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define ABS_ZER 1
-#define ABS_ONE 2
-#define ABS_UND 3
-
-static inline int Abs_ManSimInfoNot( int Value )
-{
- if ( Value == ABS_ZER )
- return ABS_ONE;
- if ( Value == ABS_ONE )
- return ABS_ZER;
- return ABS_UND;
-}
-
-static inline int Abs_ManSimInfoAnd( int Value0, int Value1 )
-{
- if ( Value0 == ABS_ZER || Value1 == ABS_ZER )
- return ABS_ZER;
- if ( Value0 == ABS_ONE && Value1 == ABS_ONE )
- return ABS_ONE;
- return ABS_UND;
-}
-
-static inline int Abs_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
-{
- unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame );
- return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1));
-}
-
-static inline void Abs_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value )
-{
- unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame );
- assert( Value >= ABS_ZER && Value <= ABS_UND );
- Value ^= Abs_ManSimInfoGet( vSimInfo, pObj, iFrame );
- pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1));
-}
-
/**Function*************************************************************
- Synopsis [Performs ternary simulation for one node.]
+ Synopsis [Create timeframes of the manager for BMC.]
- Description []
+ Description [The resulting manager is combinational. POs correspond to \
+ the property outputs in each time-frame.]
SideEffects []
SeeAlso []
***********************************************************************/
-int Abs_ManExtendOneEval_rec( Vec_Ptr_t * vSimInfo, Aig_Man_t * p, Aig_Obj_t * pObj, int iFrame )
+Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames )
{
- int Value0, Value1, Value;
- Value = Abs_ManSimInfoGet( vSimInfo, pObj, iFrame );
- if ( Value )
- return Value;
- if ( Aig_ObjIsPi(pObj) )
- {
- assert( Saig_ObjIsLo(p, pObj) );
- Value = Abs_ManExtendOneEval_rec( vSimInfo, p, Saig_ObjLoToLi(p, pObj), iFrame-1 );
- Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value );
- return Value;
- }
- Value0 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin0(pObj), iFrame );
- if ( Aig_ObjFaninC0(pObj) )
- Value0 = Abs_ManSimInfoNot( Value0 );
- if ( Aig_ObjIsPo(pObj) )
- {
- Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 );
- return Value0;
- }
- assert( Aig_ObjIsNode(pObj) );
- if ( Value0 == ABS_ZER )
- Value = ABS_ZER;
- else
- {
- Value1 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin1(pObj), iFrame );
- if ( Aig_ObjFaninC1(pObj) )
- Value1 = Abs_ManSimInfoNot( Value1 );
- Value = Abs_ManSimInfoAnd( Value0, Value1 );
- }
- Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value );
- assert( Value );
- return Value;
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs ternary simulation for one design.]
-
- Description [The returned array contains the result of ternary
- simulation for all the frames where the output could be proved 0.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Abs_ManTernarySimulate( Aig_Man_t * p, int nFramesMax, int fVerbose )
-{
- Vec_Ptr_t * vSimInfo;
- Aig_Obj_t * pObj;
- int i, f, nFramesLimit, nFrameWords;
- int clk = clock();
- assert( Aig_ManRegNum(p) > 0 );
- // the maximum number of frames will be determined to use at most 200Mb of RAM
- nFramesLimit = 1 + (200000000 * 4)/Aig_ManObjNum(p);
- nFramesLimit = ABC_MIN( nFramesLimit, nFramesMax );
- nFrameWords = Aig_BitWordNum( 2 * Aig_ManObjNum(p) );
- // allocate simulation info
- vSimInfo = Vec_PtrAlloc( nFramesLimit );
- for ( f = 0; f < nFramesLimit; f++ )
- {
- Vec_PtrPush( vSimInfo, ABC_CALLOC(unsigned, nFrameWords) );
- if ( f == 0 )
- {
- Saig_ManForEachLo( p, pObj, i )
- Abs_ManSimInfoSet( vSimInfo, pObj, 0, ABS_ZER );
- }
- Abs_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, ABS_ONE );
- Saig_ManForEachPi( p, pObj, i )
- Abs_ManSimInfoSet( vSimInfo, pObj, f, ABS_UND );
- Saig_ManForEachPo( p, pObj, i )
- Abs_ManExtendOneEval_rec( vSimInfo, p, pObj, f );
- // check if simulation has derived at least one fail or unknown
- Saig_ManForEachPo( p, pObj, i )
- if ( Abs_ManSimInfoGet(vSimInfo, pObj, f) != ABS_ZER )
- {
- if ( fVerbose )
- {
- printf( "Ternary sim found non-zero output in frame %d. Used %5.2f Mb. ",
- f, 0.25 * (f+1) * Aig_ManObjNum(p) / (1<<20) );
- ABC_PRT( "Time", clock() - clk );
- }
- return vSimInfo;
- }
- }
- if ( fVerbose )
- {
- printf( "Ternary sim proved all outputs in the first %d frames. Used %5.2f Mb. ",
- nFramesLimit, 0.25 * nFramesLimit * Aig_ManObjNum(p) / (1<<20) );
- ABC_PRT( "Time", clock() - clk );
- }
- return vSimInfo;
-}
-
-/**Function*************************************************************
-
- Synopsis [Free the array of simulation info.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abs_ManFreeAray( Vec_Ptr_t * p )
-{
- void * pTemp;
- int i;
- Vec_PtrForEachEntry( p, pTemp, i )
- ABC_FREE( pTemp );
- Vec_PtrFree( p );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Create manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Saig_Bmc_t * Saig_BmcManStart( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose )
-{
- Saig_Bmc_t * p;
- Aig_Obj_t * pObj;
- int i, Lit;
-// assert( Aig_ManRegNum(pAig) > 0 );
- p = (Saig_Bmc_t *)ABC_ALLOC( char, sizeof(Saig_Bmc_t) );
- memset( p, 0, sizeof(Saig_Bmc_t) );
- // set parameters
- p->nFramesMax = nFramesMax;
- p->nNodesMax = nNodesMax;
- p->nConfMaxOne = nConfMaxOne;
- p->nConfMaxAll = nConfMaxAll;
- p->fVerbose = fVerbose;
- p->pAig = pAig;
- p->nObjs = Aig_ManObjNumMax(pAig);
- // create node and variable mappings
- p->vAig2Frm = Vec_PtrAlloc( 0 );
- Vec_PtrFill( p->vAig2Frm, 5 * p->nObjs, NULL );
- p->vObj2Var = Vec_IntAlloc( 0 );
- Vec_IntFill( p->vObj2Var, 5 * p->nObjs, 0 );
- // start the AIG manager and map primary inputs
- p->pFrm = Aig_ManStart( 5 * p->nObjs );
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, f;
+ assert( Saig_ManRegNum(pAig) > 0 );
+ pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames );
+ // map the constant node
+ Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames );
+ // create variables for register outputs
Saig_ManForEachLo( pAig, pObj, i )
- Saig_BmcObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrm) );
- // create SAT solver
- p->nSatVars = 1;
- p->pSat = sat_solver_new();
- sat_solver_setnvars( p->pSat, 2000 );
- Lit = toLit( p->nSatVars );
- sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
- Saig_BmcSetSatNum( p, Aig_ManConst1(p->pFrm), p->nSatVars++ );
- // other data structures
- p->vTargets = Vec_PtrAlloc( 0 );
- p->vVisited = Vec_PtrAlloc( 0 );
- p->iOutputFail = -1;
- p->iFrameFail = -1;
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Delete manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Saig_BmcManStop( Saig_Bmc_t * p )
-{
-// Aig_Obj_t * pObj;
-// int i, f, Counter = 0;
-// int i, Counter = 0;
-// for ( i = 0; i < p->vAig2Frm2->nSize; i++ )
-// Counter += (p->vAig2Frm2->pArray[i] != 0);
-// for ( i = 0; i < p->vAig2Frm->nSize; i++ )
-// Counter += (p->vAig2Frm->pArray[i] != NULL);
-// printf( "Objs = %d. Nodes = %d. Frames = %d. Used = %d. Non-empty = %d.\n",
-// p->nObjs, Aig_ManNodeNum(p->pAig), p->iFrameLast, p->vAig2Frm->nSize, Counter );
-
-/*
- Aig_ManForEachObj( p->pAig, pObj, i )
- {
- int Last = -1;
- for ( f = 0; f <= p->iFrameLast; f++ )
- if ( Saig_BmcObjFrame( p, pObj, f ) )
- Last = f;
- if ( i % 50 == 0 )
- printf( "%d ", Last );
- }
- printf( "\n" );
-*/
-
- Aig_ManStop( p->pFrm );
- Vec_PtrFree( p->vAig2Frm );
-// Vec_StrFree( p->vAig2Frm2 );
- Vec_IntFree( p->vObj2Var );
- sat_solver_delete( p->pSat );
- Vec_PtrFree( p->vTargets );
- Vec_PtrFree( p->vVisited );
- ABC_FREE( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Explores the possibility of constructing the output.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i )
-{
- Aig_Obj_t * pRes, * p0, * p1, * pConst1 = Aig_ManConst1(p->pAig);
- pRes = Saig_BmcObjFrame( p, pObj, i );
- if ( pRes != NULL )
- return pRes;
- if ( Saig_ObjIsPi( p->pAig, pObj ) )
- pRes = AIG_VISITED;
- else if ( Saig_ObjIsLo( p->pAig, pObj ) )
- pRes = Saig_BmcIntervalExplore_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 );
- else if ( Aig_ObjIsPo( pObj ) )
- {
- pRes = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i );
- if ( pRes != AIG_VISITED )
- pRes = Saig_BmcObjChild0( p, pObj, i );
- }
- else
+ pObj->pData = Aig_ManConst0( pFrames );
+ // add timeframes
+ for ( f = 0; f < nFrames; f++ )
{
- p0 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i );
- if ( p0 != AIG_VISITED )
- p0 = Saig_BmcObjChild0( p, pObj, i );
- p1 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin1(pObj), i );
- if ( p1 != AIG_VISITED )
- p1 = Saig_BmcObjChild1( p, pObj, i );
-
- if ( p0 == Aig_Not(p1) )
- pRes = Aig_ManConst0(p->pFrm);
- else if ( Aig_Regular(p0) == pConst1 )
- pRes = (p0 == pConst1) ? p1 : Aig_ManConst0(p->pFrm);
- else if ( Aig_Regular(p1) == pConst1 )
- pRes = (p1 == pConst1) ? p0 : Aig_ManConst0(p->pFrm);
- else
- pRes = AIG_VISITED;
-
- if ( pRes != AIG_VISITED && !Aig_ObjIsConst1(Aig_Regular(pRes)) )
- pRes = AIG_VISITED;
+ // create PI nodes for this frame
+ Saig_ManForEachPi( pAig, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pFrames );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ // create POs for this frame
+ Saig_ManForEachPo( pAig, pObj, i )
+ Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) );
+ if ( f == nFrames - 1 )
+ break;
+ // save register inputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ // transfer to register outputs
+ Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
+ pObjLo->pData = pObjLi->pData;
}
- Saig_BmcObjSetFrame( p, pObj, i, pRes );
- return pRes;
+ Aig_ManCleanup( pFrames );
+ return pFrames;
}
/**Function*************************************************************
- Synopsis [Performs the actual construction of the output.]
+ Synopsis [Returns the number of internal nodes that are not counted yet.]
Description []
@@ -396,271 +93,88 @@ Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i
SeeAlso []
***********************************************************************/
-Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited )
+int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
{
- Aig_Obj_t * pRes;
- pRes = Saig_BmcObjFrame( p, pObj, i );
- if ( pRes != NULL )
- return pRes;
- if ( Saig_ObjIsPi( p->pAig, pObj ) )
- pRes = Aig_ObjCreatePi(p->pFrm);
- else if ( Saig_ObjIsLo( p->pAig, pObj ) )
- pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited );
- else if ( Aig_ObjIsPo( pObj ) )
- {
- Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited );
- pRes = Saig_BmcObjChild0( p, pObj, i );
- }
- else
- {
- Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited );
- if ( Saig_BmcObjChild0(p, pObj, i) == Aig_ManConst0(p->pFrm) )
- pRes = Aig_ManConst0(p->pFrm);
- else
- {
- Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited );
- pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) );
- }
- }
- assert( pRes != NULL );
- Saig_BmcObjSetFrame( p, pObj, i, pRes );
- Vec_PtrPush( vVisited, pObj );
- Vec_PtrPush( vVisited, (void *)i );
- return pRes;
+ if ( !Aig_ObjIsNode(pObj) )
+ return 0;
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ return 0;
+ Aig_ObjSetTravIdCurrent(p, pObj);
+ return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) +
+ Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) );
}
/**Function*************************************************************
- Synopsis [Adds new AIG nodes to the frames.]
+ Synopsis [Create timeframes of the manager for BMC.]
- Description []
+ Description [The resulting manager is combinational. POs correspond to
+ the property outputs in each time-frame.
+ The unrolling is stopped as soon as the number of nodes in the frames
+ exceeds the given maximum size.]
SideEffects []
SeeAlso []
***********************************************************************/
-void Saig_BmcInterval( Saig_Bmc_t * p )
+Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax )
{
- Aig_Obj_t * pTarget;
- Aig_Obj_t * pObj, * pRes;
- int i, iFrame, Counter;
- int nNodes = Aig_ManObjNum( p->pFrm );
- Vec_PtrClear( p->vTargets );
- p->iFramePrev = p->iFrameLast;
- for ( ; p->iFrameLast < p->nFramesMax; p->iFrameLast++, p->iOutputLast = 0 )
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo;
+ int i, f, Counter = 0;
+ assert( Saig_ManRegNum(pAig) > 0 );
+ pFrames = Aig_ManStart( nSizeMax );
+ Aig_ManIncrementTravId( pFrames );
+ // map the constant node
+ Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames );
+ // create variables for register outputs
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->pData = Aig_ManConst0( pFrames );
+ // add timeframes
+ Counter = 0;
+ for ( f = 0; f < nFrames; f++ )
{
- if ( p->iOutputLast == 0 )
+ // create PI nodes for this frame
+ Saig_ManForEachPi( pAig, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pFrames );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ // create POs for this frame
+ Saig_ManForEachPo( pAig, pObj, i )
{
- Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) );
+ pObjPo = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) );
+ Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) );
}
- for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ )
- {
- if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax )
- return;
-// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast );
- Vec_PtrClear( p->vVisited );
- pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited );
- Vec_PtrPush( p->vTargets, pTarget );
- Aig_ObjCreatePo( p->pFrm, pTarget );
- Aig_ManCleanup( p->pFrm );
- // check if the node is gone
- Counter = 0;
- Vec_PtrForEachEntry( p->vVisited, pObj, i )
- {
- iFrame = (int)(ABC_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ );
- pRes = Saig_BmcObjFrame( p, pObj, iFrame );
- if ( Aig_ObjIsNone( Aig_Regular(pRes) ) )
- {
- Saig_BmcObjSetFrame( p, pObj, iFrame, NULL );
- Counter++;
- }
- }
-// printf( "%d ", Counter );
- }
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs the actual construction of the output.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Aig_Obj_t * Saig_BmcIntervalToAig_rec( Saig_Bmc_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObj )
-{
- if ( pObj->pData )
- return pObj->pData;
- Vec_PtrPush( p->vVisited, pObj );
- if ( Saig_BmcSatNum(p, pObj) || Aig_ObjIsPi(pObj) )
- return pObj->pData = Aig_ObjCreatePi(pNew);
- Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin0(pObj) );
- Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin1(pObj) );
- assert( pObj->pData == NULL );
- return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
-}
-
-/**Function*************************************************************
-
- Synopsis [Creates AIG of the newly added nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Aig_Man_t * Saig_BmcIntervalToAig( Saig_Bmc_t * p )
-{
- Aig_Man_t * pNew;
- Aig_Obj_t * pObj, * pObjNew;
- int i;
- Aig_ManForEachObj( p->pFrm, pObj, i )
- assert( pObj->pData == NULL );
-
- pNew = Aig_ManStart( p->nNodesMax );
- Aig_ManConst1(p->pFrm)->pData = Aig_ManConst1(pNew);
- Vec_PtrClear( p->vVisited );
- Vec_PtrPush( p->vVisited, Aig_ManConst1(p->pFrm) );
- Vec_PtrForEachEntry( p->vTargets, pObj, i )
- {
-// assert( !Aig_ObjIsConst1(Aig_Regular(pObj)) );
- pObjNew = Saig_BmcIntervalToAig_rec( p, pNew, Aig_Regular(pObj) );
- assert( !Aig_IsComplement(pObjNew) );
- Aig_ObjCreatePo( pNew, pObjNew );
- }
- return pNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives CNF for the newly added nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Saig_BmcLoadCnf( Saig_Bmc_t * p, Cnf_Dat_t * pCnf )
-{
- Aig_Obj_t * pObj, * pObjNew;
- int i, Lits[2], VarNumOld, VarNumNew;
- Vec_PtrForEachEntry( p->vVisited, pObj, i )
- {
- // get the new variable of this node
- pObjNew = pObj->pData;
- pObj->pData = NULL;
- VarNumNew = pCnf->pVarNums[ pObjNew->Id ];
- if ( VarNumNew == -1 )
- continue;
- // get the old variable of this node
- VarNumOld = Saig_BmcSatNum( p, pObj );
- if ( VarNumOld == 0 )
+ if ( Counter >= nSizeMax )
{
- Saig_BmcSetSatNum( p, pObj, VarNumNew );
- continue;
+ Aig_ManCleanup( pFrames );
+ return pFrames;
}
- // add clauses connecting existing variables
- Lits[0] = toLitCond( VarNumOld, 0 );
- Lits[1] = toLitCond( VarNumNew, 1 );
- if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) )
- assert( 0 );
- Lits[0] = toLitCond( VarNumOld, 1 );
- Lits[1] = toLitCond( VarNumNew, 0 );
- if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) )
- assert( 0 );
- }
- // add CNF to the SAT solver
- for ( i = 0; i < pCnf->nClauses; i++ )
- if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
+ if ( f == nFrames - 1 )
break;
- if ( i < pCnf->nClauses )
- printf( "SAT solver became UNSAT after adding clauses.\n" );
-}
-
-/**Function*************************************************************
-
- Synopsis [Solves targets with the given resource limit.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Saig_BmcDeriveFailed( Saig_Bmc_t * p, int iTargetFail )
-{
- int k;
- p->iOutputFail = p->iOutputLast;
- p->iFrameFail = p->iFrameLast;
- for ( k = Vec_PtrSize(p->vTargets); k > iTargetFail; k-- )
- {
- if ( p->iOutputFail == 0 )
- {
- p->iOutputFail = Saig_ManPoNum(p->pAig);
- p->iFrameFail--;
- }
- p->iOutputFail--;
+ // save register inputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ // transfer to register outputs
+ Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
+ pObjLo->pData = pObjLi->pData;
}
+ Aig_ManCleanup( pFrames );
+ return pFrames;
}
-/**Function*************************************************************
+ABC_NAMESPACE_IMPL_END
- Synopsis [Solves targets with the given resource limit.]
+#include "utilMem.h"
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p )
-{
- Ssw_Cex_t * pCex;
- Aig_Obj_t * pObj, * pObjFrm;
- int i, f, iVarNum;
- // start the counter-example
- pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 );
- pCex->iFrame = p->iFrameFail;
- pCex->iPo = p->iOutputFail;
- // copy the bit data
- for ( f = 0; f <= p->iFrameFail; f++ )
- {
- Saig_ManForEachPi( p->pAig, pObj, i )
- {
- pObjFrm = Saig_BmcObjFrame( p, pObj, f );
- if ( pObjFrm == NULL )
- continue;
- iVarNum = Saig_BmcSatNum( p, pObjFrm );
- if ( iVarNum == 0 )
- continue;
- if ( sat_solver_var_value( p->pSat, iVarNum ) )
- Aig_InfoSetBit( pCex->pData, pCex->nRegs + Saig_ManPiNum(p->pAig) * f + i );
- }
- }
- // verify the counter example
- if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) )
- {
- printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" );
- Ssw_SmlFreeCounterExample( pCex );
- pCex = NULL;
- }
- return pCex;
-}
+ABC_NAMESPACE_IMPL_START
+
/**Function*************************************************************
- Synopsis [Solves targets with the given resource limit.]
+ Synopsis [Performs BMC for the given AIG.]
Description []
@@ -669,157 +183,156 @@ Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p )
SeeAlso []
***********************************************************************/
-int Saig_BmcSolveTargets( Saig_Bmc_t * p, int nStart, int * pnOutsSolved )
+int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit )
{
+ extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit );
+ sat_solver * pSat;
+ Cnf_Dat_t * pCnf;
+ Aig_Man_t * pFrames, * pAigTemp;
Aig_Obj_t * pObj;
- int i, VarNum, Lit, RetValue;
- assert( Vec_PtrSize(p->vTargets) > 0 );
- if ( p->pSat->qtail != p->pSat->qhead )
+ int status, clk, Lit, i, RetValue = -1;
+
+ // derive the timeframes
+ clk = clock();
+ if ( nCofFanLit )
{
- RetValue = sat_solver_simplify(p->pSat);
- assert( RetValue != 0 );
+ pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit );
+ if ( pFrames == NULL )
+ return -1;
}
- Vec_PtrForEachEntry( p->vTargets, pObj, i )
+ else if ( nSizeMax > 0 )
{
- if ( ((*pnOutsSolved)++ / Saig_ManPoNum(p->pAig)) < nStart )
- continue;
- if ( p->pSat->stats.conflicts > p->nConfMaxAll )
- return l_Undef;
- VarNum = Saig_BmcSatNum( p, Aig_Regular(pObj) );
- Lit = toLitCond( VarNum, Aig_IsComplement(pObj) );
- RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)p->nConfMaxOne, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
- if ( RetValue == l_False ) // unsat
- continue;
- if ( RetValue == l_Undef ) // undecided
- return l_Undef;
- // generate counter-example
- Saig_BmcDeriveFailed( p, i );
- p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p );
-
- {
-// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex );
-// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel );
- }
- return l_True;
+ pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax );
+ nFrames = Aig_ManPoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManPoNum(pFrames) % Saig_ManPoNum(pAig)) > 0);
}
- return l_False;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Saig_BmcAddTargetsAsPos( Saig_Bmc_t * p )
-{
- Aig_Obj_t * pObj;
- int i;
- Vec_PtrForEachEntry( p->vTargets, pObj, i )
- Aig_ObjCreatePo( p->pFrm, pObj );
- Aig_ManPrintStats( p->pFrm );
- Aig_ManCleanup( p->pFrm );
- Aig_ManPrintStats( p->pFrm );
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs BMC with the given parameters.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite )
-{
- Saig_Bmc_t * p;
- Aig_Man_t * pNew;
- Cnf_Dat_t * pCnf;
- int nOutsSolved = 0;
- int Iter, RetValue, clk = clock(), clk2;
-/*
- Vec_Ptr_t * vSimInfo;
- vSimInfo = Abs_ManTernarySimulate( pAig, nFramesMax, fVerbose );
- Abs_ManFreeAray( vSimInfo );
-*/
- p = Saig_BmcManStart( pAig, nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll, fVerbose );
+ else
+ pFrames = Saig_ManFramesBmc( pAig, nFrames );
+ if ( piFrame )
+ *piFrame = nFrames;
if ( fVerbose )
{
printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n",
Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig),
Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) );
- printf( "Params: FramesMax = %d. NodesDelta = %d. ConfMaxOne = %d. ConfMaxAll = %d.\n",
- nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll );
- }
-
- for ( Iter = 0; ; Iter++ )
+ printf( "Time-frames (%d): PI/PO = %d/%d. Node = %6d. Lev = %5d. ",
+ nFrames, Aig_ManPiNum(pFrames), Aig_ManPoNum(pFrames),
+ Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) );
+ ABC_PRT( "Time", clock() - clk );
+ fflush( stdout );
+ }
+ // rewrite the timeframes
+ if ( fRewrite )
{
- clk2 = clock();
- // add new logic interval to frames
- Saig_BmcInterval( p );
-// Saig_BmcAddTargetsAsPos( p );
- if ( Vec_PtrSize(p->vTargets) == 0 )
- break;
- // convert logic slice into new AIG
- pNew = Saig_BmcIntervalToAig( p );
- // derive CNF for the new AIG
- pCnf = Cnf_Derive( pNew, Aig_ManPoNum(pNew) );
- Cnf_DataLift( pCnf, p->nSatVars );
- p->nSatVars += pCnf->nVars;
- // add this CNF to the solver
- Saig_BmcLoadCnf( p, pCnf );
- Cnf_DataFree( pCnf );
- Aig_ManStop( pNew );
- // solve the targets
- RetValue = Saig_BmcSolveTargets( p, nStart, &nOutsSolved );
+ clk = clock();
+// pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 );
+ pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 );
+ Aig_ManStop( pAigTemp );
if ( fVerbose )
{
- printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ",
- Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts );
- ABC_PRT( "Time", clock() - clk2 );
+ printf( "Time-frames after rewriting: Node = %6d. Lev = %5d. ",
+ Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) );
+ ABC_PRT( "Time", clock() - clk );
+ fflush( stdout );
}
- if ( RetValue != l_False )
- break;
}
- if ( RetValue == l_True )
+ // create the SAT solver
+ clk = clock();
+ pCnf = Cnf_Derive( pFrames, Aig_ManPoNum(pFrames) );
+//if ( s_fInterrupt )
+//return -1;
+ pSat = sat_solver_new();
+ sat_solver_setnvars( pSat, pCnf->nVars );
+ for ( i = 0; i < pCnf->nClauses; i++ )
{
- assert( p->iFrameFail * Saig_ManPoNum(p->pAig) + p->iOutputFail + 1 == nOutsSolved );
- printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ",
- p->iOutputFail, p->iFrameFail );
+ if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
+ assert( 0 );
}
- else // if ( RetValue == l_False || RetValue == l_Undef )
- printf( "No output was asserted in %d frames. ", p->iFramePrev-1 );
- if ( fVerbOverwrite )
+ if ( fVerbose )
{
- ABC_PRTr( "Time", clock() - clk );
+ printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals );
+ ABC_PRT( "Time", clock() - clk );
+ fflush( stdout );
}
- else
+ status = sat_solver_simplify(pSat);
+ if ( status == 0 )
{
- ABC_PRT( "Time", clock() - clk );
+ if ( fVerbose )
+ {
+ printf( "The BMC problem is trivially UNSAT\n" );
+ fflush( stdout );
+ }
}
- if ( RetValue != l_True )
+ else
{
- if ( p->iFrameLast >= p->nFramesMax )
- printf( "Reached limit on the number of timeframes (%d).\n", p->nFramesMax );
- else if ( p->pSat->stats.conflicts > p->nConfMaxAll )
- printf( "Reached global conflict limit (%d).\n", p->nConfMaxAll );
- else
- printf( "Reached local conflict limit (%d).\n", p->nConfMaxOne );
+ int clkPart = clock();
+ Aig_ManForEachPo( pFrames, pObj, i )
+ {
+//if ( s_fInterrupt )
+//return -1;
+ Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 );
+ if ( fVerbose )
+ {
+ printf( "Solving output %2d of frame %3d ... \r",
+ i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
+ }
+ clk = clock();
+ status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) )
+ {
+ printf( "Solved %2d outputs of frame %3d. ",
+ Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
+ printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations );
+ ABC_PRT( "T", clock() - clkPart );
+ clkPart = clock();
+ fflush( stdout );
+ }
+ if ( status == l_False )
+ {
+/*
+ Lit = lit_neg( Lit );
+ RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
+ assert( RetValue );
+ if ( pSat->qtail != pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(pSat);
+ assert( RetValue );
+ }
+*/
+ }
+ else if ( status == l_True )
+ {
+// extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel );
+ Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames );
+ int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
+ pModel[Aig_ManPiNum(pFrames)] = pObj->Id;
+ pAig->pSeqModel = (Abc_Cex_t *)Fra_SmlCopyCounterExample( pAig, pFrames, pModel );
+ ABC_FREE( pModel );
+ Vec_IntFree( vCiIds );
+
+ if ( piFrame )
+ *piFrame = i / Saig_ManPoNum(pAig);
+ RetValue = 0;
+ break;
+ }
+ else
+ {
+ if ( piFrame )
+ *piFrame = i / Saig_ManPoNum(pAig);
+ RetValue = -1;
+ break;
+ }
+ }
}
- Saig_BmcManStop( p );
+ sat_solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ Aig_ManStop( pFrames );
+ return RetValue;
}
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+