summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-01-01 15:58:49 +0700
committerAlan Mishchenko <alanmi@berkeley.edu>2012-01-01 15:58:49 +0700
commite3a412b2e788c1bd17678e4341648ac254f409e0 (patch)
tree39ffb4f60330e95abcf9a283cd70b0f345ee1e83 /src
parentaec5d338894cc98460d92c1bc6dea311eed7727a (diff)
downloadabc-e3a412b2e788c1bd17678e4341648ac254f409e0.tar.gz
abc-e3a412b2e788c1bd17678e4341648ac254f409e0.tar.bz2
abc-e3a412b2e788c1bd17678e4341648ac254f409e0.zip
Backward reachability using circuit cofactoring.
Diffstat (limited to 'src')
-rw-r--r--src/aig/gia/giaCCof.c442
1 files changed, 442 insertions, 0 deletions
diff --git a/src/aig/gia/giaCCof.c b/src/aig/gia/giaCCof.c
new file mode 100644
index 00000000..5819ee92
--- /dev/null
+++ b/src/aig/gia/giaCCof.c
@@ -0,0 +1,442 @@
+/**CFile****************************************************************
+
+ FileName [giaCCof.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Backward reachability using circuit cofactoring.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaCCof.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ccf_Man_t_ Ccf_Man_t; // manager
+struct Ccf_Man_t_
+{
+ // user data
+ Gia_Man_t * pGia; // single output AIG manager
+ int nFrameMax; // maximum number of frames
+ int nConfMax; // maximum number of conflicts
+ int nTimeMax; // maximum runtime in seconds
+ int fVerbose; // verbose flag
+ // internal data
+ sat_solver * pSat; // SAT solver
+ Gia_Man_t * pFrames; // unrolled timeframes
+ Vec_Int_t * vIdToFra; // maps GIA obj IDs into frame obj IDs
+ Vec_Int_t * vOrder; // map Num to Id
+ Vec_Int_t * vFraLims; // frame limits
+};
+
+extern Vec_Int_t * Gia_VtaCollect( Gia_Man_t * p, Vec_Int_t ** pvFraLims, Vec_Int_t ** pvRoots );
+
+static inline int Gia_ObjFrames( Ccf_Man_t * p, int f, Gia_Obj_t * pObj ) { assert( Vec_IntEntry(p->vIdToFra, f*Gia_ManObjNum(p->pGia)+Gia_ObjId(p->pGia,pObj)) >= 0 ); return Vec_IntEntry(p->vIdToFra, f*Gia_ManObjNum(p->pGia)+Gia_ObjId(p->pGia,pObj)); }
+static inline void Gia_ObjSetFrames( Ccf_Man_t * p, int f, Gia_Obj_t * pObj, int Lit ) { Vec_IntWriteEntry(p->vIdToFra, f*Gia_ManObjNum(p->pGia)+Gia_ObjId(p->pGia,pObj), Lit); }
+
+static inline int Gia_ObjChild0Frames( Ccf_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjFrames(p, f, Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj)); }
+static inline int Gia_ObjChild1Frames( Ccf_Man_t * p, int f, Gia_Obj_t * pObj ) { return Gia_LitNotCond(Gia_ObjFrames(p, f, Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj)); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int sat_solver_add_const( sat_solver * pSat, int iVar, int fCompl )
+{
+ lit Lits[1];
+ int Cid;
+ assert( iVar >= 0 );
+
+ Lits[0] = toLitCond( iVar, fCompl );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 1 );
+ assert( Cid );
+ return 1;
+}
+static inline int sat_solver_add_buffer( sat_solver * pSat, int iVarA, int iVarB, int fCompl )
+{
+ lit Lits[2];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 );
+
+ Lits[0] = toLitCond( iVarA, 0 );
+ Lits[1] = toLitCond( iVarB, !fCompl );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVarA, 1 );
+ Lits[1] = toLitCond( iVarB, fCompl );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+ return 2;
+}
+static inline int sat_solver_add_and( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 )
+{
+ lit Lits[3];
+ int Cid;
+
+ Lits[0] = toLitCond( iVar, 1 );
+ Lits[1] = toLitCond( iVar0, fCompl0 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVar, 1 );
+ Lits[1] = toLitCond( iVar1, fCompl1 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVar, 0 );
+ Lits[1] = toLitCond( iVar0, !fCompl0 );
+ Lits[2] = toLitCond( iVar1, !fCompl1 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 3 );
+ assert( Cid );
+ return 3;
+}
+static inline int sat_solver_add_xor( sat_solver * pSat, int iVarA, int iVarB, int iVarC, int fCompl )
+{
+ lit Lits[3];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 );
+
+ Lits[0] = toLitCond( iVarA, !fCompl );
+ Lits[1] = toLitCond( iVarB, 1 );
+ Lits[2] = toLitCond( iVarC, 1 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 3 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVarA, !fCompl );
+ Lits[1] = toLitCond( iVarB, 0 );
+ Lits[2] = toLitCond( iVarC, 0 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 3 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVarA, fCompl );
+ Lits[1] = toLitCond( iVarB, 1 );
+ Lits[2] = toLitCond( iVarC, 0 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 3 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVarA, fCompl );
+ Lits[1] = toLitCond( iVarB, 0 );
+ Lits[2] = toLitCond( iVarC, 1 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 3 );
+ assert( Cid );
+ return 4;
+}
+static inline int sat_solver_add_constraint( sat_solver * pSat, int iVar, int fCompl )
+{
+ lit Lits[2];
+ int Cid;
+ assert( iVar >= 0 );
+
+ Lits[0] = toLitCond( iVar, fCompl );
+ Lits[1] = toLitCond( iVar+1, 0 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+
+ Lits[0] = toLitCond( iVar, fCompl );
+ Lits[1] = toLitCond( iVar+1, 1 );
+ Cid = sat_solver_addclause( pSat, Lits, Lits + 2 );
+ assert( Cid );
+ return 2;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ccf_Man_t * Ccf_ManStart( Gia_Man_t * pGia, int nFrameMax, int nConfMax, int nTimeMax, int fVerbose )
+{
+ Ccf_Man_t * p;
+ assert( nFrameMax > 0 );
+ p = ABC_CALLOC( Ccf_Man_t, 1 );
+ p->pGia = pGia;
+ p->nFrameMax = nFrameMax;
+ p->nConfMax = nConfMax;
+ p->nTimeMax = nTimeMax;
+ p->fVerbose = fVerbose;
+ // internal data
+ p->pFrames = Gia_ManStart( 10000 );
+ Gia_ManHashAlloc( p->pFrames );
+ p->vOrder = Gia_VtaCollect( pGia, &p->vFraLims, NULL );
+ p->vIdToFra = Vec_IntAlloc( 0 );
+ p->pSat = sat_solver_new();
+ sat_solver_setnvars( p->pSat, 10000 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Delete manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ccf_ManStop( Ccf_Man_t * p )
+{
+ Vec_IntFreeP( &p->vIdToFra );
+ Vec_IntFreeP( &p->vOrder );
+ Vec_IntFreeP( &p->vFraLims );
+ sat_solver_delete( p->pSat );
+ Gia_ManStopP( &p->pFrames );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Extends the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCofExtendSolver( Ccf_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ // add SAT clauses
+ for ( i = sat_solver_nvars(p->pSat); i < Gia_ManObjNum(p->pFrames); i++ )
+ {
+ pObj = Gia_ManObj( p->pGia, i );
+ if ( Gia_ObjIsAnd(pObj) )
+ sat_solver_add_and( p->pSat, i,
+ Gia_ObjFaninId0(pObj, i),
+ Gia_ObjFaninId1(pObj, i),
+ Gia_ObjFaninC0(pObj),
+ Gia_ObjFaninC1(pObj) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds logic of one timeframe to the manager.]
+
+ Description [Returns literal of the property output.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCofAddTimeFrame( Ccf_Man_t * p, int fMax )
+{
+ Gia_Obj_t * pObj;
+ int i, f, Beg, End, Lit;
+ assert( fMax > 0 && fMax <= p->nFrameMax );
+ assert( Vec_IntSize(p->vIdToFra) == (fMax - 1) * Gia_ManObjNum(p->pGia) );
+ // add to the mapping of nodes
+ Vec_IntFillExtra( p->vIdToFra, fMax * Gia_ManObjNum(p->pGia), -1 );
+ // add nodes to each time-frame
+ for ( f = 0; f < fMax; f++ )
+ {
+ if ( Vec_IntSize(p->vFraLims) >= fMax-f )
+ continue;
+ Beg = Vec_IntEntry( p->vFraLims, fMax-f-1 );
+ End = Vec_IntEntry( p->vFraLims, fMax-f );
+ for ( i = Beg; i < End; i++ )
+ {
+ pObj = Gia_ManObj( p->pGia, Vec_IntEntry(p->vOrder, i) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Lit = Gia_ManHashAnd( p->pFrames, Gia_ObjChild0Frames(p, f, pObj), Gia_ObjChild1Frames(p, f, pObj) );
+ else if ( Gia_ObjIsRo(p->pGia, pObj) && f > 0 )
+ Lit = Gia_ObjChild0Frames(p, f-1, Gia_ObjRoToRi(p->pGia, pObj));
+ else if ( Gia_ObjIsCi(pObj) )
+ {
+ Lit = Gia_ManAppendCi(p->pFrames);
+ // mark primary input
+ Gia_ManObj(p->pFrames, Gia_Lit2Var(Lit))->fMark0 = Gia_ObjIsPi(p->pGia, pObj);
+ }
+ else assert( 0 );
+ Gia_ObjSetFrames( p, f, pObj, Lit );
+ }
+ }
+ // add SAT clauses
+ Gia_ManCofExtendSolver( p );
+ // return output literal
+ return Gia_ObjChild0Frames( p, fMax-1, Gia_ManPo(p->pGia, 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cofactor the circuit w.r.t. the given assignment.]
+
+ Description [Assumes that the solver has just returned SAT.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCofOneDerive_rec( Ccf_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManCofOneDerive_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManCofOneDerive_rec( p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( p->pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ else if ( pObj->fMark0 ) // PI
+ pObj->Value = sat_solver_var_value( p->pSat, Gia_ObjId(p->pGia, pObj) );
+ else
+ pObj->Value = Gia_Var2Lit( Gia_ObjId(p->pGia, pObj), 0 );
+ return pObj->Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cofactor the circuit w.r.t. the given assignment.]
+
+ Description [Assumes that the solver has just returned SAT.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCofOneDerive( Ccf_Man_t * p, int LitProp )
+{
+ Gia_Obj_t * pObj;
+ int LitOut;
+ // get the property node
+ pObj = Gia_ManObj( p->pFrames, Gia_Lit2Var(LitProp) );
+ // derive the cofactor
+ Gia_ManFillValue( p->pFrames );
+ LitOut = Gia_ManCofOneDerive_rec( p, pObj );
+ LitOut = Gia_LitNotCond(LitOut, Gia_LitIsCompl(LitProp));
+ // add new PO for the cofactor
+ Gia_ManAppendCo( p->pFrames, LitOut );
+ // add SAT clauses
+ Gia_ManCofExtendSolver( p );
+ // return negative literal of the cofactor
+ return Gia_LitNot(LitOut);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Enumerates backward reachable states.]
+
+ Description [Return -1 if resource limit is reached. Returns 1
+ if computation converged (there is no more reachable states).
+ Returns 0 if no more states to enumerate.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCofGetReachable( Ccf_Man_t * p, int Lit )
+{
+ int RetValue;
+ // try solving for the first time and quit if converged
+ RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, p->nConfMax, 0, 0, 0 );
+ if ( RetValue == l_False )
+ return 1;
+ // iterate circuit cofactoring
+ while ( RetValue == 0 )
+ {
+ // derive cofactor
+ int LitOut = Gia_ManCofOneDerive( p, Lit );
+ // add the blocking clause
+ RetValue = sat_solver_addclause( p->pSat, &LitOut, &LitOut + 1 );
+ assert( RetValue );
+ // try solving again
+ RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, p->nConfMax, 0, 0, 0 );
+ }
+ if ( RetValue == l_Undef )
+ return -1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCofTest( Gia_Man_t * pGia, int nFrameMax, int nConfMax, int nTimeMax, int fVerbose )
+{
+ Gia_Man_t * pNew;
+ Ccf_Man_t * p;
+ int f, Lit, RetValue;
+ assert( Gia_ManPoNum(pGia) == 1 );
+ // create reachability manager
+ p = Ccf_ManStart( pGia, nFrameMax, nConfMax, nTimeMax, fVerbose );
+ // perform backward image computation
+ for ( f = 0; f < nFrameMax; f++ )
+ {
+ if ( fVerbose )
+ printf( "ITER %3d :\n", f );
+ // derives new timeframe and returns the property literal
+ Lit = Gia_ManCofAddTimeFrame( p, f+1 );
+ // derives cofactors of the property literal till all states are blocked
+ RetValue = Gia_ManCofGetReachable( p, Lit );
+ if ( RetValue )
+ break;
+ }
+ // report the result
+ if ( f == nFrameMax )
+ printf( "Completed %d frames without converging.\n", f );
+ else if ( RetValue == 1 )
+ printf( "Backward reachability converged after %d iterations.\n", f );
+ else if ( RetValue == -1 )
+ printf( "Conflict limit or timeout is reached after %d frames.\n", f );
+
+ // get the resulting AIG manager
+ Gia_ManHashStop( p->pFrames );
+ Gia_ManCleanMark0( p->pFrames );
+ pNew = p->pFrames; p->pFrames = NULL;
+ Ccf_ManStop( p );
+ pNew = Gia_ManCleanup( pGia = pNew );
+ Gia_ManStop( pGia );
+
+// if ( fVerbose )
+ Gia_ManPrintStats( pNew, 0 );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+