summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2017-11-26 14:41:05 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2017-11-26 14:41:05 -0800
commitc681506b48495aedc38b5d31d12368bd7de096ad (patch)
treefb71e299e0bb42ed610a710c6a8c3cc4c8757d9d
parent7bcfe6436938d8354f499522b3d013229931b009 (diff)
downloadabc-c681506b48495aedc38b5d31d12368bd7de096ad.tar.gz
abc-c681506b48495aedc38b5d31d12368bd7de096ad.tar.bz2
abc-c681506b48495aedc38b5d31d12368bd7de096ad.zip
Improvements to AIG-based quantification.
-rw-r--r--abclib.dsp4
-rw-r--r--src/aig/gia/gia.h9
-rw-r--r--src/aig/gia/giaDup.c258
-rw-r--r--src/aig/gia/giaExist.c526
-rw-r--r--src/aig/gia/giaMan.c1
-rw-r--r--src/aig/gia/module.make1
6 files changed, 552 insertions, 247 deletions
diff --git a/abclib.dsp b/abclib.dsp
index f93aff82..74cd3f44 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -4727,6 +4727,10 @@ SOURCE=.\src\aig\gia\giaEsop.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaExist.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaFalse.c
# End Source File
# Begin Source File
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index 23363687..30731dd6 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -222,6 +222,7 @@ struct Gia_Man_t_
int nSuppWords; // the number of support words
Vec_Wrd_t * vSuppWords; // support information
Vec_Int_t vCopiesTwo; // intermediate copies
+ Vec_Int_t vSuppVars; // used variables
};
@@ -1263,11 +1264,11 @@ extern Gia_Man_t * Gia_ManDupMux( int iVar, Gia_Man_t * pCof1, Gia_Man_t
extern Gia_Man_t * Gia_ManDupBlock( Gia_Man_t * p, int nBlock );
extern Gia_Man_t * Gia_ManDupExist( Gia_Man_t * p, int iVar );
extern Gia_Man_t * Gia_ManDupUniv( Gia_Man_t * p, int iVar );
-extern int Gia_ManQuantExist( Gia_Man_t * p, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData );
extern Gia_Man_t * Gia_ManDupDfsSkip( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj );
extern Gia_Man_t * Gia_ManDupConeSupp( Gia_Man_t * p, int iLit, Vec_Int_t * vCiIds );
extern int Gia_ManDupConeBack( Gia_Man_t * p, Gia_Man_t * pNew, Vec_Int_t * vCiIds );
+extern int Gia_ManDupConeBackObjs( Gia_Man_t * p, Gia_Man_t * pNew, Vec_Int_t * vObjs );
extern Gia_Man_t * Gia_ManDupDfsNode( Gia_Man_t * p, Gia_Obj_t * pObj );
extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos, int fDualOut, int OutValue );
@@ -1343,6 +1344,12 @@ extern int Gia_ManCountChoices( Gia_Man_t * p );
extern int Gia_ManFilterEquivsForSpeculation( Gia_Man_t * pGia, char * pName1, char * pName2, int fLatchA, int fLatchB );
extern int Gia_ManFilterEquivsUsingParts( Gia_Man_t * pGia, char * pName1, char * pName2 );
extern void Gia_ManFilterEquivsUsingLatches( Gia_Man_t * pGia, int fFlopsOnly, int fFlopsWith, int fUseRiDrivers );
+/*=== giaExist.c =========================================================*/
+extern void Gia_ManQuantSetSuppStart( Gia_Man_t * p );
+extern void Gia_ManQuantSetSuppZero( Gia_Man_t * p );
+extern void Gia_ManQuantSetSuppCi( Gia_Man_t * p, Gia_Obj_t * pObj );
+extern void Gia_ManQuantUpdateCiSupp( Gia_Man_t * p, int iObj );
+extern int Gia_ManQuantExist( Gia_Man_t * p, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData );
/*=== giaFanout.c =========================================================*/
extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index 552918d5..01c01f39 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -21,7 +21,6 @@
#include "gia.h"
#include "misc/tim/tim.h"
#include "misc/vec/vecWec.h"
-#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -1817,251 +1816,6 @@ Gia_Man_t * Gia_ManDupExist2( Gia_Man_t * p, int iVar )
return pNew;
}
-/**Function*************************************************************
-
- Synopsis [Existentially quantified several variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-
-static inline word * Gia_ManQuantInfoId( Gia_Man_t * p, int iObj ) { return Vec_WrdEntryP( p->vSuppWords, p->nSuppWords * iObj ); }
-static inline word * Gia_ManQuantInfo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ManQuantInfoId( p, Gia_ObjId(p, pObj) ); }
-
-static inline void Gia_ObjCopyGetTwoArray( Gia_Man_t * p, int iObj, int LitsOut[2] )
-{
- int * pLits = Vec_IntEntryP( &p->vCopiesTwo, 2*iObj );
- LitsOut[0] = pLits[0];
- LitsOut[1] = pLits[1];
-}
-static inline void Gia_ObjCopySetTwoArray( Gia_Man_t * p, int iObj, int LitsIn[2] )
-{
- int * pLits = Vec_IntEntryP( &p->vCopiesTwo, 2*iObj );
- pLits[0] = LitsIn[0];
- pLits[1] = LitsIn[1];
-}
-
-void Gia_ManQuantSetSuppStart( Gia_Man_t * p )
-{
- assert( Gia_ManObjNum(p) == 1 );
- assert( p->vSuppWords == NULL );
- p->iSuppPi = 0;
- p->nSuppWords = 1;
- p->vSuppWords = Vec_WrdAlloc( 1000 );
- Vec_WrdPush( p->vSuppWords, 0 );
-}
-void Gia_ManQuantSetSuppZero( Gia_Man_t * p )
-{
- int w;
- for ( w = 0; w < p->nSuppWords; w++ )
- Vec_WrdPush( p->vSuppWords, 0 );
- assert( Vec_WrdSize(p->vSuppWords) == p->nSuppWords * Gia_ManObjNum(p) );
-}
-void Gia_ManQuantSetSuppCi( Gia_Man_t * p, Gia_Obj_t * pObj )
-{
- assert( Gia_ObjIsCi(pObj) );
- assert( p->vSuppWords != NULL );
- if ( p->iSuppPi == 64 * p->nSuppWords )
- {
- Vec_Wrd_t * vTemp = Vec_WrdAlloc( 1000 ); word Data; int w;
- Vec_WrdForEachEntry( p->vSuppWords, Data, w )
- {
- Vec_WrdPush( vTemp, Data );
- if ( w % p->nSuppWords == 0 )
- Vec_WrdPush( vTemp, 0 );
- }
- Vec_WrdFree( p->vSuppWords );
- p->vSuppWords = vTemp;
- p->nSuppWords++;
- }
- Gia_ManQuantSetSuppZero( p );
- Abc_TtSetBit( Gia_ManQuantInfo(p, pObj), p->iSuppPi++ );
-}
-void Gia_ManQuantSetSuppAnd( Gia_Man_t * p, Gia_Obj_t * pObj )
-{
- int iObj = Gia_ObjId(p, pObj);
- int iFan0 = Gia_ObjFaninId0(pObj, iObj);
- int iFan1 = Gia_ObjFaninId1(pObj, iObj);
- assert( Gia_ObjIsAnd(pObj) );
- Gia_ManQuantSetSuppZero( p );
- Abc_TtOr( Gia_ManQuantInfo(p, pObj), Gia_ManQuantInfoId(p, iFan0), Gia_ManQuantInfoId(p, iFan1), p->nSuppWords );
-}
-int Gia_ManQuantCheckSupp( Gia_Man_t * p, int iObj, int iSupp )
-{
- return Abc_TtGetBit( Gia_ManQuantInfoId(p, iObj), iSupp );
-}
-
-
-void Gia_ManQuantDupConeSupp_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCis, Vec_Int_t * vObjs, int(*pFuncCiToKeep)(void *, int), void * pData )
-{
- int iLit0, iLit1, iObj = Gia_ObjId( p, pObj );
- int iLit = Gia_ObjCopyArray( p, iObj );
- if ( iLit >= 0 )
- return;
- if ( Gia_ObjIsCi(pObj) )
- {
- int iLit = Gia_ManAppendCi( pNew );
- Gia_Obj_t * pObjNew = Gia_ManObj( pNew, Abc_Lit2Var(iLit) );
- if ( pFuncCiToKeep( pData, Gia_ObjCioId(pObj) ) )
- Gia_ManQuantSetSuppZero( pNew );
- else
- Gia_ManQuantSetSuppCi( pNew, pObjNew );
- Gia_ObjSetCopyArray( p, iObj, iLit );
- Vec_IntPush( vCis, iObj );
- return;
- }
- assert( Gia_ObjIsAnd(pObj) );
- Gia_ManQuantDupConeSupp_rec( pNew, p, Gia_ObjFanin0(pObj), vCis, vObjs, pFuncCiToKeep, pData );
- Gia_ManQuantDupConeSupp_rec( pNew, p, Gia_ObjFanin1(pObj), vCis, vObjs, pFuncCiToKeep, pData );
- iLit0 = Gia_ObjCopyArray( p, Gia_ObjFaninId0(pObj, iObj) );
- iLit1 = Gia_ObjCopyArray( p, Gia_ObjFaninId1(pObj, iObj) );
- iLit0 = Abc_LitNotCond( iLit0, Gia_ObjFaninC0(pObj) );
- iLit1 = Abc_LitNotCond( iLit1, Gia_ObjFaninC1(pObj) );
- iLit = Gia_ManHashAnd( pNew, iLit0, iLit1 );
- Gia_ObjSetCopyArray( p, iObj, iLit );
- Vec_IntPush( vObjs, iObj );
-}
-Gia_Man_t * Gia_ManQuantDupConeSupp( Gia_Man_t * p, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t ** pvCis, int * pOutLit )
-{
- Gia_Man_t * pNew; int i, iLit0, iObj;
- Gia_Obj_t * pObj, * pRoot = Gia_ManObj( p, Abc_Lit2Var(iLit) );
- Vec_Int_t * vCis = Vec_IntAlloc( 1000 );
- Vec_Int_t * vObjs = Vec_IntAlloc( 1000 );
- assert( Gia_ObjIsAnd(pRoot) );
- if ( Vec_IntSize(&p->vCopies) < Gia_ManObjNum(p) )
- Vec_IntFillExtra( &p->vCopies, Gia_ManObjNum(p), -1 );
- pNew = Gia_ManStart( 1000 );
- Gia_ManHashStart( pNew );
- Gia_ManQuantSetSuppStart( pNew );
- Gia_ManQuantDupConeSupp_rec( pNew, p, pRoot, vCis, vObjs, pFuncCiToKeep, pData );
- iLit0 = Gia_ObjCopyArray( p, Abc_Lit2Var(iLit) );
- iLit0 = Abc_LitNotCond( iLit0, Abc_LitIsCompl(iLit) );
- if ( pOutLit ) *pOutLit = iLit0;
- Gia_ManForEachObjVec( vCis, p, pObj, i )
- Gia_ObjSetCopyArray( p, Gia_ObjId(p, pObj), -1 );
- Gia_ManForEachObjVec( vObjs, p, pObj, i )
- Gia_ObjSetCopyArray( p, Gia_ObjId(p, pObj), -1 );
- //assert( Vec_IntCountLarger(&p->vCopies, -1) == 0 );
- Vec_IntFree( vObjs );
- // remap into CI Ids
- Vec_IntForEachEntry( vCis, iObj, i )
- Vec_IntWriteEntry( vCis, i, Gia_ManIdToCioId(p, iObj) );
- if ( pvCis ) *pvCis = vCis;
- return pNew;
-}
-void Gia_ManQuantExist_rec( Gia_Man_t * p, int iObj, int pRes[2] )
-{
- Gia_Obj_t * pObj;
- int Lits0[2], Lits1[2], pFans[2], fCompl[2];
- if ( Gia_ObjIsTravIdCurrentId( p, iObj ) )
- {
- Gia_ObjCopyGetTwoArray( p, iObj, pRes );
- return;
- }
- Gia_ObjSetTravIdCurrentId( p, iObj );
- pObj = Gia_ManObj( p, iObj );
- if ( Gia_ObjIsCi(pObj) )
- {
- pRes[0] = 0; pRes[1] = 1;
- Gia_ObjCopySetTwoArray( p, iObj, pRes );
- return;
- }
- pFans[0] = Gia_ObjFaninId0( pObj, iObj );
- pFans[1] = Gia_ObjFaninId1( pObj, iObj );
- fCompl[0] = Gia_ObjFaninC0( pObj );
- fCompl[1] = Gia_ObjFaninC1( pObj );
- if ( Gia_ManQuantCheckSupp(p, pFans[0], p->iSuppPi) )
- Gia_ManQuantExist_rec( p, pFans[0], Lits0 );
- else
- Lits0[0] = Lits0[1] = Abc_Var2Lit( pFans[0], 0 );
- if ( Gia_ManQuantCheckSupp(p, pFans[1], p->iSuppPi) )
- Gia_ManQuantExist_rec( p, pFans[1], Lits1 );
- else
- Lits1[0] = Lits1[1] = Abc_Var2Lit( pFans[1], 0 );
- pRes[0] = Gia_ManHashAnd( p, Abc_LitNotCond(Lits0[0], fCompl[0]), Abc_LitNotCond(Lits1[0], fCompl[1]) );
- pRes[1] = Gia_ManHashAnd( p, Abc_LitNotCond(Lits0[1], fCompl[0]), Abc_LitNotCond(Lits1[1], fCompl[1]) );
- Gia_ObjCopySetTwoArray( p, iObj, pRes );
-}
-int Gia_ManQuantExist( Gia_Man_t * p0, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData )
-{
-// abctime clk = Abc_Clock();
- Gia_Man_t * pNew;
- Vec_Int_t * vOuts, * vOuts2, * vCis;
- Gia_Obj_t * pObj = Gia_ManObj( p0, Abc_Lit2Var(iLit) );
- int i, n, Entry, Lit, OutLit = -1, pLits[2], nVarsQua, nAndsOld, nAndsNew;
- if ( iLit < 2 ) return iLit;
- if ( Gia_ObjIsCi(pObj) ) return pFuncCiToKeep(pData, Gia_ObjCioId(pObj)) ? iLit : 1;
- assert( Gia_ObjIsAnd(pObj) );
- pNew = Gia_ManQuantDupConeSupp( p0, iLit, pFuncCiToKeep, pData, &vCis, &OutLit );
- if ( pNew->iSuppPi == 0 )
- {
- Gia_ManStop( pNew );
- Vec_IntFree( vCis );
- return iLit;
- }
- assert( pNew->iSuppPi > 0 && pNew->iSuppPi <= 64 * pNew->nSuppWords );
- vOuts = Vec_IntAlloc( 100 );
- vOuts2 = Vec_IntAlloc( 100 );
- assert( OutLit > 1 );
- Vec_IntPush( vOuts, OutLit );
- nVarsQua = pNew->iSuppPi;
- nAndsOld = Gia_ManAndNum(pNew);
- while ( --pNew->iSuppPi >= 0 )
- {
- //printf( "Quantifying input %d:\n", p->iSuppPi );
- if ( Vec_IntSize(&pNew->vCopiesTwo) < 2*Gia_ManObjNum(pNew) )
- Vec_IntFillExtra( &pNew->vCopiesTwo, 2*Gia_ManObjNum(pNew), -1 );
- assert( Vec_IntSize(vOuts) > 0 );
- Vec_IntClear( vOuts2 );
- Gia_ManIncrementTravId( pNew );
- Vec_IntForEachEntry( vOuts, Entry, i )
- {
- Gia_ManQuantExist_rec( pNew, Abc_Lit2Var(Entry), pLits );
- for ( n = 0; n < 2; n++ )
- {
- Lit = Abc_LitNotCond( pLits[n], Abc_LitIsCompl(Entry) );
- if ( Lit == 0 )
- continue;
- if ( Lit == 1 )
- {
- Vec_IntFree( vOuts );
- Vec_IntFree( vOuts2 );
- Gia_ManStop( pNew );
- Vec_IntFree( vCis );
- return 1;
- }
- Vec_IntPushUnique( vOuts2, Lit );
- }
- }
- Vec_IntClear( vOuts );
- ABC_SWAP( Vec_Int_t *, vOuts, vOuts2 );
- }
- //printf( "The number of diff cofactors = %d.\n", Vec_IntSize(vOuts) );
- assert( Vec_IntSize(vOuts) > 0 );
- Vec_IntForEachEntry( vOuts, Entry, i )
- Vec_IntWriteEntry( vOuts, i, Abc_LitNot(Entry) );
- OutLit = Gia_ManHashAndMulti( pNew, vOuts );
- OutLit = Abc_LitNot( OutLit );
- Vec_IntFree( vOuts );
- Vec_IntFree( vOuts2 );
- // transfer back
- Gia_ManAppendCo( pNew, OutLit );
- nAndsNew = Gia_ManAndNum(p0);
- Lit = Gia_ManDupConeBack( p0, pNew, vCis );
- nAndsNew = Gia_ManAndNum(p0) - nAndsNew;
- Gia_ManStop( pNew );
- // report the result
-// printf( "Performed quantification with %6d nodes, %3d keep-vars, %3d quant-vars, resulting in %5d new nodes. ",
-// nAndsOld, Vec_IntSize(vCis) - nVarsQua, nVarsQua, nAndsNew );
-// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
- Vec_IntFree( vCis );
- return Lit;
-}
-
/**Function*************************************************************
@@ -2198,6 +1952,18 @@ int Gia_ManDupConeBack( Gia_Man_t * p, Gia_Man_t * pNew, Vec_Int_t * vCiIds )
Gia_ManDupConeBack_rec( p, pNew, Gia_ObjFanin0(pRoot) );
return Gia_ObjFanin0Copy(pRoot);
}
+int Gia_ManDupConeBackObjs( Gia_Man_t * p, Gia_Man_t * pNew, Vec_Int_t * vObjs )
+{
+ Gia_Obj_t * pObj, * pRoot; int i;
+ assert( Gia_ManCiNum(pNew) == Vec_IntSize(vObjs) );
+ Gia_ManFillValue(pNew);
+ Gia_ManConst0(pNew)->Value = 0;
+ Gia_ManForEachCi( pNew, pObj, i )
+ pObj->Value = Abc_Var2Lit( Vec_IntEntry(vObjs, i), 0 );
+ pRoot = Gia_ManCo(pNew, 0);
+ Gia_ManDupConeBack_rec( p, pNew, Gia_ObjFanin0(pRoot) );
+ return Gia_ObjFanin0Copy(pRoot);
+}
/**Function*************************************************************
diff --git a/src/aig/gia/giaExist.c b/src/aig/gia/giaExist.c
new file mode 100644
index 00000000..9cffe12f
--- /dev/null
+++ b/src/aig/gia/giaExist.c
@@ -0,0 +1,526 @@
+/**CFile****************************************************************
+
+ FileName [giaExist.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Existential quantification.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaExist.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Existentially quantified several variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+static inline word * Gia_ManQuantInfoId( Gia_Man_t * p, int iObj ) { return Vec_WrdEntryP( p->vSuppWords, p->nSuppWords * iObj ); }
+static inline word * Gia_ManQuantInfo( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ManQuantInfoId( p, Gia_ObjId(p, pObj) ); }
+
+static inline void Gia_ObjCopyGetTwoArray( Gia_Man_t * p, int iObj, int LitsOut[2] )
+{
+ int * pLits = Vec_IntEntryP( &p->vCopiesTwo, 2*iObj );
+ LitsOut[0] = pLits[0];
+ LitsOut[1] = pLits[1];
+}
+static inline void Gia_ObjCopySetTwoArray( Gia_Man_t * p, int iObj, int LitsIn[2] )
+{
+ int * pLits = Vec_IntEntryP( &p->vCopiesTwo, 2*iObj );
+ pLits[0] = LitsIn[0];
+ pLits[1] = LitsIn[1];
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Existentially quantified several variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManQuantVerify_rec( Gia_Man_t * p, int iObj, int CiId )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId( p, iObj ) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return Gia_ObjCioId(pObj) == CiId;
+ return Gia_ManQuantVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), CiId ) ||
+ Gia_ManQuantVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), CiId );
+}
+void Gia_ManQuantVerify( Gia_Man_t * p, int iObj )
+{
+ word * pInfo = Gia_ManQuantInfoId( p, iObj ); int i, CiId;
+ assert( Gia_ObjIsAnd(Gia_ManObj(p, iObj)) );
+ Vec_IntForEachEntry( &p->vSuppVars, CiId, i )
+ {
+ Gia_ManIncrementTravId( p );
+ if ( Abc_TtGetBit(pInfo, i) != Gia_ManQuantVerify_rec(p, iObj, CiId) )
+ printf( "Mismatch at node %d related to CI %d (%d).\n", iObj, CiId, Abc_TtGetBit(pInfo, i) );
+ }
+}
+
+
+
+void Gia_ManQuantSetSuppStart( Gia_Man_t * p )
+{
+ assert( Gia_ManObjNum(p) == 1 );
+ assert( p->vSuppWords == NULL );
+ assert( Vec_IntSize(&p->vSuppVars) == 0 );
+ p->iSuppPi = 0;
+ p->nSuppWords = 1;
+ p->vSuppWords = Vec_WrdAlloc( 1000 );
+ Vec_WrdPush( p->vSuppWords, 0 );
+}
+void Gia_ManQuantSetSuppZero( Gia_Man_t * p )
+{
+ int w;
+ for ( w = 0; w < p->nSuppWords; w++ )
+ Vec_WrdPush( p->vSuppWords, 0 );
+ assert( Vec_WrdSize(p->vSuppWords) == p->nSuppWords * Gia_ManObjNum(p) );
+}
+void Gia_ManQuantSetSuppCi( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ assert( Gia_ObjIsCi(pObj) );
+ assert( p->vSuppWords != NULL );
+ if ( p->iSuppPi == 64 * p->nSuppWords )
+ {
+ word Data; int w, Count = 0, Size = Vec_WrdSize(p->vSuppWords);
+ Vec_Wrd_t * vTemp = Vec_WrdAlloc( Size ? 2 * Size : 1000 );
+ Vec_WrdForEachEntry( p->vSuppWords, Data, w )
+ {
+ Vec_WrdPush( vTemp, Data );
+ if ( ++Count == p->nSuppWords )
+ {
+ Vec_WrdPush( vTemp, 0 );
+ Count = 0;
+ }
+ }
+ Vec_WrdFree( p->vSuppWords );
+ p->vSuppWords = vTemp;
+ p->nSuppWords++;
+ assert( Vec_WrdSize(p->vSuppWords) == p->nSuppWords * Gia_ManObjNum(p) );
+ //printf( "Resizing to %d words.\n", p->nSuppWords );
+ }
+ assert( p->iSuppPi == Vec_IntSize(&p->vSuppVars) );
+ Vec_IntPush( &p->vSuppVars, Gia_ObjCioId(pObj) );
+ Abc_TtSetBit( Gia_ManQuantInfo(p, pObj), p->iSuppPi++ );
+}
+void Gia_ManQuantSetSuppAnd( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int iObj = Gia_ObjId(p, pObj);
+ int iFan0 = Gia_ObjFaninId0(pObj, iObj);
+ int iFan1 = Gia_ObjFaninId1(pObj, iObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManQuantSetSuppZero( p );
+ Abc_TtOr( Gia_ManQuantInfo(p, pObj), Gia_ManQuantInfoId(p, iFan0), Gia_ManQuantInfoId(p, iFan1), p->nSuppWords );
+}
+int Gia_ManQuantCheckSupp( Gia_Man_t * p, int iObj, int iSupp )
+{
+ return Abc_TtGetBit( Gia_ManQuantInfoId(p, iObj), iSupp );
+}
+void Gia_ManQuantUpdateCiSupp( Gia_Man_t * p, int iObj )
+{
+ if ( Abc_TtIsConst0( Gia_ManQuantInfoId(p, iObj), p->nSuppWords ) )
+ Gia_ManQuantSetSuppCi( p, Gia_ManObj(p, iObj) );
+ assert( !Abc_TtIsConst0( Gia_ManQuantInfoId(p, iObj), p->nSuppWords ) );
+}
+int Gia_ManQuantCheckOverlap( Gia_Man_t * p, int iObj )
+{
+ return Abc_TtIntersect( Gia_ManQuantInfoId(p, iObj), Gia_ManQuantInfoId(p, 0), p->nSuppWords, 0 );
+}
+void Gia_ManQuantMarkUsedCis( Gia_Man_t * p, int(*pFuncCiToKeep)(void *, int), void * pData )
+{
+ int i, CiId;
+ word * pInfo = Gia_ManQuantInfoId( p, 0 );
+ Abc_TtClear( pInfo, p->nSuppWords );
+ assert( Abc_TtIsConst0(pInfo, p->nSuppWords) );
+ Vec_IntForEachEntry( &p->vSuppVars, CiId, i )
+ if ( !pFuncCiToKeep( pData, CiId ) ) // quant var
+ Abc_TtSetBit( pInfo, i );
+}
+
+int Gia_ManQuantCountUsed_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj; int Count = 1;
+ if ( Gia_ObjIsTravIdCurrentId( p, iObj ) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ if ( Gia_ManQuantCheckSupp(p, Gia_ObjFaninId0(pObj, iObj), p->iSuppPi) )
+ Count += Gia_ManQuantCountUsed_rec( p, Gia_ObjFaninId0(pObj, iObj) );
+ if ( Gia_ManQuantCheckSupp(p, Gia_ObjFaninId1(pObj, iObj), p->iSuppPi) )
+ Count += Gia_ManQuantCountUsed_rec( p, Gia_ObjFaninId1(pObj, iObj) );
+ return Count;
+}
+int Gia_ManQuantCountUsed( Gia_Man_t * p, int iObj )
+{
+ Gia_ManIncrementTravId( p );
+ return Gia_ManQuantCountUsed_rec( p, iObj );
+}
+
+void Gia_ManQuantDupConeSupp_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCis, Vec_Int_t * vObjs, int(*pFuncCiToKeep)(void *, int), void * pData )
+{
+ int iLit0, iLit1, iObj = Gia_ObjId( p, pObj );
+ int iLit = Gia_ObjCopyArray( p, iObj );
+ if ( iLit >= 0 )
+ return;
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ int iLit = Gia_ManAppendCi( pNew );
+ Gia_Obj_t * pObjNew = Gia_ManObj( pNew, Abc_Lit2Var(iLit) );
+ Gia_ManQuantSetSuppZero( pNew );
+ if ( !pFuncCiToKeep( pData, Gia_ObjCioId(pObj) ) )
+ {
+ //printf( "Collecting CI %d\n", Gia_ObjCioId(pObj)+1 );
+ Gia_ManQuantSetSuppCi( pNew, pObjNew );
+ }
+ Gia_ObjSetCopyArray( p, iObj, iLit );
+ Vec_IntPush( vCis, iObj );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManQuantDupConeSupp_rec( pNew, p, Gia_ObjFanin0(pObj), vCis, vObjs, pFuncCiToKeep, pData );
+ Gia_ManQuantDupConeSupp_rec( pNew, p, Gia_ObjFanin1(pObj), vCis, vObjs, pFuncCiToKeep, pData );
+ iLit0 = Gia_ObjCopyArray( p, Gia_ObjFaninId0(pObj, iObj) );
+ iLit1 = Gia_ObjCopyArray( p, Gia_ObjFaninId1(pObj, iObj) );
+ iLit0 = Abc_LitNotCond( iLit0, Gia_ObjFaninC0(pObj) );
+ iLit1 = Abc_LitNotCond( iLit1, Gia_ObjFaninC1(pObj) );
+ iLit = Gia_ManHashAnd( pNew, iLit0, iLit1 );
+ Gia_ObjSetCopyArray( p, iObj, iLit );
+ Vec_IntPush( vObjs, iObj );
+}
+Gia_Man_t * Gia_ManQuantDupConeSupp( Gia_Man_t * p, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t ** pvCis, int * pOutLit )
+{
+ Gia_Man_t * pNew; int i, iLit0, iObj;
+ Gia_Obj_t * pObj, * pRoot = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ Vec_Int_t * vCis = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vObjs = Vec_IntAlloc( 1000 );
+ assert( Gia_ObjIsAnd(pRoot) );
+ if ( Vec_IntSize(&p->vCopies) < Gia_ManObjNum(p) )
+ Vec_IntFillExtra( &p->vCopies, Gia_ManObjNum(p), -1 );
+ pNew = Gia_ManStart( 1000 );
+ Gia_ManHashStart( pNew );
+ Gia_ManQuantSetSuppStart( pNew );
+ Gia_ManQuantDupConeSupp_rec( pNew, p, pRoot, vCis, vObjs, pFuncCiToKeep, pData );
+ iLit0 = Gia_ObjCopyArray( p, Abc_Lit2Var(iLit) );
+ iLit0 = Abc_LitNotCond( iLit0, Abc_LitIsCompl(iLit) );
+ if ( pOutLit ) *pOutLit = iLit0;
+ Gia_ManForEachObjVec( vCis, p, pObj, i )
+ Gia_ObjSetCopyArray( p, Gia_ObjId(p, pObj), -1 );
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ Gia_ObjSetCopyArray( p, Gia_ObjId(p, pObj), -1 );
+ //assert( Vec_IntCountLarger(&p->vCopies, -1) == 0 );
+ Vec_IntFree( vObjs );
+ // remap into CI Ids
+ Vec_IntForEachEntry( vCis, iObj, i )
+ Vec_IntWriteEntry( vCis, i, Gia_ManIdToCioId(p, iObj) );
+ if ( pvCis ) *pvCis = vCis;
+ return pNew;
+}
+void Gia_ManQuantExist_rec( Gia_Man_t * p, int iObj, int pRes[2] )
+{
+ Gia_Obj_t * pObj;
+ int Lits0[2], Lits1[2], pFans[2], fCompl[2];
+ if ( Gia_ObjIsTravIdCurrentId( p, iObj ) )
+ {
+ Gia_ObjCopyGetTwoArray( p, iObj, pRes );
+ return;
+ }
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pRes[0] = 0; pRes[1] = 1;
+ Gia_ObjCopySetTwoArray( p, iObj, pRes );
+ return;
+ }
+ pFans[0] = Gia_ObjFaninId0( pObj, iObj );
+ pFans[1] = Gia_ObjFaninId1( pObj, iObj );
+ fCompl[0] = Gia_ObjFaninC0( pObj );
+ fCompl[1] = Gia_ObjFaninC1( pObj );
+ if ( Gia_ManQuantCheckSupp(p, pFans[0], p->iSuppPi) )
+ Gia_ManQuantExist_rec( p, pFans[0], Lits0 );
+ else
+ Lits0[0] = Lits0[1] = Abc_Var2Lit( pFans[0], 0 );
+ if ( Gia_ManQuantCheckSupp(p, pFans[1], p->iSuppPi) )
+ Gia_ManQuantExist_rec( p, pFans[1], Lits1 );
+ else
+ Lits1[0] = Lits1[1] = Abc_Var2Lit( pFans[1], 0 );
+ pRes[0] = Gia_ManHashAnd( p, Abc_LitNotCond(Lits0[0], fCompl[0]), Abc_LitNotCond(Lits1[0], fCompl[1]) );
+ pRes[1] = Gia_ManHashAnd( p, Abc_LitNotCond(Lits0[1], fCompl[0]), Abc_LitNotCond(Lits1[1], fCompl[1]) );
+ Gia_ObjCopySetTwoArray( p, iObj, pRes );
+}
+int Gia_ManQuantExist2( Gia_Man_t * p0, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData )
+{
+// abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ Vec_Int_t * vOuts, * vOuts2, * vCis;
+ Gia_Obj_t * pObj = Gia_ManObj( p0, Abc_Lit2Var(iLit) );
+ int i, n, Entry, Lit, OutLit = -1, pLits[2], nVarsQua, nAndsOld, nAndsNew;
+ if ( iLit < 2 ) return iLit;
+ if ( Gia_ObjIsCi(pObj) ) return pFuncCiToKeep(pData, Gia_ObjCioId(pObj)) ? iLit : 1;
+ assert( Gia_ObjIsAnd(pObj) );
+ pNew = Gia_ManQuantDupConeSupp( p0, iLit, pFuncCiToKeep, pData, &vCis, &OutLit );
+ if ( pNew->iSuppPi == 0 )
+ {
+ Gia_ManStop( pNew );
+ Vec_IntFree( vCis );
+ return iLit;
+ }
+ assert( pNew->iSuppPi > 0 && pNew->iSuppPi <= 64 * pNew->nSuppWords );
+ vOuts = Vec_IntAlloc( 100 );
+ vOuts2 = Vec_IntAlloc( 100 );
+ assert( OutLit > 1 );
+ Vec_IntPush( vOuts, OutLit );
+ nVarsQua = pNew->iSuppPi;
+ nAndsOld = Gia_ManAndNum(pNew);
+ while ( --pNew->iSuppPi >= 0 )
+ {
+ Entry = Abc_Lit2Var( Vec_IntEntry(vOuts, 0) );
+// printf( "Quantifying input %d with %d affected nodes (out of %d):\n",
+// pNew->iSuppPi, Gia_ManQuantCountUsed(pNew,Entry), Gia_ManAndNum(pNew) );
+ if ( Vec_IntSize(&pNew->vCopiesTwo) < 2*Gia_ManObjNum(pNew) )
+ Vec_IntFillExtra( &pNew->vCopiesTwo, 2*Gia_ManObjNum(pNew), -1 );
+ assert( Vec_IntSize(vOuts) > 0 );
+ Vec_IntClear( vOuts2 );
+ Gia_ManIncrementTravId( pNew );
+ Vec_IntForEachEntry( vOuts, Entry, i )
+ {
+ Gia_ManQuantExist_rec( pNew, Abc_Lit2Var(Entry), pLits );
+ for ( n = 0; n < 2; n++ )
+ {
+ Lit = Abc_LitNotCond( pLits[n], Abc_LitIsCompl(Entry) );
+ if ( Lit == 0 )
+ continue;
+ if ( Lit == 1 )
+ {
+ Vec_IntFree( vOuts );
+ Vec_IntFree( vOuts2 );
+ Gia_ManStop( pNew );
+ Vec_IntFree( vCis );
+ return 1;
+ }
+ Vec_IntPushUnique( vOuts2, Lit );
+ }
+ }
+ Vec_IntClear( vOuts );
+ ABC_SWAP( Vec_Int_t *, vOuts, vOuts2 );
+ }
+// printf( "\n" );
+ //printf( "The number of diff cofactors = %d.\n", Vec_IntSize(vOuts) );
+ assert( Vec_IntSize(vOuts) > 0 );
+ Vec_IntForEachEntry( vOuts, Entry, i )
+ Vec_IntWriteEntry( vOuts, i, Abc_LitNot(Entry) );
+ OutLit = Gia_ManHashAndMulti( pNew, vOuts );
+ OutLit = Abc_LitNot( OutLit );
+ Vec_IntFree( vOuts );
+ Vec_IntFree( vOuts2 );
+ // transfer back
+ Gia_ManAppendCo( pNew, OutLit );
+ nAndsNew = Gia_ManAndNum(p0);
+ Lit = Gia_ManDupConeBack( p0, pNew, vCis );
+ nAndsNew = Gia_ManAndNum(p0) - nAndsNew;
+ Gia_ManStop( pNew );
+ // report the result
+// printf( "Performed quantification with %6d nodes, %3d keep-vars, %3d quant-vars, resulting in %5d new nodes. \n",
+// nAndsOld, Vec_IntSize(vCis) - nVarsQua, nVarsQua, nAndsNew );
+// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Vec_IntFree( vCis );
+ return Lit;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Existentially quantified several variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManQuantCollect_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vQuantCis, Vec_Int_t * vQuantSide, Vec_Int_t * vQuantAnds )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId( p, iObj ) )
+ return;
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ if ( !Gia_ManQuantCheckOverlap(p, iObj) )
+ {
+ Vec_IntPush( vQuantSide, iObj );
+ return;
+ }
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vQuantCis, iObj );
+ return;
+ }
+ Gia_ManQuantCollect_rec( p, Gia_ObjFaninId0(pObj, iObj), vQuantCis, vQuantSide, vQuantAnds );
+ Gia_ManQuantCollect_rec( p, Gia_ObjFaninId1(pObj, iObj), vQuantCis, vQuantSide, vQuantAnds );
+ Vec_IntPush( vQuantAnds, iObj );
+}
+void Gia_ManQuantCollect( Gia_Man_t * p, int iObj, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vQuantCis, Vec_Int_t * vQuantSide, Vec_Int_t * vQuantAnds )
+{
+ Gia_ManQuantMarkUsedCis( p, pFuncCiToKeep, pData );
+ Gia_ManIncrementTravId( p );
+ Gia_ManQuantCollect_rec( p, iObj, vQuantCis, vQuantSide, vQuantAnds );
+// printf( "\nCreated cone with %d quant-vars, %d side-inputs, and %d internal nodes.\n",
+// Vec_IntSize(p->vQuantCis), Vec_IntSize(p->vQuantSide), Vec_IntSize(p->vQuantAnds) );
+}
+
+Gia_Man_t * Gia_ManQuantExist2Dup( Gia_Man_t * p, int iLit, Vec_Int_t * vCis, Vec_Int_t * vSide, Vec_Int_t * vAnds, int * pOutLit )
+{
+ int i, iObj, iLit0, iLit1, iLitR;
+ Gia_Man_t * pNew = Gia_ManStart( Vec_IntSize(vSide) + Vec_IntSize(vCis) + 10*Vec_IntSize(vAnds) );
+ Gia_ManQuantSetSuppStart( pNew );
+ Gia_ManHashStart( pNew );
+ if ( Vec_IntSize(&p->vCopies) < Gia_ManObjNum(p) )
+ Vec_IntFillExtra( &p->vCopies, Gia_ManObjNum(p), -1 );
+ Vec_IntForEachEntry( vSide, iObj, i )
+ {
+ Gia_ObjSetCopyArray( p, iObj, Gia_ManAppendCi(pNew) );
+ Gia_ManQuantSetSuppZero( pNew );
+ }
+ Vec_IntForEachEntry( vCis, iObj, i )
+ {
+ Gia_ObjSetCopyArray( p, iObj, (iLit0 = Gia_ManAppendCi(pNew)) );
+ Gia_ManQuantSetSuppZero( pNew );
+ Gia_ManQuantSetSuppCi( pNew, Gia_ManObj(pNew, Abc_Lit2Var(iLit0)) );
+ }
+ Vec_IntForEachEntry( vAnds, iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ iLit0 = Gia_ObjCopyArray( p, Gia_ObjFaninId0(pObj, iObj) );
+ iLit1 = Gia_ObjCopyArray( p, Gia_ObjFaninId1(pObj, iObj) );
+ iLit0 = Abc_LitNotCond( iLit0, Gia_ObjFaninC0(pObj) );
+ iLit1 = Abc_LitNotCond( iLit1, Gia_ObjFaninC1(pObj) );
+ iLitR = Gia_ManHashAnd( pNew, iLit0, iLit1 );
+ Gia_ObjSetCopyArray( p, iObj, iLitR );
+ }
+ iLit0 = Gia_ObjCopyArray( p, Abc_Lit2Var(iLit) );
+ iLit0 = Abc_LitNotCond( iLit0, Abc_LitIsCompl(iLit) );
+ if ( pOutLit ) *pOutLit = iLit0;
+ Vec_IntForEachEntry( vSide, iObj, i )
+ Gia_ObjSetCopyArray( p, iObj, -1 );
+ Vec_IntForEachEntry( vCis, iObj, i )
+ Gia_ObjSetCopyArray( p, iObj, -1 );
+ Vec_IntForEachEntry( vAnds, iObj, i )
+ Gia_ObjSetCopyArray( p, iObj, -1 );
+ return pNew;
+}
+int Gia_ManQuantExistInt( Gia_Man_t * p0, int iLit, Vec_Int_t * vCis, Vec_Int_t * vSide, Vec_Int_t * vAnds )
+{
+ int i, Lit, iOutLit, nAndsNew, pLits[2], pRes[2] = {0};
+ Gia_Man_t * pNew;
+ if ( iLit < 2 )
+ return 0;
+ if ( Vec_IntSize(vCis) == 0 )
+ return iLit;
+ if ( Vec_IntSize(vAnds) == 0 )
+ {
+ assert( Gia_ObjIsCi( Gia_ManObj(p0, Abc_Lit2Var(iLit)) ) );
+ return Vec_IntFind(vCis, Abc_Lit2Var(iLit)) == -1 ? iLit : 1;
+ }
+ pNew = Gia_ManQuantExist2Dup( p0, iLit, vCis, vSide, vAnds, &iOutLit );
+ if ( Vec_IntSize(&pNew->vCopiesTwo) < 2*Gia_ManObjNum(pNew) )
+ Vec_IntFillExtra( &pNew->vCopiesTwo, 2*Gia_ManObjNum(pNew), -1 );
+ Gia_ObjCopySetTwoArray( pNew, 0, pRes );
+ for ( i = 0; i < Gia_ManCiNum(pNew); i++ )
+ {
+ pRes[0] = pRes[1] = Abc_Var2Lit( i+1, 0 );
+ Gia_ObjCopySetTwoArray( pNew, i+1, pRes );
+ }
+ assert( pNew->iSuppPi == Gia_ManCiNum(pNew) - Vec_IntSize(vSide) );
+ for ( i = Gia_ManCiNum(pNew) - 1; i >= Vec_IntSize(vSide); i-- )
+ {
+ pRes[0] = 0; pRes[1] = 1;
+ Gia_ObjCopySetTwoArray( pNew, i+1, pRes );
+
+ pNew->iSuppPi--;
+ if ( Vec_IntSize(&pNew->vCopiesTwo) < 2*Gia_ManObjNum(pNew) )
+ Vec_IntFillExtra( &pNew->vCopiesTwo, 2*Gia_ManObjNum(pNew), -1 );
+ Gia_ManIncrementTravId( pNew );
+ Gia_ManQuantExist_rec( pNew, Abc_Lit2Var(iOutLit), pLits );
+ pLits[0] = Abc_LitNotCond( pLits[0], Abc_LitIsCompl(iOutLit) );
+ pLits[1] = Abc_LitNotCond( pLits[1], Abc_LitIsCompl(iOutLit) );
+ iOutLit = Gia_ManHashOr( pNew, pLits[0], pLits[1] );
+
+ pRes[0] = pRes[1] = Abc_Var2Lit( i+1, 0 );
+ Gia_ObjCopySetTwoArray( pNew, i+1, pRes );
+ }
+ assert( pNew->iSuppPi == 0 );
+ Vec_IntAppend( vSide, vCis );
+ // transfer back
+ Gia_ManAppendCo( pNew, iOutLit );
+ nAndsNew = Gia_ManAndNum(p0);
+ Lit = Gia_ManDupConeBackObjs( p0, pNew, vSide );
+ nAndsNew = Gia_ManAndNum(p0) - nAndsNew;
+ Vec_IntShrink( vSide, Vec_IntSize(vSide) - Vec_IntSize(vCis) );
+// printf( "Performed quantification with %6d -> %6d nodes, %3d side-vars, %3d quant-vars, resulting in %5d new nodes. \n",
+// Vec_IntSize(vAnds), Gia_ManAndNum(pNew), Vec_IntSize(vSide), Vec_IntSize(vCis), nAndsNew );
+ Gia_ManStop( pNew );
+ return Lit;
+}
+int Gia_ManQuantExist( Gia_Man_t * p0, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData )
+{
+ int Res;
+ Vec_Int_t * vQuantCis = Vec_IntAlloc( 100 );
+ Vec_Int_t * vQuantSide = Vec_IntAlloc( 100 );
+ Vec_Int_t * vQuantAnds = Vec_IntAlloc( 100 );
+ Gia_ManQuantCollect( p0, Abc_Lit2Var(iLit), pFuncCiToKeep, pData, vQuantCis, vQuantSide, vQuantAnds );
+ Res = Gia_ManQuantExistInt( p0, iLit, vQuantCis, vQuantSide, vQuantAnds );
+ Vec_IntFree( vQuantCis );
+ Vec_IntFree( vQuantSide );
+ Vec_IntFree( vQuantAnds );
+ return Res;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index 032980fe..7d0ef288 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -119,6 +119,7 @@ void Gia_ManStop( Gia_Man_t * p )
Vec_IntErase( &p->vCopies );
Vec_IntErase( &p->vCopies2 );
Vec_IntErase( &p->vCopiesTwo );
+ Vec_IntErase( &p->vSuppVars );
Vec_WrdFreeP( &p->vSuppWords );
Vec_IntFreeP( &p->vTtNums );
Vec_IntFreeP( &p->vTtNodes );
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index cb12d5f6..7a0e1617 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -24,6 +24,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaEra.c \
src/aig/gia/giaEra2.c \
src/aig/gia/giaEsop.c \
+ src/aig/gia/giaExist.c \
src/aig/gia/giaFalse.c \
src/aig/gia/giaFanout.c \
src/aig/gia/giaForce.c \