summaryrefslogtreecommitdiffstats
path: root/src/aig/gia
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia')
-rw-r--r--src/aig/gia/gia.h10
-rw-r--r--src/aig/gia/giaDup.c51
-rw-r--r--src/aig/gia/giaEsop.c2
-rw-r--r--src/aig/gia/giaIf.c54
-rw-r--r--src/aig/gia/giaSupp.c887
-rw-r--r--src/aig/gia/module.make1
6 files changed, 1001 insertions, 4 deletions
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index 5ad87008..f8e36a4f 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -577,6 +577,7 @@ static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pO
static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
+static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); }
static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); }
static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); }
@@ -1464,6 +1465,15 @@ extern int Gia_ManComputeOneWin( Gia_Man_t * p, int iPivot, Vec_
/*=== giaStg.c ============================================================*/
extern void Gia_ManStgPrint( FILE * pFile, Vec_Int_t * vLines, int nIns, int nOuts, int nStates );
extern Gia_Man_t * Gia_ManStgRead( char * pFileName, int kHot, int fVerbose );
+/*=== giaSupp.c ============================================================*/
+typedef struct Gia_ManMin_t_ Gia_ManMin_t;
+extern Gia_ManMin_t * Gia_ManSuppStart( Gia_Man_t * pGia );
+extern void Gia_ManSuppStop( Gia_ManMin_t * p );
+extern int Gia_ManSupportAnd( Gia_ManMin_t * p, int iLit0, int iLit1 );
+typedef struct Gia_Man2Min_t_ Gia_Man2Min_t;
+extern Gia_Man2Min_t * Gia_Man2SuppStart( Gia_Man_t * pGia );
+extern void Gia_Man2SuppStop( Gia_Man2Min_t * p );
+extern int Gia_Man2SupportAnd( Gia_Man2Min_t * p, int iLit0, int iLit1 );
/*=== giaSweep.c ============================================================*/
extern Gia_Man_t * Gia_ManFraigSweepSimple( Gia_Man_t * p, void * pPars );
extern Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS, int fConst, int fEquiv, int fVerbose, int fVerbEquivs );
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index ee709df4..5e7dc639 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -1638,6 +1638,57 @@ Gia_Man_t * Gia_ManDupExist( Gia_Man_t * p, int iVar )
/**Function*************************************************************
+ Synopsis [Existentially quantified given variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupUniv( Gia_Man_t * p, int iVar )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( iVar >= 0 && iVar < Gia_ManPiNum(p) );
+ assert( Gia_ManRegNum(p) == 0 );
+ Gia_ManFillValue( p );
+ // find the cofactoring variable
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManHashAlloc( pNew );
+ // compute negative cofactor
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManPi( p, iVar )->Value = Abc_Var2Lit( 0, 0 );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ // compute the positive cofactor
+ Gia_ManPi( p, iVar )->Value = Abc_Var2Lit( 0, 1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // create OR gate
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ if ( i == 0 )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, Gia_ObjFanin0Copy(pObj), pObj->Value) );
+ else
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Existentially quantifies the given variable.]
Description []
diff --git a/src/aig/gia/giaEsop.c b/src/aig/gia/giaEsop.c
index 13627c0c..a819bc20 100644
--- a/src/aig/gia/giaEsop.c
+++ b/src/aig/gia/giaEsop.c
@@ -167,7 +167,7 @@ Vec_Wec_t * Eso_ManCoverDerive( Eso_Man_t * p, Vec_Ptr_t * vCover )
}
}
}
- assert( Abc_MaxInt(Vec_WecSize(vRes), 8) == Vec_WecCap(vRes) );
+ //assert( Abc_MaxInt(Vec_WecSize(vRes), 8) == Vec_WecCap(vRes) );
return vRes;
}
Gia_Man_t * Eso_ManCoverConvert( Eso_Man_t * p, Vec_Ptr_t * vCover )
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index ab80a762..0f656b03 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -1498,7 +1498,7 @@ int Gia_ManFromIfLogicFindLut( If_Man_t * pIfMan, Gia_Man_t * pNew, If_Cut_t * p
SeeAlso []
***********************************************************************/
-void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t * pCutBest, int fCompl )
+void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t * pCutBest, int iLit, Vec_Str_t * vConfigsStr )
{
If_Obj_t * pIfObj;
word * pPerm = If_DsdManGetFuncConfig( pIfMan->pIfDsdMan, If_CutDsdLit(pIfMan, pCutBest) ); // cell input -> DSD input
@@ -1537,10 +1537,33 @@ void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t *
}
// remember complementation
assert( nTtBitNum + nPermBitNum < 32 * nIntNum );
- if ( Abc_LitIsCompl(If_CutDsdLit(pIfMan, pCutBest)) ^ pCutBest->fCompl ^ fCompl )
+ if ( Abc_LitIsCompl(If_CutDsdLit(pIfMan, pCutBest)) ^ pCutBest->fCompl ^ Abc_LitIsCompl(iLit) )
Abc_TtSetBit( pArray, nTtBitNum + nPermBitNum );
// update count
Vec_IntAddToEntry( vConfigs, 0, 1 );
+ // write configs
+ if ( vConfigsStr )
+ {
+ Vec_StrPrintF( vConfigsStr, "%d", Abc_Lit2Var(iLit) );
+ Vec_StrPush( vConfigsStr, ' ' );
+ for ( i = 0; i < nTtBitNum; i++ )
+ Vec_StrPush( vConfigsStr, (char)(Abc_TtGetBit(pArray, i) ? '1' : '0') );
+ Vec_StrPush( vConfigsStr, ' ' );
+ Vec_StrPush( vConfigsStr, ' ' );
+ for ( v = 0; v < nVarNum; v++ )
+ {
+ for ( i = 0; i < nPermBitOne; i++ )
+ {
+ Vec_StrPush( vConfigsStr, (char)(Abc_TtGetBit(pArray, nTtBitNum + v * nPermBitOne + i) ? '1' : '0') );
+ if ( i == 0 )
+ Vec_StrPush( vConfigsStr, ' ' );
+ }
+ Vec_StrPush( vConfigsStr, ' ' );
+ Vec_StrPush( vConfigsStr, ' ' );
+ }
+ Vec_StrPush( vConfigsStr, (char)(Abc_TtGetBit(pArray, nTtBitNum + nPermBitNum) ? '1' : '0') );
+ Vec_StrPush( vConfigsStr, '\n' );
+ }
}
int Gia_ManFromIfLogicFindCell( If_Man_t * pIfMan, Gia_Man_t * pNew, Gia_Man_t * pTemp, If_Cut_t * pCutBest, Ifn_Ntk_t * pNtkCell, int nLutMax, Vec_Int_t * vLeaves, Vec_Int_t * vLits, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vConfigs )
{
@@ -1730,11 +1753,13 @@ int Gia_ManFromIfLogicAndVars( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Cut_t * p
***********************************************************************/
Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
{
+ int fWriteConfigs = 1;
Gia_Man_t * pNew, * pHashed = NULL;
If_Cut_t * pCutBest;
If_Obj_t * pIfObj, * pIfLeaf;
Vec_Int_t * vMapping, * vMapping2, * vPacking = NULL, * vConfigs = NULL;
Vec_Int_t * vLeaves, * vLeaves2, * vCover, * vLits;
+ Vec_Str_t * vConfigsStr = NULL;
Ifn_Ntk_t * pNtkCell = NULL;
sat_solver * pSat = NULL;
int i, k, Entry;
@@ -1757,6 +1782,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
vConfigs = Vec_IntAlloc( 1000 );
Vec_IntPush( vConfigs, 0 );
Vec_IntPush( vConfigs, nConfigInts );
+ if ( fWriteConfigs )
+ vConfigsStr = Vec_StrAlloc( 1000 );
}
// create new manager
pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
@@ -1840,7 +1867,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u), pIfMan->pPars->fEnableCheck07 );
pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
if ( vConfigs && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 )
- Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, Abc_LitIsCompl(pIfObj->iCopy) );
+ Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, pIfObj->iCopy, vConfigsStr );
}
else
{
@@ -1921,6 +1948,27 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
Gia_ManForEachCi( pNew, pObj, i )
assert( !Gia_ObjIsLut(pNew, Gia_ObjId(pNew, pObj)) );
}
+ // dump configuration strings
+ if ( vConfigsStr )
+ {
+ FILE * pFile; int status;
+ char * pStr, Buffer[1000] = {0};
+ char * pNameGen = pIfMan->pName? Extra_FileNameGeneric( pIfMan->pName ) : "nameless_";
+ sprintf( Buffer, "%s_configs.txt", pNameGen );
+ ABC_FREE( pNameGen );
+ pFile = fopen( Buffer, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\".\n", Buffer );
+ return pNew;
+ }
+ Vec_StrPush( vConfigsStr, '\0' );
+ pStr = Vec_StrArray(vConfigsStr);
+ status = fwrite( pStr, strlen(pStr), 1, pFile );
+ Vec_StrFree( vConfigsStr );
+ fclose( pFile );
+ printf( "Finished dumping configs into file \"%s\".\n", Buffer );
+ }
return pNew;
}
diff --git a/src/aig/gia/giaSupp.c b/src/aig/gia/giaSupp.c
new file mode 100644
index 00000000..d9ba4e70
--- /dev/null
+++ b/src/aig/gia/giaSupp.c
@@ -0,0 +1,887 @@
+/**CFile****************************************************************
+
+ FileName [giaSupp.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Support minimization for AIGs.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "sat/satoko/satoko.h"
+#include "sat/satoko/solver.h"
+
+#ifdef ABC_USE_CUDD
+#include "bdd/extrab/extraBdd.h"
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef ABC_USE_CUDD
+
+struct Gia_ManMin_t_
+{
+ // problem formulation
+ Gia_Man_t * pGia;
+ int iLits[2];
+ // structural information
+ Vec_Int_t * vCis[2];
+ Vec_Int_t * vObjs[2];
+ Vec_Int_t * vCleared;
+ // intermediate functions
+ DdManager * dd;
+ Vec_Ptr_t * vFuncs;
+ Vec_Int_t * vSupp;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Create/delete the data representation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_ManMin_t * Gia_ManSuppStart( Gia_Man_t * pGia )
+{
+ Gia_ManMin_t * p;
+ p = ABC_CALLOC( Gia_ManMin_t, 1 );
+ p->pGia = pGia;
+ p->vCis[0] = Vec_IntAlloc( 512 );
+ p->vCis[1] = Vec_IntAlloc( 512 );
+ p->vObjs[0] = Vec_IntAlloc( 512 );
+ p->vObjs[1] = Vec_IntAlloc( 512 );
+ p->vCleared = Vec_IntAlloc( 512 );
+ p->dd = Cudd_Init( 0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+// Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT );
+ Cudd_AutodynDisable( p->dd );
+ p->vFuncs = Vec_PtrAlloc( 10000 );
+ p->vSupp = Vec_IntAlloc( 10000 );
+ return p;
+}
+void Gia_ManSuppStop( Gia_ManMin_t * p )
+{
+ Vec_IntFreeP( &p->vCis[0] );
+ Vec_IntFreeP( &p->vCis[1] );
+ Vec_IntFreeP( &p->vObjs[0] );
+ Vec_IntFreeP( &p->vObjs[1] );
+ Vec_IntFreeP( &p->vCleared );
+ Vec_PtrFreeP( &p->vFuncs );
+ Vec_IntFreeP( &p->vSupp );
+ printf( "Refs = %d. \n", Cudd_CheckZeroRef( p->dd ) );
+ Cudd_Quit( p->dd );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute variables, which are not in the support.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManFindRemoved( Gia_ManMin_t * p )
+{
+ extern void ddSupportStep2( DdNode * f, int * support );
+ extern void ddClearFlag2( DdNode * f );
+
+ //int fVerbose = 1;
+ int nBddLimit = 100000;
+ int nPart0 = Vec_IntSize(p->vCis[0]);
+ int n, i, iObj, nVars = 0;
+ DdNode * bFunc0, * bFunc1, * bFunc;
+ Vec_PtrFillExtra( p->vFuncs, Gia_ManObjNum(p->pGia), NULL );
+ // assign variables
+ for ( n = 0; n < 2; n++ )
+ Vec_IntForEachEntry( p->vCis[n], iObj, i )
+ Vec_PtrWriteEntry( p->vFuncs, iObj, Cudd_bddIthVar(p->dd, nVars++) );
+ // create nodes
+ for ( n = 0; n < 2; n++ )
+ Vec_IntForEachEntry( p->vObjs[n], iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj );
+ bFunc0 = Cudd_NotCond( (DdNode *)Vec_PtrEntry(p->vFuncs, Gia_ObjFaninId0(pObj, iObj)), Gia_ObjFaninC0(pObj) );
+ bFunc1 = Cudd_NotCond( (DdNode *)Vec_PtrEntry(p->vFuncs, Gia_ObjFaninId1(pObj, iObj)), Gia_ObjFaninC1(pObj) );
+ bFunc = Cudd_bddAndLimit( p->dd, bFunc0, bFunc1, nBddLimit );
+ assert( bFunc != NULL );
+ Cudd_Ref( bFunc );
+ Vec_PtrWriteEntry( p->vFuncs, iObj, bFunc );
+ }
+ // create new node
+ bFunc0 = Cudd_NotCond( (DdNode *)Vec_PtrEntry(p->vFuncs, Abc_Lit2Var(p->iLits[0])), Abc_LitIsCompl(p->iLits[0]) );
+ bFunc1 = Cudd_NotCond( (DdNode *)Vec_PtrEntry(p->vFuncs, Abc_Lit2Var(p->iLits[1])), Abc_LitIsCompl(p->iLits[1]) );
+ bFunc = Cudd_bddAndLimit( p->dd, bFunc0, bFunc1, nBddLimit );
+ assert( bFunc != NULL );
+ Cudd_Ref( bFunc );
+ //if ( fVerbose ) Extra_bddPrint( p->dd, bFunc ), printf( "\n" );
+ // collect support
+ Vec_IntFill( p->vSupp, nVars, 0 );
+ ddSupportStep2( Cudd_Regular(bFunc), Vec_IntArray(p->vSupp) );
+ ddClearFlag2( Cudd_Regular(bFunc) );
+ // find variables not present in the support
+ Vec_IntClear( p->vCleared );
+ for ( i = 0; i < nVars; i++ )
+ if ( Vec_IntEntry(p->vSupp, i) == 0 )
+ Vec_IntPush( p->vCleared, i < nPart0 ? Vec_IntEntry(p->vCis[0], i) : Vec_IntEntry(p->vCis[1], i-nPart0) );
+ //printf( "%d(%d)%d ", Cudd_SupportSize(p->dd, bFunc), Vec_IntSize(p->vCleared), Cudd_DagSize(bFunc) );
+ // deref results
+ Cudd_RecursiveDeref( p->dd, bFunc );
+ for ( n = 0; n < 2; n++ )
+ Vec_IntForEachEntry( p->vObjs[n], iObj, i )
+ Cudd_RecursiveDeref( p->dd, (DdNode *)Vec_PtrEntry(p->vFuncs, iObj) );
+ //Vec_IntPrint( p->vCleared );
+ return Vec_IntSize(p->vCleared);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute variables, which are not in the support.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManRebuildOne( Gia_ManMin_t * p, int n )
+{
+ int i, iObj, iGiaLitNew = -1;
+ Vec_Int_t * vTempIns = p->vCis[n];
+ Vec_Int_t * vTempNds = p->vObjs[n];
+ Vec_Int_t * vCopies = &p->pGia->vCopies;
+ Vec_IntFillExtra( vCopies, Gia_ManObjNum(p->pGia), -1 );
+ assert( p->iLits[n] >= 2 );
+ // process inputs
+ Vec_IntForEachEntry( vTempIns, iObj, i )
+ Vec_IntWriteEntry( vCopies, iObj, Abc_Var2Lit(iObj, 0) );
+ // process constants
+ assert( Vec_IntSize(p->vCleared) > 0 );
+ Vec_IntForEachEntry( p->vCleared, iObj, i )
+ Vec_IntWriteEntry( vCopies, iObj, 0 );
+ if ( Vec_IntSize(vTempNds) == 0 )
+ iGiaLitNew = Vec_IntEntry( vCopies, Abc_Lit2Var(p->iLits[n]) );
+ else
+ {
+ Vec_IntForEachEntry( vTempNds, iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj );
+ int iGiaLit0 = Vec_IntEntry( vCopies, Gia_ObjFaninId0p(p->pGia, pObj) );
+ int iGiaLit1 = Vec_IntEntry( vCopies, Gia_ObjFaninId1p(p->pGia, pObj) );
+ iGiaLit0 = Abc_LitNotCond( iGiaLit0, Gia_ObjFaninC0(pObj) );
+ iGiaLit1 = Abc_LitNotCond( iGiaLit1, Gia_ObjFaninC1(pObj) );
+ iGiaLitNew = Gia_ManHashAnd( p->pGia, iGiaLit0, iGiaLit1 );
+ Vec_IntWriteEntry( vCopies, iObj, iGiaLitNew );
+ }
+ assert( Abc_Lit2Var(p->iLits[n]) == iObj );
+ }
+ return Abc_LitNotCond( iGiaLitNew, Abc_LitIsCompl(p->iLits[n]) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManGatherSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vCis, Vec_Int_t * vObjs )
+{
+ int Val0, Val1;
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) )
+ return 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vCis, iObj );
+ return 0;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Val0 = Gia_ManGatherSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vCis, vObjs );
+ Val1 = Gia_ManGatherSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vCis, vObjs );
+ Vec_IntPush( vObjs, iObj );
+ return Val0 || Val1;
+}
+int Gia_ManGatherSupp( Gia_ManMin_t * p )
+{
+ int n, Overlap = 0;
+ Gia_ManIncrementTravId( p->pGia );
+ for ( n = 0; n < 2; n++ )
+ {
+ Vec_IntClear( p->vCis[n] );
+ Vec_IntClear( p->vObjs[n] );
+ Gia_ManIncrementTravId( p->pGia );
+ Overlap = Gia_ManGatherSupp_rec( p->pGia, Abc_Lit2Var(p->iLits[n]), p->vCis[n], p->vObjs[n] );
+ assert( n || !Overlap );
+ }
+ return Overlap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Takes a literal and returns a support-minized literal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSupportAnd( Gia_ManMin_t * p, int iLit0, int iLit1 )
+{
+ int iLitNew0, iLitNew1;
+ p->iLits[0] = iLit0;
+ p->iLits[1] = iLit1;
+ if ( iLit0 < 2 || iLit1 < 2 || !Gia_ManGatherSupp(p) || !Gia_ManFindRemoved(p) )
+ return Gia_ManHashAnd( p->pGia, iLit0, iLit1 );
+ iLitNew0 = Gia_ManRebuildOne( p, 0 );
+ iLitNew1 = Gia_ManRebuildOne( p, 1 );
+ return Gia_ManHashAnd( p->pGia, iLitNew0, iLitNew1 );
+}
+
+
+#else
+
+Gia_ManMin_t * Gia_ManSuppStart( Gia_Man_t * pGia ) { return NULL; }
+int Gia_ManSupportAnd( Gia_ManMin_t * p, int iLit0, int iLit1 ) { return 0; }
+void Gia_ManSuppStop( Gia_ManMin_t * p ) {}
+
+#endif
+
+
+/**Function*************************************************************
+
+ Synopsis [Testbench.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManSupportAndTest( Gia_Man_t * pGia )
+{
+ Gia_ManMin_t * pMan;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManFillValue( pGia );
+ pNew = Gia_ManStart( Gia_ManObjNum(pGia) );
+ pNew->pName = Abc_UtilStrsav( pGia->pName );
+ pNew->pSpec = Abc_UtilStrsav( pGia->pSpec );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManConst0(pGia)->Value = 0;
+ pMan = Gia_ManSuppStart( pNew );
+ Gia_ManForEachObj1( pGia, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+// pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pObj->Value = Gia_ManSupportAnd( pMan, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ else assert( 0 );
+
+ if ( i % 10000 == 0 )
+ printf( "%d\n", i );
+ }
+ Gia_ManSuppStop( pMan );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+
+
+struct Gia_Man2Min_t_
+{
+ // problem formulation
+ Gia_Man_t * pGia;
+ int iLits[2];
+ // structural information
+ Vec_Int_t * vCis[2];
+ Vec_Int_t * vObjs[2];
+ // SAT solving
+ satoko_t * pSat; // SAT solver
+ Vec_Wrd_t * vSims; // simulation
+ Vec_Ptr_t * vFrontier; // CNF construction
+ Vec_Ptr_t * vFanins; // CNF construction
+ Vec_Int_t * vSatVars; // nodes
+ int nCisOld; // previous number of CIs
+ int iPattern; // the next pattern to write
+ int nSatSat;
+ int nSatUnsat;
+ int nCalls;
+ int nSims;
+ int nSupps;
+};
+
+static inline int Gia_Min2ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); }
+static inline int Gia_Min2ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Gia_Min2ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num; }
+static inline void Gia_Min2ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Gia_Min2ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1); }
+
+
+/**Function*************************************************************
+
+ Synopsis [Create/delete the data representation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man2Min_t * Gia_Man2SuppStart( Gia_Man_t * pGia )
+{
+ Gia_Man2Min_t * p;
+ p = ABC_CALLOC( Gia_Man2Min_t, 1 );
+ p->pGia = pGia;
+ p->vCis[0] = Vec_IntAlloc( 512 );
+ p->vCis[1] = Vec_IntAlloc( 512 );
+ p->vObjs[0] = Vec_IntAlloc( 512 );
+ p->vObjs[1] = Vec_IntAlloc( 512 );
+ // SAT solving
+ p->pSat = satoko_create();
+ p->vSims = Vec_WrdAlloc( 1000 );
+ p->vFrontier = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vSatVars = Vec_IntAlloc( 100 );
+ p->iPattern = 1;
+ p->pSat->opts.learnt_ratio = 0; // prevent garbage collection
+ return p;
+}
+void Gia_Man2SuppStop( Gia_Man2Min_t * p )
+{
+ printf( "Total calls = %8d. Supps = %6d. Sims = %6d. SAT = %6d. UNSAT = %6d.\n",
+ p->nCalls, p->nSupps, p->nSims, p->nSatSat, p->nSatUnsat );
+ Vec_IntFreeP( &p->vCis[0] );
+ Vec_IntFreeP( &p->vCis[1] );
+ Vec_IntFreeP( &p->vObjs[0] );
+ Vec_IntFreeP( &p->vObjs[1] );
+ Gia_ManCleanMark01( p->pGia );
+ satoko_destroy( p->pSat );
+ Vec_WrdFreeP( &p->vSims );
+ Vec_PtrFreeP( &p->vFrontier );
+ Vec_PtrFreeP( &p->vFanins );
+ Vec_IntFreeP( &p->vSatVars );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_Min2AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( pNode->fMark0 );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Gia_Min2ObjSatId(p, pNode);
+ VarI = Gia_Min2ObjSatId(p, pNodeI);
+ VarT = Gia_Min2ObjSatId(p, Gia_Regular(pNodeT));
+ VarE = Gia_Min2ObjSatId(p, Gia_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Gia_IsComplement(pNodeT);
+ fCompE = Gia_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+
+ // two additional clauses
+ // t' & e' -> f'
+ // t & e -> f
+
+ // t + e + f'
+ // t' + e' + f
+
+ if ( VarT == VarE )
+ {
+// assert( fCompT == !fCompE );
+ return;
+ }
+
+ pLits[0] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+}
+void Gia_Min2AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsAnd( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ABC_ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = Abc_Var2Lit(Gia_Min2ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = Abc_Var2Lit(Gia_Min2ObjSatId(p, pNode), 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = Abc_Var2Lit(Gia_Min2ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = Abc_Var2Lit(Gia_Min2ObjSatId(p, pNode), 0);
+ if ( fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses and returns CNF variable of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_Min2CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||
+ (!fFirst && Gia_ObjValue(pObj) > 1) ||
+ (fUseMuxes && pObj->fMark0) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Gia_Min2CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Gia_Min2CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+void Gia_Min2CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Gia_Min2CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+void Gia_Min2ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat, Vec_Int_t * vSatVars )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Gia_Min2ObjSatId(p, pObj) >= 0 )
+ return;
+ assert( Gia_Min2ObjSatId(p, pObj) == -1 );
+ Vec_IntPush( vSatVars, Gia_ObjId(p, pObj) );
+ Gia_Min2ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+int Gia_Min2ObjGetCnfVar( Gia_Man2Min_t * p, int iObj )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
+ Gia_Obj_t * pNode, * pFanin;
+ int i, k, fUseMuxes = 1;
+ if ( Gia_Min2ObjSatId(p->pGia, pObj) >= 0 )
+ return Gia_Min2ObjSatId(p->pGia, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( p->vSatVars, iObj );
+ return Gia_Min2ObjSetSatId( p->pGia, pObj, satoko_add_variable(p->pSat, 0) );
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ // start the frontier
+ Vec_PtrClear( p->vFrontier );
+ Gia_Min2ObjAddToFrontier( p->pGia, pObj, p->vFrontier, p->pSat, p->vSatVars );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i )
+ {
+ assert( Gia_Min2ObjSatId(p->pGia,pNode) >= 0 );
+ if ( fUseMuxes && pNode->fMark0 )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Gia_Min2ObjAddToFrontier( p->pGia, Gia_Regular(pFanin), p->vFrontier, p->pSat, p->vSatVars );
+ Gia_Min2AddClausesMux( p->pGia, pNode, p->pSat );
+ }
+ else
+ {
+ Gia_Min2CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Gia_Min2ObjAddToFrontier( p->pGia, Gia_Regular(pFanin), p->vFrontier, p->pSat, p->vSatVars );
+ Gia_Min2AddClausesSuper( p->pGia, pNode, p->vFanins, p->pSat );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ return Gia_Min2ObjSatId(p->pGia,pObj);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 0 if the node is not a constant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_Min2ManSimulate( Gia_Man2Min_t * p )
+{
+ word Sim0, Sim1; int n, i, iObj;
+ p->nSims++;
+ // add random values to new CIs
+ Vec_WrdFillExtra( p->vSims, Gia_ManObjNum(p->pGia), 0 );
+ for ( i = p->nCisOld; i < Gia_ManCiNum(p->pGia); i++ )
+ Vec_WrdWriteEntry( p->vSims, Gia_ManCiIdToId(p->pGia, i), Gia_ManRandomW( 0 ) << 1 );
+ p->nCisOld = Gia_ManCiNum(p->pGia);
+ // simulate internal nodes
+ for ( n = 0; n < 2; n++ )
+ Vec_IntForEachEntry( p->vObjs[n], iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iObj );
+ Sim0 = Vec_WrdEntry( p->vSims, Gia_ObjFaninId0p(p->pGia, pObj) );
+ Sim1 = Vec_WrdEntry( p->vSims, Gia_ObjFaninId1p(p->pGia, pObj) );
+ Sim0 = Gia_ObjFaninC0(pObj) ? ~Sim0 : Sim0;
+ Sim1 = Gia_ObjFaninC1(pObj) ? ~Sim1 : Sim1;
+ Vec_WrdWriteEntry( p->vSims, iObj, Sim0 & Sim1 );
+ }
+ Sim0 = Vec_WrdEntry( p->vSims, Abc_Lit2Var(p->iLits[0]) );
+ Sim1 = Vec_WrdEntry( p->vSims, Abc_Lit2Var(p->iLits[1]) );
+ Sim0 = Abc_LitIsCompl(p->iLits[0]) ? ~Sim0 : Sim0;
+ Sim1 = Abc_LitIsCompl(p->iLits[1]) ? ~Sim1 : Sim1;
+// assert( (Sim0 & Sim1) != ~0 );
+ return (Sim0 & Sim1) == 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_Min2SimSetInputBit( Gia_Man2Min_t * p, int iObj, int Bit, int iPattern )
+{
+ word * pSim = Vec_WrdEntryP( p->vSims, iObj );
+ assert( iPattern > 0 && iPattern < 64 );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, iPattern ) != Bit )
+ Abc_InfoXorBit( (unsigned*)pSim, iPattern );
+}
+int Gia_Min2ManSolve( Gia_Man2Min_t * p )
+{
+ int iObj0 = Abc_Lit2Var(p->iLits[0]);
+ int iObj1 = Abc_Lit2Var(p->iLits[1]);
+ int n, i, status, iVar0, iVar1, iTemp;
+ assert( iObj0 > 0 && iObj1 > 0 );
+// Vec_IntForEachEntry( &p->pGia->vCopies, iTemp, i )
+// assert( iTemp == -1 );
+ Vec_IntFillExtra( &p->pGia->vCopies, Gia_ManObjNum(p->pGia), -1 );
+ Vec_IntClear( p->vSatVars );
+ assert( solver_varnum(p->pSat) == 0 );
+ iVar0 = Gia_Min2ObjGetCnfVar( p, iObj0 );
+ iVar1 = Gia_Min2ObjGetCnfVar( p, iObj1 );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, Abc_LitIsCompl(p->iLits[0])) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, Abc_LitIsCompl(p->iLits[1])) );
+ status = satoko_solve( p->pSat );
+ satoko_assump_pop( p->pSat );
+ satoko_assump_pop( p->pSat );
+ if ( status == SATOKO_SAT )
+ {
+ //printf( "Disproved %d %d\n", p->iLits[0], p->iLits[1] );
+ assert( Gia_Min2ManSimulate(p) == 1 );
+ for ( n = 0; n < 2; n++ )
+ Vec_IntForEachEntry( p->vCis[n], iTemp, i )
+ Gia_Min2SimSetInputBit( p, iTemp, var_polarity(p->pSat, Gia_Min2ObjSatId(p->pGia, Gia_ManObj(p->pGia, iTemp))) == LIT_TRUE, p->iPattern );
+ assert( Gia_Min2ManSimulate(p) == 0 );
+ p->iPattern = p->iPattern == 63 ? 1 : p->iPattern + 1;
+ p->nSatSat++;
+ }
+ //printf( "supp %d node %d vars %d\n",
+ // Vec_IntSize(p->vCis[0]) + Vec_IntSize(p->vCis[1]),
+ // Vec_IntSize(p->vObjs[0]) + Vec_IntSize(p->vObjs[1]),
+ // Vec_IntSize(p->vSatVars) );
+ satoko_rollback( p->pSat );
+ Vec_IntForEachEntry( p->vSatVars, iTemp, i )
+ Gia_Min2ObjCleanSatId( p->pGia, Gia_ManObj(p->pGia, iTemp) );
+ return status == SATOKO_UNSAT;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_Min2ManGatherSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vCis, Vec_Int_t * vObjs )
+{
+ int Val0, Val1;
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) )
+ return 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vCis, iObj );
+ return 0;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Val0 = Gia_Min2ManGatherSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vCis, vObjs );
+ Val1 = Gia_Min2ManGatherSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vCis, vObjs );
+ Vec_IntPush( vObjs, iObj );
+ return Val0 || Val1;
+}
+int Gia_Min2ManGatherSupp( Gia_Man2Min_t * p )
+{
+ int n, Overlap = 0;
+ p->nSupps++;
+ Gia_ManIncrementTravId( p->pGia );
+ for ( n = 0; n < 2; n++ )
+ {
+ Vec_IntClear( p->vCis[n] );
+ Vec_IntClear( p->vObjs[n] );
+ Gia_ManIncrementTravId( p->pGia );
+ Overlap = Gia_Min2ManGatherSupp_rec( p->pGia, Abc_Lit2Var(p->iLits[n]), p->vCis[n], p->vObjs[n] );
+ assert( n || !Overlap );
+ }
+ return Overlap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Takes a literal and returns a support-minized literal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_Man2SupportAnd( Gia_Man2Min_t * p, int iLit0, int iLit1 )
+{
+ p->nCalls++;
+ //return Gia_ManHashAnd( p->pGia, iLit0, iLit1 );
+ p->iLits[0] = iLit0;
+ p->iLits[1] = iLit1;
+ if ( iLit0 < 2 || iLit1 < 2 || Abc_Lit2Var(iLit0) == Abc_Lit2Var(iLit1) || Gia_ManHashLookupInt(p->pGia, iLit0, iLit1) ||
+ !Gia_Min2ManGatherSupp(p) || !Gia_Min2ManSimulate(p) || !Gia_Min2ManSolve(p) )
+ return Gia_ManHashAnd( p->pGia, iLit0, iLit1 );
+ //printf( "%d %d\n", iLit0, iLit1 );
+ p->nSatUnsat++;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testbench.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_Man2SupportAndTest( Gia_Man_t * pGia )
+{
+ Gia_Man2Min_t * pMan;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManRandomW( 1 );
+ Gia_ManFillValue( pGia );
+ pNew = Gia_ManStart( Gia_ManObjNum(pGia) );
+ pNew->pName = Abc_UtilStrsav( pGia->pName );
+ pNew->pSpec = Abc_UtilStrsav( pGia->pSpec );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManConst0(pGia)->Value = 0;
+ pMan = Gia_Man2SuppStart( pNew );
+ Gia_ManForEachObj1( pGia, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+// pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pObj->Value = Gia_Man2SupportAnd( pMan, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ else assert( 0 );
+
+ //if ( i % 10000 == 0 )
+ // printf( "%d\n", i );
+ }
+ Gia_Man2SuppStop( pMan );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 1f4c4c07..7ffd6bc5 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -76,6 +76,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaStg.c \
src/aig/gia/giaStr.c \
src/aig/gia/giaSupMin.c \
+ src/aig/gia/giaSupp.c \
src/aig/gia/giaSweep.c \
src/aig/gia/giaSweeper.c \
src/aig/gia/giaSwitch.c \