Commit ac037cbb by Alan Mishchenko

New MFS package.

parent 78d60d98
...@@ -122,6 +122,11 @@ static inline void Vec_WecGrow( Vec_Wec_t * p, int nCapMin ) ...@@ -122,6 +122,11 @@ static inline void Vec_WecGrow( Vec_Wec_t * p, int nCapMin )
memset( p->pArray + p->nCap, 0, sizeof(Vec_Int_t) * (nCapMin - p->nCap) ); memset( p->pArray + p->nCap, 0, sizeof(Vec_Int_t) * (nCapMin - p->nCap) );
p->nCap = nCapMin; p->nCap = nCapMin;
} }
static inline void Vec_WecInit( Vec_Wec_t * p, int nSize )
{
Vec_WecGrow( p, nSize );
p->nSize = nSize;
}
/**Function************************************************************* /**Function*************************************************************
...@@ -314,12 +319,24 @@ static inline double Vec_WecMemory( Vec_Wec_t * p ) ...@@ -314,12 +319,24 @@ static inline double Vec_WecMemory( Vec_Wec_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Vec_WecFree( Vec_Wec_t * p ) static inline void Vec_WecZero( Vec_Wec_t * p )
{
p->pArray = NULL;
p->nSize = 0;
p->nCap = 0;
}
static inline void Vec_WecErase( Vec_Wec_t * p )
{ {
int i; int i;
for ( i = 0; i < p->nCap; i++ ) for ( i = 0; i < p->nCap; i++ )
ABC_FREE( p->pArray[i].pArray ); ABC_FREE( p->pArray[i].pArray );
ABC_FREE( p->pArray ); ABC_FREE( p->pArray );
p->nSize = 0;
p->nCap = 0;
}
static inline void Vec_WecFree( Vec_Wec_t * p )
{
Vec_WecErase( p );
ABC_FREE( p ); ABC_FREE( p );
} }
static inline void Vec_WecFreeP( Vec_Wec_t ** p ) static inline void Vec_WecFreeP( Vec_Wec_t ** p )
......
...@@ -75,6 +75,8 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p ) ...@@ -75,6 +75,8 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p )
p->vNodes = Vec_IntAlloc( 1000 ); p->vNodes = Vec_IntAlloc( 1000 );
p->vTfo = Vec_IntAlloc( 1000 ); p->vTfo = Vec_IntAlloc( 1000 );
p->vDivs = Vec_IntAlloc( 100 ); p->vDivs = Vec_IntAlloc( 100 );
p->vDivIds = Vec_IntAlloc( 1000 );
p->vDiffs = Vec_IntAlloc( 1000 );
p->vLits = Vec_IntAlloc( 100 ); p->vLits = Vec_IntAlloc( 100 );
p->vClauses = Vec_WecAlloc( 100 ); p->vClauses = Vec_WecAlloc( 100 );
p->vFaninMap = Vec_IntAlloc( 10 ); p->vFaninMap = Vec_IntAlloc( 10 );
...@@ -94,15 +96,19 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p ) ...@@ -94,15 +96,19 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p )
***********************************************************************/ ***********************************************************************/
int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars ) int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars )
{ {
int i; // int i;
p->pPars = pPars; p->pPars = pPars;
Sfm_NtkPrepare( p ); Sfm_NtkPrepare( p );
Sfm_ComputeInterpolantCheck( p );
/*
Sfm_NtkForEachNode( p, i ) Sfm_NtkForEachNode( p, i )
{ {
printf( "Node %d:\n", i ); // printf( "Node %d:\n", i );
Sfm_PrintCnf( (Vec_Str_t *)Vec_WecEntry(p->vCnfs, i) ); // Sfm_PrintCnf( (Vec_Str_t *)Vec_WecEntry(p->vCnfs, i) );
printf( "\n" ); // printf( "\n" );
Sfm_NtkWindow( p, i, 1 );
} }
*/
return 0; return 0;
} }
......
...@@ -55,33 +55,37 @@ struct Sfm_Ntk_t_ ...@@ -55,33 +55,37 @@ struct Sfm_Ntk_t_
int nNodes; // internal nodes int nNodes; // internal nodes
int nObjs; // total objects int nObjs; // total objects
// user data // user data
Vec_Wec_t * vFanins; // fanins
Vec_Str_t * vFixed; // persistent objects Vec_Str_t * vFixed; // persistent objects
Vec_Wrd_t * vTruths; // truth tables Vec_Wrd_t * vTruths; // truth tables
Vec_Wec_t vFanins; // fanins
// attributes // attributes
Vec_Wec_t * vFanouts; // fanouts Vec_Wec_t vFanouts; // fanouts
Vec_Int_t * vLevels; // logic level Vec_Int_t vLevels; // logic level
Vec_Int_t vTravIds; // traversal IDs Vec_Int_t vCounts; // fanin counters
Vec_Int_t vId2Var; // ObjId -> SatVar Vec_Int_t vId2Var; // ObjId -> SatVar
Vec_Int_t vVar2Id; // SatVar -> ObjId Vec_Int_t vVar2Id; // SatVar -> ObjId
Vec_Wec_t * vCnfs; // CNFs Vec_Wec_t * vCnfs; // CNFs
Vec_Int_t * vCover; // temporary Vec_Int_t * vCover; // temporary
// traversal IDs
Vec_Int_t vTravIds; // traversal IDs
Vec_Int_t vTravIds2;// traversal IDs
int nTravIds; // traversal IDs int nTravIds; // traversal IDs
int nTravIds2;// traversal IDs
// window // window
int iNode; int iNode;
Vec_Int_t * vLeaves; // leaves Vec_Int_t * vLeaves; // leaves
Vec_Int_t * vRoots; // roots Vec_Int_t * vRoots; // roots
Vec_Int_t * vNodes; // internal Vec_Int_t * vNodes; // internal
Vec_Int_t * vTfo; // TFO (excluding iNode) Vec_Int_t * vTfo; // TFO (excluding iNode)
Vec_Int_t * vDivs; // divisors
// SAT solving // SAT solving
int nSatVars; // the number of variables int nSatVars; // the number of variables
sat_solver * pSat1; // SAT solver for the on-set sat_solver * pSat1; // SAT solver for the on-set
sat_solver * pSat0; // SAT solver for the off-set sat_solver * pSat0; // SAT solver for the off-set
// intermediate data // intermediate data
Vec_Int_t * vDivs; // divisors Vec_Int_t * vDivIds; // divisors indexes
Vec_Int_t * vLits; // literals Vec_Int_t * vLits; // literals
Vec_Int_t * vFani; // iterator fanins Vec_Int_t * vDiffs; // differences
Vec_Int_t * vFano; // iterator fanouts
Vec_Wec_t * vClauses; // CNF clauses for the node Vec_Wec_t * vClauses; // CNF clauses for the node
Vec_Int_t * vFaninMap;// mapping fanins into their SAT vars Vec_Int_t * vFaninMap;// mapping fanins into their SAT vars
}; };
...@@ -89,26 +93,38 @@ struct Sfm_Ntk_t_ ...@@ -89,26 +93,38 @@ struct Sfm_Ntk_t_
#define SFM_SAT_UNDEC 0x1234567812345678 #define SFM_SAT_UNDEC 0x1234567812345678
#define SFM_SAT_SAT 0x8765432187654321 #define SFM_SAT_SAT 0x8765432187654321
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Sfm_NtkForEachNode( p, i ) for ( i = p->nPis; i + p->nPos < p->nObjs; i++ )
#define Sfm_NodeForEachFanin( p, Node, Fan, i ) for ( p->vFani = Vec_WecEntry(p->vFanins, Node), i = 0; i < Vec_IntSize(p->vFani) && ((Fan = Vec_IntEntry(p->vFani, i)), 1); i++ )
#define Sfm_NodeForEachFanout( p, Node, Fan, i ) for ( p->vFano = Vec_WecEntry(p->vFanouts, Node), i = 0; i < Vec_IntSize(p->vFani) && ((Fan = Vec_IntEntry(p->vFano, i)), 1); i++ )
static inline int Sfm_ObjIsPi( Sfm_Ntk_t * p, int i ) { return i < p->nPis; } static inline int Sfm_ObjIsPi( Sfm_Ntk_t * p, int i ) { return i < p->nPis; }
static inline int Sfm_ObjIsPo( Sfm_Ntk_t * p, int i ) { return i + p->nPos < p->nObjs; } static inline int Sfm_ObjIsPo( Sfm_Ntk_t * p, int i ) { return i + p->nPos >= p->nObjs; }
static inline int Sfm_ObjIsNode( Sfm_Ntk_t * p, int i ) { return i >= p->nPis && i + p->nPos < p->nObjs; } static inline int Sfm_ObjIsNode( Sfm_Ntk_t * p, int i ) { return i >= p->nPis && i + p->nPos < p->nObjs; }
static inline int Sfm_ObjFaninNum( Sfm_Ntk_t * p, int i ) { return Vec_IntSize(Vec_WecEntry(p->vFanins, i)); } static inline Vec_Int_t * Sfm_ObjFiArray( Sfm_Ntk_t * p, int i ) { return Vec_WecEntry(&p->vFanins, i); }
static inline int Sfm_ObjFanoutNum( Sfm_Ntk_t * p, int i ) { return Vec_IntSize(Vec_WecEntry(p->vFanouts, i)); } static inline Vec_Int_t * Sfm_ObjFoArray( Sfm_Ntk_t * p, int i ) { return Vec_WecEntry(&p->vFanouts, i); }
static inline int Sfm_ObjFaninNum( Sfm_Ntk_t * p, int i ) { return Vec_IntSize(Sfm_ObjFiArray(p, i)); }
static inline int Sfm_ObjFanoutNum( Sfm_Ntk_t * p, int i ) { return Vec_IntSize(Sfm_ObjFoArray(p, i)); }
static inline int Sfm_ObjFanin( Sfm_Ntk_t * p, int i, int k ) { return Vec_IntEntry(Sfm_ObjFiArray(p, i), k); }
static inline int Sfm_ObjFanout( Sfm_Ntk_t * p, int i, int k ) { return Vec_IntEntry(Sfm_ObjFoArray(p, i), k); }
static inline int Sfm_ObjSatVar( Sfm_Ntk_t * p, int iObj ) { return Vec_IntEntry(&p->vId2Var, iObj); } static inline int Sfm_ObjSatVar( Sfm_Ntk_t * p, int iObj ) { return Vec_IntEntry(&p->vId2Var, iObj); }
static inline void Sfm_ObjSetSatVar( Sfm_Ntk_t * p, int iObj, int Num ) { assert(Sfm_ObjSatVar(p, iObj) == -1); Vec_IntWriteEntry(&p->vId2Var, iObj, Num); Vec_IntWriteEntry(&p->vVar2Id, Num, iObj); } static inline void Sfm_ObjSetSatVar( Sfm_Ntk_t * p, int iObj, int Num ) { assert(Sfm_ObjSatVar(p, iObj) == -1); Vec_IntWriteEntry(&p->vId2Var, iObj, Num); Vec_IntWriteEntry(&p->vVar2Id, Num, iObj); }
static inline void Sfm_ObjCleanSatVar( Sfm_Ntk_t * p, int Num ) { assert(Sfm_ObjSatVar(p, Vec_IntEntry(&p->vVar2Id, Num)) != -1); Vec_IntWriteEntry(&p->vId2Var, Vec_IntEntry(&p->vVar2Id, Num), Num); Vec_IntWriteEntry(&p->vVar2Id, Num, -1); } static inline void Sfm_ObjCleanSatVar( Sfm_Ntk_t * p, int Num ) { assert(Sfm_ObjSatVar(p, Vec_IntEntry(&p->vVar2Id, Num)) != -1); Vec_IntWriteEntry(&p->vId2Var, Vec_IntEntry(&p->vVar2Id, Num), Num); Vec_IntWriteEntry(&p->vVar2Id, Num, -1); }
static inline void Sfm_NtkCleanVars( Sfm_Ntk_t * p, int nSize ) { int i; for ( i = 1; i < nSize; i++ ) Sfm_ObjCleanSatVar( p, i ); } static inline void Sfm_NtkCleanVars( Sfm_Ntk_t * p, int nSize ) { int i; for ( i = 1; i < nSize; i++ ) Sfm_ObjCleanSatVar( p, i ); }
static inline int Sfm_ObjLevel( Sfm_Ntk_t * p, int iObj ) { return Vec_IntEntry(&p->vLevels, iObj); }
static inline int Sfm_ObjUpdateFaninCount( Sfm_Ntk_t * p, int iObj ) { return Vec_IntAddToEntry(&p->vCounts, iObj, -1); }
static inline void Sfm_ObjResetFaninCount( Sfm_Ntk_t * p, int iObj ) { Vec_IntWriteEntry(&p->vCounts, iObj, Sfm_ObjFaninNum(p, iObj)-1); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Sfm_NtkForEachNode( p, i ) for ( i = p->nPis; i + p->nPos < p->nObjs; i++ )
#define Sfm_NodeForEachFanin( p, Node, Fan, i ) for ( i = 0; i < Sfm_ObjFaninNum(p, Node) && ((Fan = Sfm_ObjFanin(p, Node, i)), 1); i++ )
#define Sfm_NodeForEachFanout( p, Node, Fan, i ) for ( i = 0; i < Sfm_ObjFanoutNum(p, Node) && ((Fan = Sfm_ObjFanout(p, Node, i)), 1); i++ )
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS /// /// FUNCTION DECLARATIONS ///
...@@ -124,7 +140,7 @@ extern Sfm_Ntk_t * Sfm_ConstructNetwork( Vec_Wec_t * vFanins, int nPis, int nPo ...@@ -124,7 +140,7 @@ extern Sfm_Ntk_t * Sfm_ConstructNetwork( Vec_Wec_t * vFanins, int nPis, int nPo
/*=== sfmSat.c ==========================================================*/ /*=== sfmSat.c ==========================================================*/
extern word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_t * vDivs, Vec_Int_t * vLits, Vec_Int_t * vDiffs, int nBTLimit ); extern word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_t * vDivs, Vec_Int_t * vLits, Vec_Int_t * vDiffs, int nBTLimit );
/*=== sfmWin.c ==========================================================*/ /*=== sfmWin.c ==========================================================*/
extern int Sfm_NtkWindow( Sfm_Ntk_t * p, int iNode ); extern int Sfm_NtkWindow( Sfm_Ntk_t * p, int iNode, int fVerbose );
extern void Sfm_NtkWin2Sat( Sfm_Ntk_t * p ); extern void Sfm_NtkWin2Sat( Sfm_Ntk_t * p );
......
...@@ -72,13 +72,12 @@ void Sfm_CheckConsistency( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t * ...@@ -72,13 +72,12 @@ void Sfm_CheckConsistency( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t *
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Wec_t * Sfm_CreateFanout( Vec_Wec_t * vFanins ) void Sfm_CreateFanout( Vec_Wec_t * vFanins, Vec_Wec_t * vFanouts )
{ {
Vec_Wec_t * vFanouts;
Vec_Int_t * vArray; Vec_Int_t * vArray;
int i, k, Fanin; int i, k, Fanin;
// count fanouts // count fanouts
vFanouts = Vec_WecStart( Vec_WecSize(vFanins) ); Vec_WecInit( vFanouts, Vec_WecSize(vFanins) );
Vec_WecForEachLevel( vFanins, vArray, i ) Vec_WecForEachLevel( vFanins, vArray, i )
Vec_IntForEachEntry( vArray, Fanin, k ) Vec_IntForEachEntry( vArray, Fanin, k )
Vec_WecEntry( vFanouts, Fanin )->nSize++; Vec_WecEntry( vFanouts, Fanin )->nSize++;
...@@ -93,9 +92,8 @@ Vec_Wec_t * Sfm_CreateFanout( Vec_Wec_t * vFanins ) ...@@ -93,9 +92,8 @@ Vec_Wec_t * Sfm_CreateFanout( Vec_Wec_t * vFanins )
Vec_IntForEachEntry( vArray, Fanin, k ) Vec_IntForEachEntry( vArray, Fanin, k )
Vec_IntPush( Vec_WecEntry( vFanouts, Fanin ), i ); Vec_IntPush( Vec_WecEntry( vFanouts, Fanin ), i );
// verify // verify
Vec_WecForEachLevel( vFanins, vArray, i ) Vec_WecForEachLevel( vFanouts, vArray, i )
assert( Vec_IntSize(vArray) == Vec_IntCap(vArray) ); assert( Vec_IntSize(vArray) == Vec_IntCap(vArray) );
return vFanouts;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -109,17 +107,15 @@ Vec_Wec_t * Sfm_CreateFanout( Vec_Wec_t * vFanins ) ...@@ -109,17 +107,15 @@ Vec_Wec_t * Sfm_CreateFanout( Vec_Wec_t * vFanins )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Sfm_CreateLevel( Vec_Wec_t * vFanins ) void Sfm_CreateLevel( Vec_Wec_t * vFanins, Vec_Int_t * vLevels )
{ {
Vec_Int_t * vLevels;
Vec_Int_t * vArray; Vec_Int_t * vArray;
int i, k, Fanin, * pLevels; int i, k, Fanin, * pLevels;
vLevels = Vec_IntStart( Vec_WecSize(vFanins) ); Vec_IntFill( vLevels, Vec_WecSize(vFanins), 0 );
pLevels = Vec_IntArray( vLevels ); pLevels = Vec_IntArray( vLevels );
Vec_WecForEachLevel( vFanins, vArray, i ) Vec_WecForEachLevel( vFanins, vArray, i )
Vec_IntForEachEntry( vArray, Fanin, k ) Vec_IntForEachEntry( vArray, Fanin, k )
pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Fanin] + 1 ); pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Fanin] + 1 );
return vLevels;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -143,7 +139,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p ) ...@@ -143,7 +139,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p )
vCnfs = Vec_WecStart( p->nObjs ); vCnfs = Vec_WecStart( p->nObjs );
Vec_WrdForEachEntryStartStop( p->vTruths, uTruth, i, p->nPis, Vec_WrdSize(p->vTruths)-p->nPos ) Vec_WrdForEachEntryStartStop( p->vTruths, uTruth, i, p->nPis, Vec_WrdSize(p->vTruths)-p->nPos )
{ {
Sfm_TruthToCnf( uTruth, Vec_IntSize(Vec_WecEntry(p->vFanins, i)), p->vCover, vCnf ); Sfm_TruthToCnf( uTruth, Sfm_ObjFaninNum(p, i), p->vCover, vCnf );
vCnfBase = (Vec_Str_t *)Vec_WecEntry( vCnfs, i ); vCnfBase = (Vec_Str_t *)Vec_WecEntry( vCnfs, i );
Vec_StrGrow( vCnfBase, Vec_StrSize(vCnf) ); Vec_StrGrow( vCnfBase, Vec_StrSize(vCnf) );
memcpy( Vec_StrArray(vCnfBase), Vec_StrArray(vCnf), Vec_StrSize(vCnf) ); memcpy( Vec_StrArray(vCnfBase), Vec_StrArray(vCnf), Vec_StrSize(vCnf) );
...@@ -173,14 +169,17 @@ Sfm_Ntk_t * Sfm_NtkConstruct( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t ...@@ -173,14 +169,17 @@ Sfm_Ntk_t * Sfm_NtkConstruct( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t
p->nPis = nPis; p->nPis = nPis;
p->nPos = nPos; p->nPos = nPos;
p->nNodes = p->nObjs - p->nPis - p->nPos; p->nNodes = p->nObjs - p->nPis - p->nPos;
p->vFanins = vFanins;
// user data // user data
p->vFixed = vFixed; p->vFixed = vFixed;
p->vTruths = vTruths; p->vTruths = vTruths;
p->vFanins = *vFanins;
ABC_FREE( vFanins );
// attributes // attributes
p->vFanouts = Sfm_CreateFanout( vFanins ); Sfm_CreateFanout( &p->vFanins, &p->vFanouts );
p->vLevels = Sfm_CreateLevel( vFanins ); Sfm_CreateLevel( &p->vFanins, &p->vLevels );
Vec_IntFill( &p->vCounts, p->nObjs, 0 );
Vec_IntFill( &p->vTravIds, p->nObjs, 0 ); Vec_IntFill( &p->vTravIds, p->nObjs, 0 );
Vec_IntFill( &p->vTravIds2, p->nObjs, 0 );
Vec_IntFill( &p->vId2Var, p->nObjs, -1 ); Vec_IntFill( &p->vId2Var, p->nObjs, -1 );
Vec_IntFill( &p->vVar2Id, p->nObjs, -1 ); Vec_IntFill( &p->vVar2Id, p->nObjs, -1 );
p->vCover = Vec_IntAlloc( 1 << 16 ); p->vCover = Vec_IntAlloc( 1 << 16 );
...@@ -190,13 +189,15 @@ Sfm_Ntk_t * Sfm_NtkConstruct( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t ...@@ -190,13 +189,15 @@ Sfm_Ntk_t * Sfm_NtkConstruct( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t
void Sfm_NtkFree( Sfm_Ntk_t * p ) void Sfm_NtkFree( Sfm_Ntk_t * p )
{ {
// user data // user data
Vec_WecFree( p->vFanins );
Vec_StrFree( p->vFixed ); Vec_StrFree( p->vFixed );
Vec_WrdFree( p->vTruths ); Vec_WrdFree( p->vTruths );
Vec_WecErase( &p->vFanins );
// attributes // attributes
Vec_WecFree( p->vFanouts ); Vec_WecErase( &p->vFanouts );
Vec_IntFree( p->vLevels ); ABC_FREE( p->vLevels.pArray );
ABC_FREE( p->vCounts.pArray );
ABC_FREE( p->vTravIds.pArray ); ABC_FREE( p->vTravIds.pArray );
ABC_FREE( p->vTravIds2.pArray );
ABC_FREE( p->vId2Var.pArray ); ABC_FREE( p->vId2Var.pArray );
ABC_FREE( p->vVar2Id.pArray ); ABC_FREE( p->vVar2Id.pArray );
Vec_WecFree( p->vCnfs ); Vec_WecFree( p->vCnfs );
...@@ -207,7 +208,9 @@ void Sfm_NtkFree( Sfm_Ntk_t * p ) ...@@ -207,7 +208,9 @@ void Sfm_NtkFree( Sfm_Ntk_t * p )
Vec_IntFreeP( &p->vNodes ); Vec_IntFreeP( &p->vNodes );
Vec_IntFreeP( &p->vTfo ); Vec_IntFreeP( &p->vTfo );
Vec_IntFreeP( &p->vDivs ); Vec_IntFreeP( &p->vDivs );
Vec_IntFreeP( &p->vDivIds );
Vec_IntFreeP( &p->vLits ); Vec_IntFreeP( &p->vLits );
Vec_IntFreeP( &p->vDiffs );
Vec_WecFreeP( &p->vClauses ); Vec_WecFreeP( &p->vClauses );
Vec_IntFreeP( &p->vFaninMap ); Vec_IntFreeP( &p->vFaninMap );
if ( p->pSat0 ) sat_solver_delete( p->pSat0 ); if ( p->pSat0 ) sat_solver_delete( p->pSat0 );
...@@ -228,7 +231,7 @@ void Sfm_NtkFree( Sfm_Ntk_t * p ) ...@@ -228,7 +231,7 @@ void Sfm_NtkFree( Sfm_Ntk_t * p )
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Sfm_NodeReadFanins( Sfm_Ntk_t * p, int i ) Vec_Int_t * Sfm_NodeReadFanins( Sfm_Ntk_t * p, int i )
{ {
return Vec_WecEntry( p->vFanins, i ); return Vec_WecEntry( &p->vFanins, i );
} }
word Sfm_NodeReadTruth( Sfm_Ntk_t * p, int i ) word Sfm_NodeReadTruth( Sfm_Ntk_t * p, int i )
{ {
......
...@@ -42,6 +42,78 @@ static word s_Truths6[6] = { ...@@ -42,6 +42,78 @@ static word s_Truths6[6] = {
/**Function************************************************************* /**Function*************************************************************
Synopsis [Converts a window into a SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sfm_NtkWin2Sat( Sfm_Ntk_t * p )
{
Vec_Int_t * vClause;
int RetValue, Lit, iNode = -1, iFanin, i, k, c;
sat_solver * pSat0 = sat_solver_new();
sat_solver * pSat1 = sat_solver_new();
sat_solver_setnvars( pSat0, 1 + Vec_IntSize(p->vLeaves) + Vec_IntSize(p->vNodes) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) );
sat_solver_setnvars( pSat1, 1 + Vec_IntSize(p->vLeaves) + Vec_IntSize(p->vNodes) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) );
// create SAT variables
p->nSatVars = 1;
Vec_IntForEachEntryReverse( p->vNodes, iNode, i )
Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
Vec_IntForEachEntryReverse( p->vLeaves, iNode, i )
Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
Vec_IntForEachEntryReverse( p->vDivs, iNode, i )
Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
// add CNF clauses
for ( c = 0; c < 2; c++ )
{
Vec_Int_t * vObjs = c ? p->vDivs : p->vNodes;
Vec_IntForEachEntryReverse( vObjs, iNode, i )
{
// collect fanin variables
Vec_IntClear( p->vFaninMap );
Sfm_NodeForEachFanin( p, iNode, iFanin, k )
Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iFanin) );
Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iNode) );
// generate CNF
Sfm_TranslateCnf( p->vClauses, (Vec_Str_t *)Vec_WecEntry(p->vCnfs, iNode), p->vFaninMap );
// add clauses
Vec_WecForEachLevel( p->vClauses, vClause, k )
{
if ( Vec_IntSize(vClause) == 0 )
break;
RetValue = sat_solver_addclause( pSat0, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) );
assert( RetValue );
RetValue = sat_solver_addclause( pSat1, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) );
assert( RetValue );
}
}
}
// get the last node
iNode = Vec_IntEntryLast( p->vNodes );
// add unit clause
Lit = Abc_Var2Lit( Sfm_ObjSatVar(p, iNode), 1 );
RetValue = sat_solver_addclause( pSat0, &Lit, &Lit + 1 );
assert( RetValue );
// add unit clause
Lit = Abc_Var2Lit( Sfm_ObjSatVar(p, iNode), 0 );
RetValue = sat_solver_addclause( pSat1, &Lit, &Lit + 1 );
assert( RetValue );
// finalize
sat_solver_compress( pSat0 );
sat_solver_compress( pSat1 );
// return the result
assert( p->pSat0 == NULL );
assert( p->pSat1 == NULL );
p->pSat0 = pSat0;
p->pSat1 = pSat1;
}
/**Function*************************************************************
Synopsis [Takes SAT solver and returns interpolant.] Synopsis [Takes SAT solver and returns interpolant.]
Description [If interpolant does not exist, returns diff SAT variables.] Description [If interpolant does not exist, returns diff SAT variables.]
...@@ -51,12 +123,14 @@ static word s_Truths6[6] = { ...@@ -51,12 +123,14 @@ static word s_Truths6[6] = {
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_t * vDivs, Vec_Int_t * vLits, Vec_Int_t * vDiffs, int nBTLimit ) word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_t * vDivIds, Vec_Int_t * vLits, Vec_Int_t * vDiffs, int nBTLimit )
{ {
word uTruth = 0, uCube; word uTruth = 0, uCube;
int status, i, Div, iVar, nFinal, * pFinal; int status, i, Div, iVar, nFinal, * pFinal;
int nVars = sat_solver_nvars(pSatOn); int nVars = sat_solver_nvars(pSatOn);
int iNewLit = Abc_Var2Lit( nVars, 0 ); int iNewLit = Abc_Var2Lit( nVars, 0 );
int RetValue;
sat_solver_setnvars( pSatOn, nVars + 1 );
while ( 1 ) while ( 1 )
{ {
// find onset minterm // find onset minterm
...@@ -68,8 +142,9 @@ word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_ ...@@ -68,8 +142,9 @@ word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_
assert( status == l_True ); assert( status == l_True );
// collect literals // collect literals
Vec_IntClear( vLits ); Vec_IntClear( vLits );
Vec_IntForEachEntry( vDivs, Div, i ) Vec_IntForEachEntry( vDivIds, Div, i )
Vec_IntPush( vLits, Abc_LitNot(sat_solver_var_literal(pSatOn, Div)) ); // Vec_IntPush( vLits, Abc_LitNot(sat_solver_var_literal(pSatOn, Div)) );
Vec_IntPush( vLits, sat_solver_var_literal(pSatOn, Div) );
// check against offset // check against offset
status = sat_solver_solve( pSatOff, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); status = sat_solver_solve( pSatOff, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
if ( status == l_Undef ) if ( status == l_Undef )
...@@ -90,16 +165,60 @@ word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_ ...@@ -90,16 +165,60 @@ word Sfm_ComputeInterpolant( sat_solver * pSatOn, sat_solver * pSatOff, Vec_Int_
for ( i = 0; i < nFinal; i++ ) for ( i = 0; i < nFinal; i++ )
{ {
Vec_IntPush( vLits, pFinal[i] ); Vec_IntPush( vLits, pFinal[i] );
iVar = Vec_IntFind( vDivs, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); iVar = Vec_IntFind( vDivIds, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
} }
uTruth |= uCube; uTruth |= uCube;
sat_solver_addclause( pSatOn, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ); RetValue = sat_solver_addclause( pSatOn, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) );
assert( RetValue );
} }
assert( 0 ); assert( 0 );
return 0; return 0;
} }
/**Function*************************************************************
Synopsis [Checks resubstitution.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sfm_ComputeInterpolantCheck( Sfm_Ntk_t * p )
{
int iNode = 3;
int iDiv0 = 6;
int iDiv1 = 7;
word uTruth;
// int i;
// Sfm_NtkForEachNode( p, i )
{
Sfm_NtkWindow( p, iNode, 1 );
Sfm_NtkWin2Sat( p );
// collect SAT variables of divisors
Vec_IntClear( p->vDivIds );
Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iDiv0) );
Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iDiv1) );
uTruth = Sfm_ComputeInterpolant( p->pSat1, p->pSat0, p->vDivIds, p->vLits, p->vDiffs, 0 );
if ( uTruth == SFM_SAT_SAT )
printf( "The problem is SAT.\n" );
else if ( uTruth == SFM_SAT_UNDEC )
printf( "The problem is UNDEC.\n" );
else
Kit_DsdPrintFromTruth( (unsigned *)&uTruth, 2 ); printf( "\n" );
Sfm_NtkCleanVars( p, p->nSatVars );
sat_solver_delete( p->pSat0 ); p->pSat0 = NULL;
sat_solver_delete( p->pSat1 ); p->pSat1 = NULL;
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -46,6 +46,100 @@ static inline void Sfm_NtkIncrementTravId( Sfm_Ntk_t * p ) { p->nTra ...@@ -46,6 +46,100 @@ static inline void Sfm_NtkIncrementTravId( Sfm_Ntk_t * p ) { p->nTra
static inline void Sfm_ObjSetTravIdCurrent( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds, Id, p->nTravIds ); } static inline void Sfm_ObjSetTravIdCurrent( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds, Id, p->nTravIds ); }
static inline int Sfm_ObjIsTravIdCurrent( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds, Id) == p->nTravIds); } static inline int Sfm_ObjIsTravIdCurrent( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds, Id) == p->nTravIds); }
static inline void Sfm_NtkIncrementTravId2( Sfm_Ntk_t * p ) { p->nTravIds2++; }
static inline void Sfm_ObjSetTravIdCurrent2( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds2, Id, p->nTravIds2 ); }
static inline int Sfm_ObjIsTravIdCurrent2( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds2, Id) == p->nTravIds2); }
/**Function*************************************************************
Synopsis [Check if this fanout overlaps with TFI cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sfm_NtkCheckOverlap_rec( Sfm_Ntk_t * p, int iThis, int iNode )
{
int i, iFanin;
if ( Sfm_ObjIsTravIdCurrent2(p, iThis) || iThis == iNode )
return 0;
if ( Sfm_ObjIsTravIdCurrent(p, iThis) )
return 1;
Sfm_ObjSetTravIdCurrent2(p, iThis);
Sfm_NodeForEachFanin( p, iThis, iFanin, i )
if ( Sfm_NtkCheckOverlap_rec(p, iFanin, iNode) )
return 1;
return 0;
}
int Sfm_NtkCheckOverlap( Sfm_Ntk_t * p, int iFan, int iNode )
{
Sfm_NtkIncrementTravId2( p );
return Sfm_NtkCheckOverlap_rec( p, iFan, iNode );
}
/**Function*************************************************************
Synopsis [Check fanouts of the node.]
Description [Returns 1 if they can be used instead of the node.]
SideEffects []
SeeAlso []
***********************************************************************/
int Sfm_NtkCheckFanouts( Sfm_Ntk_t * p, int iNode )
{
int i, iFanout;
if ( Sfm_ObjFanoutNum(p, iNode) >= p->pPars->nFanoutMax )
return 0;
Sfm_NodeForEachFanout( p, iNode, iFanout, i )
if ( !Sfm_NtkCheckOverlap( p, iFanout, iNode ) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Collects divisors of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sfm_NtkAddDivisors( Sfm_Ntk_t * p, int iNode )
{
int i, iFanout;
Sfm_NodeForEachFanout( p, iNode, iFanout, i )
{
// skip TFI nodes, PO nodes, and nodes with high fanout or nodes with high logic level
if ( Sfm_ObjIsTravIdCurrent(p, iFanout) || Sfm_ObjIsPo(p, iFanout) ||
Sfm_ObjFanoutNum(p, iFanout) >= p->pPars->nFanoutMax ||
(p->pPars->fFixLevel && Sfm_ObjLevel(p, iFanout) >= Sfm_ObjLevel(p, iNode)) )
continue;
// handle single-input nodes
if ( Sfm_ObjFaninNum(p, iFanout) == 1 )
Vec_IntPush( p->vDivs, iFanout );
// visit node for the first time
else if ( !Sfm_ObjIsTravIdCurrent2(p, iFanout) )
{
assert( Sfm_ObjFaninNum(p, iFanout) > 1 );
Sfm_ObjSetTravIdCurrent2( p, iFanout );
Sfm_ObjResetFaninCount( p, iFanout );
}
// visit node again
else if ( Sfm_ObjUpdateFaninCount(p, iFanout) == 0 )
Vec_IntPush( p->vDivs, iFanout );
}
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes structural window.] Synopsis [Computes structural window.]
...@@ -72,94 +166,63 @@ void Sfm_NtkCollectTfi_rec( Sfm_Ntk_t * p, int iNode ) ...@@ -72,94 +166,63 @@ void Sfm_NtkCollectTfi_rec( Sfm_Ntk_t * p, int iNode )
Sfm_NtkCollectTfi_rec( p, iFanin ); Sfm_NtkCollectTfi_rec( p, iFanin );
Vec_IntPush( p->vNodes, iNode ); Vec_IntPush( p->vNodes, iNode );
} }
int Sfm_NtkWindow( Sfm_Ntk_t * p, int iNode ) int Sfm_NtkWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
{ {
// int i, iRoot; int i, iTemp;
/*
if ( iNode == 7 )
{
int iLevel = Sfm_ObjLevel(p, iNode);
int s = 0;
}
*/
assert( Sfm_ObjIsNode( p, iNode ) ); assert( Sfm_ObjIsNode( p, iNode ) );
Sfm_NtkIncrementTravId( p );
Vec_IntClear( p->vLeaves ); // leaves Vec_IntClear( p->vLeaves ); // leaves
Vec_IntClear( p->vNodes ); // internal Vec_IntClear( p->vNodes ); // internal
// collect transitive fanin // collect transitive fanin
Sfm_NtkIncrementTravId( p );
Sfm_NtkCollectTfi_rec( p, iNode ); Sfm_NtkCollectTfi_rec( p, iNode );
// collect TFO // collect TFO (currently use only one level of TFO)
Vec_IntClear( p->vRoots ); // roots Vec_IntClear( p->vRoots ); // roots
Vec_IntClear( p->vTfo ); // roots Vec_IntClear( p->vTfo ); // roots
Vec_IntPush( p->vRoots, iNode ); if ( Sfm_NtkCheckFanouts(p, iNode) )
/*
Vec_IntForEachEntry( p->vRoots, iRoot, i )
{ {
assert( Sfm_ObjIsNode(p, iRoot) ); Sfm_NodeForEachFanout( p, iNode, iTemp, i )
if ( Sfm_ObjIsTravIdCurrent(p, iRoot) ) {
continue; if ( Sfm_ObjIsPo(p, iTemp) )
if ( Sfm_ObjFanoutNum(p, iRoot) >= p->pPars->nFanoutMax )
continue; continue;
Vec_IntPush( p->vRoots, iTemp );
Vec_IntPush( p->vTfo, iTemp );
} }
*/ }
else
Vec_IntPush( p->vRoots, iNode );
// collect divisors of the TFI nodes
Vec_IntClear( p->vDivs );
Sfm_NtkIncrementTravId2( p );
Vec_IntForEachEntry( p->vLeaves, iTemp, i )
Sfm_NtkAddDivisors( p, iTemp );
Vec_IntForEachEntry( p->vNodes, iTemp, i )
Sfm_NtkAddDivisors( p, iTemp );
Vec_IntForEachEntry( p->vDivs, iTemp, i )
Sfm_NtkAddDivisors( p, iTemp );
if ( !fVerbose )
return 1; return 1;
}
/**Function*************************************************************
Synopsis [Converts a window into a SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/ // print stats about the window
void Sfm_NtkWin2Sat( Sfm_Ntk_t * p ) printf( "%6d : ", iNode );
printf( "Leaves = %5d. ", Vec_IntSize(p->vLeaves) );
printf( "Nodes = %5d. ", Vec_IntSize(p->vNodes) );
printf( "Roots = %5d. ", Vec_IntSize(p->vRoots) );
printf( "Divs = %5d. ", Vec_IntSize(p->vDivs) );
printf( "\n" );
return 1;
}
void Sfm_NtkWindowTest( Sfm_Ntk_t * p, int iNode )
{ {
Vec_Int_t * vClause; int i;
int RetValue, Lit, iNode = -1, iFanin, i, k; Sfm_NtkForEachNode( p, i )
sat_solver * pSat0 = sat_solver_new(); Sfm_NtkWindow( p, i, 1 );
sat_solver * pSat1 = sat_solver_new();
sat_solver_setnvars( pSat0, 1 + Vec_IntSize(p->vLeaves) + Vec_IntSize(p->vNodes) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) );
sat_solver_setnvars( pSat1, 1 + Vec_IntSize(p->vLeaves) + Vec_IntSize(p->vNodes) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) );
// create SAT variables
p->nSatVars = 1;
Vec_IntForEachEntryReverse( p->vNodes, iNode, i )
Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
Vec_IntForEachEntryReverse( p->vLeaves, iNode, i )
Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
// add CNF clauses
Vec_IntForEachEntryReverse( p->vNodes, iNode, i )
{
// collect fanin variables
Vec_IntClear( p->vFaninMap );
Sfm_NodeForEachFanin( p, iNode, iFanin, k )
Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iFanin) );
Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iNode) );
// generate CNF
Sfm_TranslateCnf( p->vClauses, (Vec_Str_t *)Vec_WecEntry(p->vCnfs, iNode), p->vFaninMap );
// add clauses
Vec_WecForEachLevel( p->vClauses, vClause, k )
{
if ( Vec_IntSize(vClause) == 0 )
break;
RetValue = sat_solver_addclause( pSat0, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) );
assert( RetValue );
RetValue = sat_solver_addclause( pSat1, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) );
assert( RetValue );
}
}
// add unit clause
Lit = Abc_Var2Lit( Sfm_ObjSatVar(p, iNode), 1 );
RetValue = sat_solver_addclause( pSat0, &Lit, &Lit + 1 );
assert( RetValue );
// add unit clause
Lit = Abc_Var2Lit( Sfm_ObjSatVar(p, iNode), 0 );
RetValue = sat_solver_addclause( pSat1, &Lit, &Lit + 1 );
assert( RetValue );
// finalize
sat_solver_compress( p->pSat0 );
sat_solver_compress( p->pSat1 );
// return the result
assert( p->pSat0 == NULL );
assert( p->pSat1 == NULL );
p->pSat0 = pSat0;
p->pSat1 = pSat1;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment