diff options
Diffstat (limited to 'src/aig/gia')
-rw-r--r-- | src/aig/gia/gia.h | 9 | ||||
-rw-r--r-- | src/aig/gia/giaDup.c | 258 | ||||
-rw-r--r-- | src/aig/gia/giaExist.c | 526 | ||||
-rw-r--r-- | src/aig/gia/giaMan.c | 1 | ||||
-rw-r--r-- | src/aig/gia/module.make | 1 |
5 files changed, 548 insertions, 247 deletions
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 \ |