mirror of https://github.com/YosysHQ/abc.git
Experiments with don't-cares.
This commit is contained in:
parent
1ac9d2997c
commit
a34d8cbb36
|
|
@ -5695,7 +5695,7 @@ SOURCE=.\src\proof\acec\acec.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acec2Booth.c
|
||||
SOURCE=.\src\proof\acec\acec2Mult.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
|
|||
|
|
@ -88,9 +88,13 @@ struct Acb_Ntk_t_
|
|||
Vec_Int_t vLevelR; // level
|
||||
Vec_Int_t vPathD; // path
|
||||
Vec_Int_t vPathR; // path
|
||||
Vec_Wec_t vClauses;
|
||||
Vec_Wec_t vCnfs;
|
||||
Vec_Int_t vCover;
|
||||
// other
|
||||
Vec_Int_t vArray0;
|
||||
Vec_Int_t vArray1;
|
||||
Vec_Int_t vArray2;
|
||||
};
|
||||
|
||||
// design
|
||||
|
|
@ -239,6 +243,7 @@ static inline int Acb_ObjFanOffset( Acb_Ntk_t * p, int i ) { a
|
|||
static inline int * Acb_ObjFanins( Acb_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vFanSto, Acb_ObjFanOffset(p, i)); }
|
||||
static inline int Acb_ObjFanin( Acb_Ntk_t * p, int i, int k ) { return Acb_ObjFanins(p, i)[k+1]; }
|
||||
static inline int Acb_ObjFaninNum( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[0]; }
|
||||
static inline int Acb_ObjFanoutNum( Acb_Ntk_t * p, int i ) { return Vec_IntSize( Vec_WecEntry(&p->vFanouts, i) ); }
|
||||
static inline int Acb_ObjFanin0( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[1]; }
|
||||
static inline int Acb_ObjCioId( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[2]; }
|
||||
|
||||
|
|
@ -272,28 +277,31 @@ static inline int Acb_ObjUpdateLevelR( Acb_Ntk_t * p, int i, int x )
|
|||
static inline int Acb_ObjAddToPathD( Acb_Ntk_t * p, int i, int x ) { Vec_IntAddToEntry( &p->vPathD, i, x ); return x; }
|
||||
static inline int Acb_ObjAddToPathR( Acb_Ntk_t * p, int i, int x ) { Vec_IntAddToEntry( &p->vPathR, i, x ); return x; }
|
||||
|
||||
static inline int Acb_ObjNtkId( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_ObjIsBox(p, i) ? Acb_ObjFanin(p, i, Acb_ObjFaninNum(p, i)) : 0; }
|
||||
static inline Acb_Ntk_t * Acb_ObjNtk( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_NtkNtk(p, Acb_ObjNtkId(p, i)); }
|
||||
static inline int Acb_ObjIsSeq( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_ObjIsBox(p, i) ? Acb_ObjNtk(p, i)->fSeq : Acb_TypeIsSeq(Acb_ObjType(p, i)); }
|
||||
static inline int Acb_ObjNtkId( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_ObjIsBox(p, i) ? Acb_ObjFanin(p, i, Acb_ObjFaninNum(p, i)) : 0; }
|
||||
static inline Acb_Ntk_t * Acb_ObjNtk( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_NtkNtk(p, Acb_ObjNtkId(p, i)); }
|
||||
static inline int Acb_ObjIsSeq( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_ObjIsBox(p, i) ? Acb_ObjNtk(p, i)->fSeq : Acb_TypeIsSeq(Acb_ObjType(p, i)); }
|
||||
|
||||
static inline int Acb_ObjRangeId( Acb_Ntk_t * p, int i ) { return Acb_NtkHasObjRanges(p) ? Vec_IntGetEntry(&p->vObjRange, i) : 0; }
|
||||
static inline int Acb_ObjRange( Acb_Ntk_t * p, int i ) { return Abc_Lit2Var( Acb_ObjRangeId(p, i) ); }
|
||||
static inline int Acb_ObjLeft( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeLeft(p, Acb_ObjRange(p, i)); }
|
||||
static inline int Acb_ObjRight( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeRight(p, Acb_ObjRange(p, i)); }
|
||||
static inline int Acb_ObjSigned( Acb_Ntk_t * p, int i ) { return Abc_LitIsCompl(Acb_ObjRangeId(p, i)); }
|
||||
static inline int Acb_ObjRangeSize( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeSize(p, Acb_ObjRange(p, i)); }
|
||||
static inline int Acb_ObjRangeId( Acb_Ntk_t * p, int i ) { return Acb_NtkHasObjRanges(p) ? Vec_IntGetEntry(&p->vObjRange, i) : 0; }
|
||||
static inline int Acb_ObjRange( Acb_Ntk_t * p, int i ) { return Abc_Lit2Var( Acb_ObjRangeId(p, i) ); }
|
||||
static inline int Acb_ObjLeft( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeLeft(p, Acb_ObjRange(p, i)); }
|
||||
static inline int Acb_ObjRight( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeRight(p, Acb_ObjRange(p, i)); }
|
||||
static inline int Acb_ObjSigned( Acb_Ntk_t * p, int i ) { return Abc_LitIsCompl(Acb_ObjRangeId(p, i)); }
|
||||
static inline int Acb_ObjRangeSize( Acb_Ntk_t * p, int i ) { return Acb_NtkRangeSize(p, Acb_ObjRange(p, i)); }
|
||||
static inline void Acb_ObjSetRangeSign( Acb_Ntk_t * p, int i, int x ) { assert(Acb_NtkHasObjRanges(p)); Vec_IntSetEntry(&p->vObjRange, i, x); }
|
||||
static inline void Acb_ObjSetRange( Acb_Ntk_t * p, int i, int x ) { assert(Acb_NtkHasObjRanges(p)); Vec_IntSetEntry(&p->vObjRange, i, Abc_Var2Lit(x,0)); }
|
||||
static inline void Acb_ObjHashRange( Acb_Ntk_t * p, int i, int l, int r ) { Acb_ObjSetRange( p, i, Acb_NtkHashRange(p, l, r) ); }
|
||||
static inline int Acb_ObjRangeSign( Acb_Ntk_t * p, int i ) { return Abc_Var2Lit( Acb_ObjRangeSize(p, i), Acb_ObjSigned(p, i) ); }
|
||||
static inline int Acb_ObjRangeSign( Acb_Ntk_t * p, int i ) { return Abc_Var2Lit( Acb_ObjRangeSize(p, i), Acb_ObjSigned(p, i) ); }
|
||||
|
||||
static inline int Acb_ObjTravId( Acb_Ntk_t * p, int i ) { return Vec_IntGetEntry(&p->vObjTrav, i); }
|
||||
static inline int Acb_ObjIsTravIdCur( Acb_Ntk_t * p, int i ) { return Acb_ObjTravId(p, i) == p->nObjTravs; }
|
||||
static inline int Acb_ObjIsTravIdPrev( Acb_Ntk_t * p, int i ) { return Acb_ObjTravId(p, i) == p->nObjTravs-1; }
|
||||
static inline int Acb_ObjSetTravIdCur( Acb_Ntk_t * p, int i ) { int r = Acb_ObjIsTravIdCur(p, i); Vec_IntWriteEntry(&p->vObjTrav, i, p->nObjTravs); return r; }
|
||||
static inline int Acb_ObjSetTravIdPrev( Acb_Ntk_t * p, int i ) { int r = Acb_ObjIsTravIdPrev(p, i); Vec_IntWriteEntry(&p->vObjTrav, i, p->nObjTravs-1); return r; }
|
||||
static inline int Acb_NtkTravId( Acb_Ntk_t * p ) { return p->nObjTravs; }
|
||||
static inline void Acb_NtkIncTravId( Acb_Ntk_t * p ) { if ( !Acb_NtkHasObjTravs(p) ) Acb_NtkCleanObjTravs(p); p->nObjTravs++; }
|
||||
static inline int Acb_ObjTravId( Acb_Ntk_t * p, int i ) { return Vec_IntGetEntry(&p->vObjTrav, i); }
|
||||
static inline int Acb_ObjTravIdDiff( Acb_Ntk_t * p, int i ) { return p->nObjTravs - Vec_IntGetEntry(&p->vObjTrav, i); }
|
||||
static inline int Acb_ObjIsTravIdCur( Acb_Ntk_t * p, int i ) { return Acb_ObjTravId(p, i) == p->nObjTravs; }
|
||||
static inline int Acb_ObjIsTravIdPrev( Acb_Ntk_t * p, int i ) { return Acb_ObjTravId(p, i) == p->nObjTravs-1; }
|
||||
static inline int Acb_ObjIsTravIdDiff( Acb_Ntk_t * p, int i, int d ) { return Acb_ObjTravId(p, i) == p->nObjTravs-d; }
|
||||
static inline int Acb_ObjSetTravIdCur( Acb_Ntk_t * p, int i ) { int r = Acb_ObjIsTravIdCur(p, i); Vec_IntWriteEntry(&p->vObjTrav, i, p->nObjTravs); return r; }
|
||||
static inline int Acb_ObjSetTravIdPrev( Acb_Ntk_t * p, int i ) { int r = Acb_ObjIsTravIdPrev(p, i); Vec_IntWriteEntry(&p->vObjTrav, i, p->nObjTravs-1); return r; }
|
||||
static inline int Acb_ObjSetTravIdDiff( Acb_Ntk_t * p, int i, int d ) { int r = Acb_ObjTravIdDiff(p, i); Vec_IntWriteEntry(&p->vObjTrav, i, p->nObjTravs-d); return r; }
|
||||
static inline int Acb_NtkTravId( Acb_Ntk_t * p ) { return p->nObjTravs; }
|
||||
static inline void Acb_NtkIncTravId( Acb_Ntk_t * p ) { if ( !Acb_NtkHasObjTravs(p) ) Acb_NtkCleanObjTravs(p); p->nObjTravs++; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
|
|
@ -493,6 +501,7 @@ static inline void Acb_NtkFree( Acb_Ntk_t * p )
|
|||
// other
|
||||
Vec_IntErase( &p->vArray0 );
|
||||
Vec_IntErase( &p->vArray1 );
|
||||
Vec_IntErase( &p->vArray2 );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
static inline int Acb_NtkNewStrId( Acb_Ntk_t * pNtk, const char * format, ... )
|
||||
|
|
@ -663,8 +672,9 @@ static inline int Acb_NtkMemory( Acb_Ntk_t * p )
|
|||
nMem += (int)Vec_IntMemory(&p->vNtkObjs );
|
||||
nMem += (int)Vec_IntMemory(&p->vTargets );
|
||||
// other
|
||||
nMem += (int)Vec_IntMemory(&p->vArray0 );
|
||||
nMem += (int)Vec_IntMemory(&p->vArray1 );
|
||||
nMem += (int)Vec_IntMemory(&p->vArray1 );
|
||||
nMem += (int)Vec_IntMemory(&p->vArray2 );
|
||||
return nMem;
|
||||
}
|
||||
static inline void Acb_NtkPrintStats( Acb_Ntk_t * p )
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acb.c]
|
||||
FileName [abcMfs.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Optimization with don't-cares.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -14,11 +14,13 @@
|
|||
|
||||
Date [Ver. 1.0. Started - July 21, 2015.]
|
||||
|
||||
Revision [$Id: acb.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: abcMfs.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "acb.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "sat/bsat/satSolver.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -41,7 +43,591 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acb_Truth2Cnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf )
|
||||
{
|
||||
Vec_StrClear( vCnf );
|
||||
if ( Truth == 0 || ~Truth == 0 )
|
||||
{
|
||||
// assert( nVars == 0 );
|
||||
Vec_StrPush( vCnf, (char)(Truth == 0) );
|
||||
Vec_StrPush( vCnf, (char)-1 );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, k, c, RetValue, Literal, Cube, nCubes = 0;
|
||||
assert( nVars > 0 );
|
||||
for ( c = 0; c < 2; c ++ )
|
||||
{
|
||||
Truth = c ? ~Truth : Truth;
|
||||
RetValue = Kit_TruthIsop( (unsigned *)&Truth, nVars, vCover, 0 );
|
||||
assert( RetValue == 0 );
|
||||
nCubes += Vec_IntSize( vCover );
|
||||
Vec_IntForEachEntry( vCover, Cube, i )
|
||||
{
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
{
|
||||
Literal = 3 & (Cube >> (k << 1));
|
||||
if ( Literal == 1 ) // '0' -> pos lit
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(k, 0) );
|
||||
else if ( Literal == 2 ) // '1' -> neg lit
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(k, 1) );
|
||||
else if ( Literal != 0 )
|
||||
assert( 0 );
|
||||
}
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(nVars, c) );
|
||||
Vec_StrPush( vCnf, (char)-1 );
|
||||
}
|
||||
}
|
||||
return nCubes;
|
||||
}
|
||||
}
|
||||
Vec_Wec_t * Acb_NtkDeriveCnf( Acb_Ntk_t * p )
|
||||
{
|
||||
Vec_Wec_t * vCnfs = Vec_WecStart( Acb_NtkObjNumMax(p) );
|
||||
Vec_Str_t * vCnf = Vec_StrAlloc( 100 ); int iObj;
|
||||
Acb_NtkForEachNode( p, iObj )
|
||||
{
|
||||
int nCubes = Acb_Truth2Cnf( Acb_ObjTruth(p, iObj), Acb_ObjFaninNum(p, iObj), &p->vCover, vCnf );
|
||||
Vec_Str_t * vCnfBase = (Vec_Str_t *)Vec_WecEntry( vCnfs, iObj );
|
||||
Vec_StrGrow( vCnfBase, Vec_StrSize(vCnf) );
|
||||
memcpy( Vec_StrArray(vCnfBase), Vec_StrArray(vCnf), Vec_StrSize(vCnf) );
|
||||
vCnfBase->nSize = Vec_StrSize(vCnf);
|
||||
}
|
||||
Vec_StrFree( vCnf );
|
||||
return vCnfs;
|
||||
}
|
||||
void Acb_CnfTranslate( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vSatVars, int iPivotVar )
|
||||
{
|
||||
Vec_Int_t * vClause;
|
||||
signed char Entry;
|
||||
int i, Lit;
|
||||
Vec_WecClear( vRes );
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
Vec_StrForEachEntry( vCnf, Entry, i )
|
||||
{
|
||||
if ( (int)Entry == -1 )
|
||||
{
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
continue;
|
||||
}
|
||||
Lit = Abc_Lit2LitV( Vec_IntArray(vSatVars), (int)Entry );
|
||||
Lit = Abc_LitNotCond( Lit, Abc_Lit2Var(Lit) == iPivotVar );
|
||||
Vec_IntPush( vClause, Lit );
|
||||
}
|
||||
}
|
||||
int Acb_ObjCreateCnf( sat_solver * pSat, Acb_Ntk_t * p, int iObj, Vec_Int_t * vSatVars, int iPivotVar )
|
||||
{
|
||||
Vec_Int_t * vClause; int k, RetValue;
|
||||
Acb_CnfTranslate( &p->vClauses, (Vec_Str_t *)Vec_WecEntry(&p->vCnfs, iObj), vSatVars, iPivotVar );
|
||||
Vec_WecForEachLevel( &p->vClauses, vClause, k )
|
||||
{
|
||||
if ( Vec_IntSize(vClause) == 0 )
|
||||
break;
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vClause), Vec_IntLimit(vClause) );
|
||||
if ( RetValue == 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs SAT solver for the window.]
|
||||
|
||||
Description [The window for the pivot node is represented as a DFS ordered array
|
||||
of objects (vWinObjs) whose indexes are used as SAT variable IDs (stored in p->vCopies).
|
||||
PivotVar is the index of the pivot node in array vWinObjs.
|
||||
The nodes before (after) PivotVar are TFI (TFO) nodes.
|
||||
The leaf (root) nodes are labeled with Abc_LitIsCompl().
|
||||
If fQbf is 1, returns the instance meant for QBF solving. It uses the last
|
||||
variable (LastVar) as the placeholder for the second copy of the pivot node.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acb_NtkCountRoots( Vec_Int_t * vWinObjs, int PivotVar )
|
||||
{
|
||||
int i, iObjLit, nRoots = 0;
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObjLit, i, PivotVar + 1 )
|
||||
nRoots += Abc_LitIsCompl(iObjLit);
|
||||
return nRoots;
|
||||
}
|
||||
sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot, Vec_Int_t * vWinObjs, int fQbf )
|
||||
{
|
||||
Vec_Int_t * vFaninVars = Vec_IntAlloc( 8 );
|
||||
int PivotVar = Vec_IntFind(vWinObjs, Abc_Var2Lit(Pivot, 0));
|
||||
int nRoots = Acb_NtkCountRoots(vWinObjs, PivotVar);
|
||||
int TfoStart = PivotVar + 1;
|
||||
int nTfoSize = Vec_IntSize(vWinObjs) - TfoStart;
|
||||
int LastVar = Vec_IntSize(vWinObjs) + TfoStart + nRoots;
|
||||
int i, k, iLit = 1, RetValue, iObj, iObjLit, iFanin, * pFanins;
|
||||
//Vec_IntPrint( vWinObjs );
|
||||
// mark new SAT variables
|
||||
Vec_IntForEachEntry( vWinObjs, iObj, i )
|
||||
Acb_ObjSetCopy( p, i, iObj );
|
||||
// create SAT solver
|
||||
if ( pSat == NULL )
|
||||
pSat = sat_solver_new();
|
||||
else
|
||||
sat_solver_restart( pSat );
|
||||
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + nTfoSize + nRoots + 1 );
|
||||
// create constant 0 clause
|
||||
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
|
||||
// add clauses for all nodes
|
||||
Vec_IntForEachEntryStop( vWinObjs, iObjLit, i, TfoStart )
|
||||
{
|
||||
if ( Abc_LitIsCompl(iObjLit) )
|
||||
continue;
|
||||
iObj = Abc_Lit2Var(iObjLit);
|
||||
assert( !Acb_ObjIsCio(p, iObj) );
|
||||
// collect SAT variables
|
||||
Vec_IntClear( vFaninVars );
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iFanin) );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iObj) );
|
||||
// derive CNF for the node
|
||||
RetValue = Acb_ObjCreateCnf( pSat, p, iObj, vFaninVars, -1 );
|
||||
assert( RetValue );
|
||||
}
|
||||
// add second clauses for the TFO
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObjLit, i, TfoStart )
|
||||
{
|
||||
iObj = Abc_Lit2Var(iObjLit);
|
||||
assert( !Acb_ObjIsCio(p, iObj) );
|
||||
// collect SAT variables
|
||||
Vec_IntClear( vFaninVars );
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPush( vFaninVars, (fQbf && iFanin == Pivot) ? LastVar : Acb_ObjCopy(p, iFanin) );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iObj) );
|
||||
// derive CNF for the node
|
||||
RetValue = Acb_ObjCreateCnf( pSat, p, iObj, vFaninVars, fQbf ? -1 : PivotVar );
|
||||
assert( RetValue );
|
||||
}
|
||||
if ( nRoots > 0 )
|
||||
{
|
||||
// create XOR clauses for the roots
|
||||
int nVars = Vec_IntSize(vWinObjs) + nTfoSize;
|
||||
Vec_IntClear( vFaninVars );
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObjLit, i, TfoStart )
|
||||
{
|
||||
if ( !Abc_LitIsCompl(iObjLit) )
|
||||
continue;
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
|
||||
sat_solver_add_xor( pSat, Acb_ObjCopy(p, iObj), Acb_ObjCopy(p, iObj) + nTfoSize, nVars++, 0 );
|
||||
}
|
||||
// make OR clause for the last nRoots variables
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vFaninVars), Vec_IntLimit(vFaninVars) );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
Vec_IntFree( vFaninVars );
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
assert( sat_solver_nvars(pSat) == nVars + 1 );
|
||||
}
|
||||
else if ( fQbf )
|
||||
{
|
||||
int n, pLits[2];
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
pLits[0] = Abc_Var2Lit( PivotVar, n );
|
||||
pLits[1] = Abc_Var2Lit( LastVar, n );
|
||||
RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 );
|
||||
assert( RetValue );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vFaninVars );
|
||||
// finalize
|
||||
RetValue = sat_solver_simplify( pSat );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
return pSat;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkUnmarkWindow( Acb_Ntk_t * p, Vec_Int_t * vWin )
|
||||
{
|
||||
int i, iObj;
|
||||
Vec_IntForEachEntry( vWin, iObj, i )
|
||||
Vec_IntWriteEntry( &p->vObjCopy, iObj, -1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Acb_ObjIsCritFanin( Acb_Ntk_t * p, int i, int f ) { return Acb_ObjLevelR(p, i) + Acb_ObjLevelD(p, f) == p->LevelMax; }
|
||||
Vec_Int_t * Acb_NtkDivisors( Acb_Ntk_t * p, int Pivot, int nTfiLevMin )
|
||||
{
|
||||
int i, k, iObj, iFanin, iFanin2, * pFanins, * pFanins2, Lev, Level = Acb_ObjLevelD(p, Pivot);
|
||||
// include non-critical pivot fanins AND fanins of critical pivot fanins
|
||||
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
|
||||
Acb_ObjForEachFaninFast( p, Pivot, pFanins, iFanin, i )
|
||||
{
|
||||
if ( !Acb_ObjIsCritFanin(p, Pivot, iFanin) ) // non-critical fanin
|
||||
Vec_IntPush( vDivs, iFanin );
|
||||
else // critical fanin
|
||||
Acb_ObjForEachFaninFast( p, iFanin, pFanins2, iFanin2, k )
|
||||
Vec_IntPushUnique( vDivs, iFanin2 );
|
||||
}
|
||||
// continue for a few more levels
|
||||
for ( Lev = Level-2; Lev >= nTfiLevMin; Lev-- )
|
||||
{
|
||||
Vec_IntForEachEntry( vDivs, iObj, i )
|
||||
if ( Acb_ObjLevelD(p, iObj) == Lev )
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPushUnique( vDivs, iFanin );
|
||||
}
|
||||
// sort them by level
|
||||
Vec_IntSelectSortCost( Vec_IntArray(vDivs), Vec_IntSize(vDivs), &p->vLevelD );
|
||||
return vDivs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks TFO of divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_ObjMarkTfo_rec( Acb_Ntk_t * p, int iObj, int Pivot, int nTfoLevMax, int nFanMax )
|
||||
{
|
||||
int iFanout, i;
|
||||
if ( Acb_ObjSetTravIdCur(p, iObj) )
|
||||
return;
|
||||
if ( Acb_ObjLevelD(p, iObj) > nTfoLevMax || Acb_ObjFanoutNum(p, iObj) >= nFanMax || iObj == Pivot )
|
||||
return;
|
||||
Acb_ObjForEachFanout( p, iObj, iFanout, i )
|
||||
Acb_ObjMarkTfo_rec( p, iFanout, Pivot, nTfoLevMax, nFanMax );
|
||||
}
|
||||
void Acb_ObjMarkTfo( Acb_Ntk_t * p, Vec_Int_t * vDivs, int Pivot, int nTfoLevMax, int nFanMax )
|
||||
{
|
||||
int i, iObj;
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vDivs, iObj, i )
|
||||
Acb_ObjMarkTfo_rec( p, iObj, Pivot, nTfoLevMax, nFanMax );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Labels TFO nodes with {none, root, inner} based on their type.]
|
||||
|
||||
Description [Assuming TFO of TFI is marked with the current trav ID.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acb_ObjLabelTfo_rec( Acb_Ntk_t * p, int iObj, int nTfoLevMax, int nFanMax )
|
||||
{
|
||||
int iFanout, i, Diff, fHasNone = 0;
|
||||
if ( (Diff = Acb_ObjTravIdDiff(p, iObj)) <= 2 )
|
||||
return Diff;
|
||||
Acb_ObjSetTravIdDiff( p, iObj, 2 );
|
||||
if ( Acb_ObjIsCo(p, iObj) || Acb_ObjLevelD(p, iObj) > nTfoLevMax )
|
||||
return 2;
|
||||
if ( Acb_ObjLevelD(p, iObj) == nTfoLevMax || Acb_ObjFanoutNum(p, iObj) >= nFanMax )
|
||||
{
|
||||
if ( Diff == 3 )
|
||||
Acb_ObjSetTravIdDiff( p, iObj, 1 ); // mark root
|
||||
return Acb_ObjTravIdDiff(p, iObj);
|
||||
}
|
||||
Acb_ObjForEachFanout( p, iObj, iFanout, i )
|
||||
fHasNone |= 2 == Acb_ObjLabelTfo_rec( p, iFanout, nTfoLevMax, nFanMax );
|
||||
if ( fHasNone && Diff == 3 )
|
||||
Acb_ObjSetTravIdDiff( p, iObj, 1 ); // root
|
||||
else
|
||||
Acb_ObjSetTravIdDiff( p, iObj, 0 ); // inner
|
||||
return Acb_ObjTravIdDiff(p, iObj);
|
||||
}
|
||||
int Acb_ObjLabelTfo( Acb_Ntk_t * p, int Root, int nTfoLevMax, int nFanMax )
|
||||
{
|
||||
Acb_NtkIncTravId( p ); // none (2) marked (3) unmarked (4)
|
||||
Acb_NtkIncTravId( p ); // root (1)
|
||||
Acb_NtkIncTravId( p ); // inner (0)
|
||||
assert( Acb_ObjTravIdDiff(p, Root) < 3 );
|
||||
return Acb_ObjLabelTfo_rec( p, Root, nTfoLevMax, nFanMax );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects labeled TFO.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_ObjDeriveTfo_rec( Acb_Ntk_t * p, int iObj, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
|
||||
{
|
||||
int iFanout, i, Diff = Acb_ObjTravIdDiff(p, iObj);
|
||||
if ( Acb_ObjSetTravIdCur(p, iObj) )
|
||||
return;
|
||||
if ( Diff == 2 ) // root
|
||||
{
|
||||
Vec_IntPush( vRoots, Diff );
|
||||
return;
|
||||
}
|
||||
assert( Diff == 1 );
|
||||
Acb_ObjForEachFanout( p, iObj, iFanout, i )
|
||||
Acb_ObjDeriveTfo_rec( p, iFanout, vTfo, vRoots );
|
||||
Vec_IntPush( vTfo, Diff );
|
||||
}
|
||||
void Acb_ObjDeriveTfo( Acb_Ntk_t * p, int Root, int nTfoLevMax, int nFanMax, Vec_Int_t ** pvTfo, Vec_Int_t ** pvRoots )
|
||||
{
|
||||
int Res = Acb_ObjLabelTfo( p, Root, nTfoLevMax, nFanMax );
|
||||
Vec_Int_t * vTfo = *pvTfo = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRoots = *pvRoots = Vec_IntAlloc( 100 );
|
||||
if ( Res ) // none or root
|
||||
return;
|
||||
Acb_NtkIncTravId( p ); // root (2) inner (1) visited (0)
|
||||
Acb_ObjDeriveTfo_rec( p, Root, vTfo, vRoots );
|
||||
assert( Vec_IntEntryLast(vTfo) == Root );
|
||||
Vec_IntPop( vTfo );
|
||||
assert( Vec_IntEntryLast(vRoots) != Root );
|
||||
Vec_IntReverseOrder( vTfo );
|
||||
Vec_IntReverseOrder( vRoots );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect side-inputs of the TFO, except the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acb_NtkCollectTfoSideInputs( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vTfo )
|
||||
{
|
||||
Vec_Int_t * vSide = Vec_IntAlloc( 100 );
|
||||
int i, k, Node, iFanin, * pFanins;
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vTfo, Node, i )
|
||||
Acb_ObjSetTravIdCur( p, Node ), assert( Node != Pivot );
|
||||
Vec_IntForEachEntry( vTfo, Node, i )
|
||||
Acb_ObjForEachFaninFast( p, Node, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjSetTravIdCur(p, iFanin) && iFanin != Pivot )
|
||||
Vec_IntPush( vSide, iFanin );
|
||||
return vSide;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [From side inputs, collect marked nodes and their unmarked fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkCollectNewTfi1_rec( Acb_Ntk_t * p, int iObj, Vec_Int_t * vTfiNew )
|
||||
{
|
||||
int i, iFanin, * pFanins;
|
||||
if ( !Acb_ObjIsTravIdPrev(p, iObj) )
|
||||
return;
|
||||
if ( Acb_ObjSetTravIdCur(p, iObj) )
|
||||
return;
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, i )
|
||||
Acb_NtkCollectNewTfi1_rec( p, iFanin, vTfiNew );
|
||||
Vec_IntPush( vTfiNew, iObj );
|
||||
}
|
||||
void Acb_NtkCollectNewTfi2_rec( Acb_Ntk_t * p, int iObj, Vec_Int_t * vTfiNew )
|
||||
{
|
||||
int i, iFanin, * pFanins;
|
||||
int fTravIdPrev = Acb_ObjIsTravIdPrev(p, iObj);
|
||||
if ( Acb_ObjSetTravIdCur(p, iObj) )
|
||||
return;
|
||||
if ( fTravIdPrev && !Acb_ObjIsCi(p, iObj) )
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, i )
|
||||
Acb_NtkCollectNewTfi2_rec( p, iFanin, vTfiNew );
|
||||
Vec_IntPush( vTfiNew, iObj );
|
||||
}
|
||||
Vec_Int_t * Acb_NtkCollectNewTfi( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vSide )
|
||||
{
|
||||
Vec_Int_t * vTfiNew = Vec_IntAlloc( 100 );
|
||||
int i, Node;
|
||||
Acb_NtkIncTravId( p );
|
||||
Acb_NtkCollectNewTfi1_rec( p, Pivot, vTfiNew );
|
||||
assert( Vec_IntEntryLast(vTfiNew) == Pivot );
|
||||
Vec_IntPop( vTfiNew );
|
||||
Vec_IntForEachEntry( vSide, Node, i )
|
||||
Acb_NtkCollectNewTfi2_rec( p, Node, vTfiNew );
|
||||
Vec_IntPush( vTfiNew, Pivot );
|
||||
return vTfiNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acb_NtkCollectWindow( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vTfi, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
|
||||
{
|
||||
Vec_Int_t * vWin = Vec_IntAlloc( 100 );
|
||||
int i, k, iObj, iFanin, * pFanins;
|
||||
// mark leaves
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vTfi, iObj, i )
|
||||
Acb_ObjSetTravIdCur(p, iObj);
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vTfi, iObj, i )
|
||||
if ( !Acb_ObjIsCi(p, iObj) )
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjIsTravIdCur(p, iFanin) )
|
||||
Acb_ObjSetTravIdCur(p, iObj);
|
||||
// add TFI
|
||||
Vec_IntForEachEntry( vTfi, iObj, i )
|
||||
Vec_IntPush( vWin, Abc_Var2Lit( iObj, Acb_ObjIsTravIdCur(p, iObj)) );
|
||||
// mark roots
|
||||
Vec_IntForEachEntry( vRoots, iObj, i )
|
||||
Acb_ObjSetTravIdCur(p, iObj);
|
||||
// add TFO
|
||||
Vec_IntForEachEntry( vTfo, iObj, i )
|
||||
Vec_IntPush( vWin, Abc_Var2Lit( iObj, Acb_ObjIsTravIdCur(p, iObj)) );
|
||||
return vWin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acb_NtkWindow( Acb_Ntk_t * p, int Pivot, int nTfiLevs, int nTfoLevs, int nFanMax, Vec_Int_t ** pvDivs )
|
||||
{
|
||||
int nTfiLevMin = Acb_ObjLevelD(p, Pivot) - nTfiLevs;
|
||||
int nTfoLevMax = Acb_ObjLevelD(p, Pivot) + nTfoLevs;
|
||||
Vec_Int_t * vWin, * vDivs, * vTfo, * vRoots, * vSide, * vTfi;
|
||||
// collect divisors by traversing limited TFI
|
||||
vDivs = Acb_NtkDivisors( p, Pivot, nTfiLevMin );
|
||||
// mark limited TFO of the divisors
|
||||
Acb_ObjMarkTfo( p, vDivs, Pivot, nTfoLevMax, nFanMax );
|
||||
// collect TFO and roots
|
||||
Acb_ObjDeriveTfo( p, Pivot, nTfoLevMax, nFanMax, &vTfo, &vRoots );
|
||||
// collect side inputs of the TFO
|
||||
vSide = Acb_NtkCollectTfoSideInputs( p, Pivot, vTfo );
|
||||
// collect new TFI
|
||||
vTfi = Acb_NtkCollectNewTfi( p, Pivot, vSide );
|
||||
// collect all nodes
|
||||
vWin = Acb_NtkCollectWindow( p, Pivot, vTfi, vTfo, vRoots );
|
||||
// cleanup
|
||||
Vec_IntFree( vTfi );
|
||||
Vec_IntFree( vTfo );
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_IntFree( vSide );
|
||||
*pvDivs = vDivs;
|
||||
return vWin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acb_NtkFindSupp( sat_solver * pSat, Acb_Ntk_t * p, Vec_Int_t * vWin, Vec_Int_t * vDivs, int nBTLimit )
|
||||
{
|
||||
int i, iObj, nDivsNew;
|
||||
// reload divisors in terms of SAT variables
|
||||
Vec_IntForEachEntry( vDivs, iObj, i )
|
||||
Vec_IntWriteEntry( vDivs, i, Acb_ObjCopy(p, iObj) );
|
||||
// try solving
|
||||
nDivsNew = sat_solver_minimize_assumptions( pSat, Vec_IntArray(vDivs), Vec_IntSize(vDivs), nBTLimit );
|
||||
Vec_IntShrink( vDivs, nDivsNew );
|
||||
// reload divisors in terms of network variables
|
||||
Vec_IntForEachEntry( vDivs, iObj, i )
|
||||
Vec_IntWriteEntry( vDivs, i, Vec_IntEntry(vWin, iObj) );
|
||||
return Vec_IntSize(vDivs);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkOptNode( Acb_Ntk_t * p, int Pivot, int nTfiLevs, int nTfoLevs, int nFanMax )
|
||||
{
|
||||
Vec_Int_t * vSupp = &p->vArray0;
|
||||
Vec_Int_t * vDivs, * vWin = Acb_NtkWindow( p, Pivot, nTfiLevs, nTfoLevs, nFanMax, &vDivs );
|
||||
sat_solver * pSat = Acb_NtkWindow2Solver( pSat, p, Pivot, vWin, 0 );
|
||||
int nSuppNew, Level = Acb_ObjLevelD( p, Pivot );
|
||||
|
||||
// try solving the original support
|
||||
Vec_IntClear( vSupp );
|
||||
Vec_IntAppend( vSupp, vDivs );
|
||||
nSuppNew = sat_solver_minimize_assumptions( pSat, Vec_IntArray(vSupp), Vec_IntSize(vSupp), 0 );
|
||||
Vec_IntShrink( vSupp, nSuppNew );
|
||||
|
||||
// try solving by level
|
||||
|
||||
Acb_NtkUnmarkWindow( p, vWin );
|
||||
Vec_IntFree( vWin );
|
||||
Vec_IntFree( vDivs );
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,7 @@ Vec_Int_t * Gia_ManGetTestPatterns( char * pFileName )
|
|||
continue;
|
||||
if ( c != '0' && c != '1' )
|
||||
{
|
||||
printf( "Wring symbol (%c) in the input file.\n", c );
|
||||
printf( "Wrong symbol (%c) in the input file.\n", c );
|
||||
Vec_IntFreeP( &vTests );
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue