| /**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 |
| |