diff options
Diffstat (limited to 'src/aig/gia/giaGiarf.c')
-rw-r--r-- | src/aig/gia/giaGiarf.c | 1077 |
1 files changed, 1077 insertions, 0 deletions
diff --git a/src/aig/gia/giaGiarf.c b/src/aig/gia/giaGiarf.c new file mode 100644 index 00000000..501f9bb3 --- /dev/null +++ b/src/aig/gia/giaGiarf.c @@ -0,0 +1,1077 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// combinational simulation manager +typedef struct Hcd_Man_t_ Hcd_Man_t; +struct Hcd_Man_t_ +{ + // parameters + Gia_Man_t * pGia; // the AIG to be used for simulation + int nBTLimit; // internal backtrack limit + int fVerbose; // internal verbose flag + // internal variables + unsigned * pSimInfo; // simulation info for each object + Vec_Ptr_t * vSimInfo; // pointers to the CI simulation info + Vec_Ptr_t * vSimPres; // pointers to the presense of simulation info + // temporaries + Vec_Int_t * vClassOld; // old class numbers + Vec_Int_t * vClassNew; // new class numbers + Vec_Int_t * vClassTemp; // temporary storage + Vec_Int_t * vRefinedC; // refined const reprs +}; + +static inline unsigned Hcd_ObjSim( Hcd_Man_t * p, int Id ) { return p->pSimInfo[Id]; } +static inline unsigned * Hcd_ObjSimP( Hcd_Man_t * p, int Id ) { return p->pSimInfo + Id; } +static inline unsigned Hcd_ObjSetSim( Hcd_Man_t * p, int Id, unsigned n ) { return p->pSimInfo[Id] = n; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hcd_Man_t * Gia_ManEquivStart( Gia_Man_t * pGia, int nBTLimit, int fVerbose ) +{ + Hcd_Man_t * p; + Gia_Obj_t * pObj; + int i; + p = ABC_CALLOC( Hcd_Man_t, 1 ); + p->pGia = pGia; + p->nBTLimit = nBTLimit; + p->fVerbose = fVerbose; + p->pSimInfo = ABC_ALLOC( unsigned, Gia_ManObjNum(pGia) ); + p->vClassOld = Vec_IntAlloc( 100 ); + p->vClassNew = Vec_IntAlloc( 100 ); + p->vClassTemp = Vec_IntAlloc( 100 ); + p->vRefinedC = Vec_IntAlloc( 100 ); + // collect simulation info + p->vSimInfo = Vec_PtrAlloc( 1000 ); + Gia_ManForEachCi( pGia, pObj, i ) + Vec_PtrPush( p->vSimInfo, Hcd_ObjSimP(p, Gia_ObjId(pGia,pObj)) ); + p->vSimPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pGia), 1 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivStop( Hcd_Man_t * p ) +{ + Vec_PtrFree( p->vSimInfo ); + Vec_PtrFree( p->vSimPres ); + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Compared two simulation infos.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareEqual( unsigned s0, unsigned s1 ) +{ + if ( (s0 & 1) == (s1 & 1) ) + return s0 == s1; + else + return s0 ==~s1; +} + +/**Function************************************************************* + + Synopsis [Compares one simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareConst( unsigned s ) +{ + if ( s & 1 ) + return s ==~0; + else + return s == 0; +} + +/**Function************************************************************* + + Synopsis [Creates one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassCreate( Gia_Man_t * pGia, Vec_Int_t * vClass ) +{ + int Repr = -1, EntPrev = -1, Ent, i; + assert( Vec_IntSize(vClass) > 0 ); + Vec_IntForEachEntry( vClass, Ent, i ) + { + if ( i == 0 ) + { + Repr = Ent; + Gia_ObjSetRepr( pGia, Ent, -1 ); + EntPrev = Ent; + } + else + { + Gia_ObjSetRepr( pGia, Ent, Repr ); + Gia_ObjSetNext( pGia, EntPrev, Ent ); + EntPrev = Ent; + } + } + Gia_ObjSetNext( pGia, EntPrev, 0 ); +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassClassRemoveOne( Hcd_Man_t * p, int i ) +{ + int iRepr, Ent; + if ( Gia_ObjIsConst(p->pGia, i) ) + { + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + return 1; + } + if ( !Gia_ObjIsClass(p->pGia, i) ) + return 0; + assert( Gia_ObjIsClass(p->pGia, i) ); + iRepr = Gia_ObjRepr( p->pGia, i ); + if ( iRepr == GIA_VOID ) + iRepr = i; + // collect nodes + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Gia_ClassForEachObj( p->pGia, iRepr, Ent ) + { + if ( Ent == i ) + Vec_IntPush( p->vClassNew, Ent ); + else + Vec_IntPush( p->vClassOld, Ent ); + } + assert( Vec_IntSize( p->vClassNew ) == 1 ); + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + assert( !Gia_ObjIsClass(p->pGia, i) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassRefineOne( Hcd_Man_t * p, int i ) +{ + unsigned Sim0, Sim1; + int Ent; + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Vec_IntPush( p->vClassOld, i ); + Sim0 = Hcd_ObjSim(p, i); + Gia_ClassForEachObj1( p->pGia, i, Ent ) + { + Sim1 = Hcd_ObjSim(p, Ent); + if ( Hcd_ManCompareEqual( Sim0, Sim1 ) ) + Vec_IntPush( p->vClassOld, Ent ); + else + Vec_IntPush( p->vClassNew, Ent ); + } + if ( Vec_IntSize( p->vClassNew ) == 0 ) + return 0; + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + if ( Vec_IntSize(p->vClassNew) > 1 ) + return 1 + Hcd_ManClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManHashKey( unsigned * pSim, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0; + int i; + if ( pSim[0] & 1 ) + for ( i = 0; i < nWords; i++ ) + uHash ^= ~pSim[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nWords; i++ ) + uHash ^= pSim[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Rehashes the refined classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRehash( Hcd_Man_t * p, Vec_Int_t * vRefined ) +{ + int * pTable, nTableSize, Key, i, k; + nTableSize = Gia_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 ); + pTable = ABC_CALLOC( int, nTableSize ); + Vec_IntForEachEntry( vRefined, i, k ) + { + assert( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ); + Key = Hcd_ManHashKey( Hcd_ObjSimP(p, i), 1, nTableSize ); + if ( pTable[Key] == 0 ) + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + else + { + Gia_ObjSetNext( p->pGia, pTable[Key], i ); + Gia_ObjSetRepr( p->pGia, i, Gia_ObjRepr(p->pGia, pTable[Key]) ); + if ( Gia_ObjRepr(p->pGia, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pGia, i, pTable[Key] ); + } + pTable[Key] = i; + } + ABC_FREE( pTable ); +// Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); + // refine classes in the table + Vec_IntForEachEntry( vRefined, i, k ) + { + if ( Gia_ObjIsHead( p->pGia, i ) ) + Hcd_ManClassRefineOne( p, i ); + } + Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); +} + +/**Function************************************************************* + + Synopsis [Refines equivalence classes after simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRefine( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Vec_IntClear( p->vRefinedC ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Gia_ObjIsTail(p->pGia, i) ) // add check for the class level + { + Hcd_ManClassRefineOne( p, Gia_ObjRepr(p->pGia, i) ); + } + else if ( Gia_ObjIsConst(p->pGia, i) ) + { + if ( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ) + Vec_IntPush( p->vRefinedC, i ); + } + } + Hcd_ManClassesRehash( p, p->vRefinedC ); +} + +/**Function************************************************************* + + Synopsis [Creates equivalence classes for the first time.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesCreate( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pGia->pReprs == NULL ); + p->pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pGia) ); + p->pGia->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( p->pGia, pObj, i ) + Gia_ObjSetRepr( p->pGia, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); +} + +/**Function************************************************************* + + Synopsis [Initializes simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulationInit( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachCi( p->pGia, pObj, i ) + Hcd_ObjSetSim( p, i, (Gia_ManRandom(0) << 1) ); +} + +/**Function************************************************************* + + Synopsis [Performs one round of simple combinational simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulateSimple( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + int i; + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + Res0 = Hcd_ObjSim( p, Gia_ObjFaninId0(pObj, i) ); + Res1 = Hcd_ObjSim( p, Gia_ObjFaninId1(pObj, i) ); + Hcd_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); + } +} + + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_Resimulate_rec( Hcd_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + if ( Gia_ObjIsTravIdCurrentId( p->pGia, iObj ) ) + return Hcd_ObjSim( p, iObj ); + Gia_ObjSetTravIdCurrentId( p->pGia, iObj ); + pObj = Gia_ManObj(p->pGia, iObj); + if ( Gia_ObjIsCi(pObj) ) + return Hcd_ObjSim( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Res0 = Gia_Resimulate_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + Res1 = Gia_Resimulate_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + return Hcd_ObjSetSim( p, iObj, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); +} + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [Assumes that the counter-example is assigned at the PIs. + The counter-example should have the first bit set to 0 at each PI.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ResimulateAndRefine( Hcd_Man_t * p, int i ) +{ + int RetValue, iObj; + Gia_ManIncrementTravId( p->pGia ); + Gia_ClassForEachObj( p->pGia, i, iObj ) + Gia_Resimulate_rec( p, iObj ); + RetValue = Hcd_ManClassRefineOne( p, i ); + if ( RetValue == 0 ) + printf( "!!! no refinement !!!\n" ); +// assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Returns temporary representative of the node.] + + Description [The temp repr is the first node among the nodes in the class that + (a) precedes the given node, and (b) whose level is lower than the given node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ObjTempRepr( Gia_Man_t * p, int i, int Level ) +{ + int iRepr, iMember; + iRepr = Gia_ObjRepr( p, i ); + if ( !Gia_ObjProved(p, i) ) + return NULL; + if ( Gia_ObjFailed(p, i) ) + return NULL; + if ( iRepr == GIA_VOID ) + return NULL; + if ( iRepr == 0 ) + return Gia_ManConst0( p ); +// if ( p->pLevels[iRepr] < Level ) +// return Gia_ManObj( p, iRepr ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjFailed(p, iMember) ) + continue; + if ( iMember >= i ) + return NULL; + if ( Gia_ObjLevelId(p, iMember) < Level ) + return Gia_ManObj( p, iMember ); + } + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Generates reduced AIG for the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_GenerateReducedLevel( Gia_Man_t * p, int Level, Vec_Ptr_t ** pvRoots ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRepr; + Vec_Ptr_t * vRoots; + int i; + vRoots = Vec_PtrAlloc( 100 ); + // copy unmarked nodes + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjLevelId(p, i) > Level ) + continue; + if ( Gia_ObjLevelId(p, i) == Level ) + Vec_PtrPush( vRoots, pObj ); + if ( Gia_ObjLevelId(p, i) < Level && (pRepr = Gia_ObjTempRepr(p, i, Level)) ) + { +// printf( "Substituting %d <--- %d\n", Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj) ); + assert( pRepr < pObj ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + continue; + } + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + *pvRoots = vRoots; + // required by SAT solving + Gia_ManCreateRefs( pNew ); + Gia_ManFillValue( pNew ); + Gia_ManIncrementTravId( pNew ); // needed for MiniSat to record cexes +// Gia_ManSetPhase( pNew ); // needed if MiniSat is using polarity -- should not be enabled for TAS because fPhase is used to label + return pNew; +} + +/**Function************************************************************* + + Synopsis [Collects relevant classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_CollectRelatedClasses( Gia_Man_t * pGia, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vClasses; + Gia_Obj_t * pRoot, * pRepr; + int i; + vClasses = Vec_PtrAlloc( 100 ); + Gia_ManConst0( pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pRoot, i ) + { + pRepr = Gia_ObjReprObj( pGia, Gia_ObjId(pGia, pRoot) ); + if ( pRepr == NULL || pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); + } + Gia_ManConst0( pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + return vClasses; +} + +/**Function************************************************************* + + Synopsis [Collects class members.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Obj_t * Gia_CollectClassMembers( Gia_Man_t * p, Gia_Obj_t * pRepr, Vec_Ptr_t * vMembers, int Level ) +{ + Gia_Obj_t * pTempRepr = NULL; + int iRepr, iMember; + iRepr = Gia_ObjId( p, pRepr ); + Vec_PtrClear( vMembers ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjLevelId(p, iMember) == Level ) + Vec_PtrPush( vMembers, Gia_ManObj( p, iMember ) ); + if ( pTempRepr == NULL && Gia_ObjLevelId(p, iMember) < Level ) + pTempRepr = Gia_ManObj( p, iMember ); + } + return pTempRepr; +} + + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Gia_GiarfStorePatternTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Gia_InfoHasBit( pPres, iBit ) && + Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_GiarfStorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex ) +{ + int k; + for ( k = 1; k < 32; k++ ) + if ( Gia_GiarfStorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) ) + break; + return (int)(k < 32); +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfInsertPattern( Hcd_Man_t * p, Vec_Int_t * vCex, int k ) +{ + Gia_Obj_t * pObj; + unsigned * pInfo; + int Lit, i; + Vec_IntForEachEntry( vCex, Lit, i ) + { + pObj = Gia_ManCi( p->pGia, Gia_Lit2Var(Lit) ); + pInfo = Hcd_ObjSimP( p, Gia_ObjId( p->pGia, pObj ) ); + if ( Gia_InfoHasBit( pInfo, k ) == Gia_LitIsCompl(Lit) ) + Gia_InfoXorBit( pInfo, k ); + } +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfPrintClasses( Gia_Man_t * pGia ) +{ + int nFails = 0; + int nProves = 0; + int nTotal = 0; + int nBoth = 0; + int i; + for ( i = 0; i < Gia_ManObjNum(pGia); i++ ) + { + nFails += Gia_ObjFailed(pGia, i); + nProves += Gia_ObjProved(pGia, i); + nTotal += Gia_ObjReprObj(pGia, i) != NULL; + nBoth += Gia_ObjFailed(pGia, i) && Gia_ObjProved(pGia, i); + } + printf( "nFails = %7d. nProves = %7d. nBoth = %7d. nTotal = %7d.\n", + nFails, nProves, nBoth, nTotal ); +} + +ABC_NAMESPACE_IMPL_END + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ComputeEquivalencesLevel( Hcd_Man_t * p, Gia_Man_t * pGiaLev, Vec_Ptr_t * vOldRoots, int Level, int fUseMiniSat ) +{ + int fUse2Solver = 0; + Cec_ManSat_t * pSat; + Cec_ParSat_t Pars; + Tas_Man_t * pTas; + Vec_Int_t * vCex; + Vec_Ptr_t * vClasses, * vMembers, * vOldRootsNew; + Gia_Obj_t * pRoot, * pMember, * pMemberPrev, * pRepr, * pTempRepr; + int i, k, nIter, iRoot, iRootNew, iMember, iMemberPrev, status, fOneFailed;//, iRepr;//, fTwoMember; + int nSaved = 0, nRecords = 0, nUndec = 0, nClassRefs = 0, nTsat = 0, nMiniSat = 0; + int clk, timeTsat = 0, timeMiniSat = 0, timeSim = 0, timeTotal = clock(); + if ( Vec_PtrSize(vOldRoots) == 0 ) + return 0; + // start SAT solvers + Cec_ManSatSetDefaultParams( &Pars ); + Pars.fPolarFlip = 0; + Pars.nBTLimit = p->nBTLimit; + pSat = Cec_ManSatCreate( pGiaLev, &Pars ); + pTas = Tas_ManAlloc( pGiaLev, p->nBTLimit ); + if ( fUseMiniSat ) + vCex = Cec_ManSatReadCex( pSat ); + else + vCex = Tas_ReadModel( pTas ); + vMembers = Vec_PtrAlloc( 100 ); + Vec_PtrCleanSimInfo( p->vSimPres, 0, 1 ); + // resolve constants + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( !Gia_ObjIsConst( p->pGia, iRoot ) ) + continue; + iRootNew = Gia_LitNotCond( pRoot->Value, pRoot->fPhase ); + assert( iRootNew != 1 ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; +// Hcd_ManClassClassRemoveOne( p, iRoot ); + Gia_ObjSetFailed( p->pGia, iRoot ); + } + else if ( status == 1 ) // unsat + { + Gia_ObjSetProved( p->pGia, iRoot ); +// printf( "proved constant %d\n", iRoot ); + } + else // sat + { +// printf( "Disproved constant %d\n", iRoot ); + Gia_ObjUnsetRepr( p->pGia, iRoot ); // do we need this? + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + } + } + + vClasses = Vec_PtrAlloc( 100 ); + vOldRootsNew = Vec_PtrAlloc( 100 ); + for ( nIter = 0; Vec_PtrSize(vOldRoots) > 0; nIter++ ) + { +// printf( "Iter = %d (Size = %d)\n", nIter, Vec_PtrSize(vOldRoots) ); + // resolve equivalences + Vec_PtrClear( vClasses ); + Vec_PtrClear( vOldRootsNew ); + Gia_ManConst0( p->pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( Gia_ObjIsHead( p->pGia, iRoot ) ) + pRepr = pRoot; + else if ( Gia_ObjIsClass( p->pGia, iRoot ) ) + pRepr = Gia_ObjReprObj( p->pGia, iRoot ); + else + continue; + if ( pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// fTwoMember = Gia_ClassIsPair(p->pGia, iRepr) + // derive temp repr and members on this level + pTempRepr = Gia_CollectClassMembers( p->pGia, pRepr, vMembers, Level ); + if ( pTempRepr ) + Vec_PtrPush( vMembers, pTempRepr ); + if ( Vec_PtrSize(vMembers) < 2 ) + continue; + // try proving the members + fOneFailed = 0; + pMemberPrev = (Gia_Obj_t *)Vec_PtrEntryLast( vMembers ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + { + iMemberPrev = Gia_LitNotCond( pMemberPrev->Value, pMemberPrev->fPhase ); + iMember = Gia_LitNotCond( pMember->Value, !pMember->fPhase ); + assert( iMemberPrev != iMember ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; + if ( Gia_ObjLevel(p->pGia, pMemberPrev) > Gia_ObjLevel(p->pGia, pMember) ) + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + else + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMember) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + } + else if ( status == 1 ) // unsat + { +// Gia_ObjSetProved( p->pGia, iRoot ); + } + else // sat + { +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// if ( Gia_ClassIsPair(p->pGia, iRepr) ) +// Gia_ClassUndoPair(p->pGia, iRepr); +// else + { + fOneFailed = 1; + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + Gia_GiarfInsertPattern( p, vCex, (k % 31) + 1 ); + } + } + pMemberPrev = pMember; +// if ( fOneFailed ) +// k += Vec_PtrSize(vMembers) / 4; + } + // if fail, quit this class + if ( fOneFailed ) + { + nClassRefs++; + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + if ( pMember != pTempRepr && !Gia_ObjFailed(p->pGia, Gia_ObjId(p->pGia, pMember)) ) + Vec_PtrPush( vOldRootsNew, pMember ); + clk = clock(); + Gia_ResimulateAndRefine( p, Gia_ObjId(p->pGia, pRepr) ); + timeSim += clock() - clk; + } + else + { + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + Gia_ObjSetProved( p->pGia, Gia_ObjId(p->pGia, pMember) ); +/* +// } +// else +// { + printf( "Proved equivalent: " ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + printf( "%d(L=%d) ", Gia_ObjId(p->pGia, pMember), p->pGia->pLevels[Gia_ObjId(p->pGia, pMember)] ); + printf( "\n" ); +*/ + } + + } + Vec_PtrClear( vOldRoots ); + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRootsNew, pMember, i ) + Vec_PtrPush( vOldRoots, pMember ); + // clean up + Gia_ManConst0( p->pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + } + Vec_PtrFree( vClasses ); + Vec_PtrFree( vOldRootsNew ); + printf( "nSaved = %d nRecords = %d nUndec = %d nClassRefs = %d nMiniSat = %d nTas = %d\n", + nSaved, nRecords, nUndec, nClassRefs, nMiniSat, nTsat ); + ABC_PRT( "Tas ", timeTsat ); + ABC_PRT( "MiniSat", timeMiniSat ); + ABC_PRT( "Sim ", timeSim ); + ABC_PRT( "Total ", clock() - timeTotal ); + + // resimulate +// clk = clock(); + Hcd_ManSimulateSimple( p ); + Hcd_ManClassesRefine( p ); +// ABC_PRT( "Simulate/refine", clock() - clk ); + + // verify the results + Vec_PtrFree( vMembers ); + Tas_ManStop( pTas ); + Cec_ManSatStop( pSat ); + return nIter; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ComputeEquivalences( Gia_Man_t * pGia, int nBTLimit, int fUseMiniSat, int fVerbose ) +{ + Hcd_Man_t * p; + Vec_Ptr_t * vRoots; + Gia_Man_t * pGiaLev; + int i, Lev, nLevels, nIters, clk; + Gia_ManRandom( 1 ); + Gia_ManSetPhase( pGia ); + nLevels = Gia_ManLevelNum( pGia ); + Gia_ManIncrementTravId( pGia ); + // start the manager + p = Gia_ManEquivStart( pGia, nBTLimit, fVerbose ); + // create trivial classes + Hcd_ManClassesCreate( p ); + // refine + for ( i = 0; i < 3; i++ ) + { + clk = clock(); + Hcd_ManSimulationInit( p ); + Hcd_ManSimulateSimple( p ); + ABC_PRT( "Sim", clock() - clk ); + clk = clock(); + Hcd_ManClassesRefine( p ); + ABC_PRT( "Ref", clock() - clk ); + } + // process in the levelized order + for ( Lev = 1; Lev < nLevels; Lev++ ) + { + clk = clock(); + printf( "LEVEL %3d (out of %3d) ", Lev, nLevels ); + pGiaLev = Gia_GenerateReducedLevel( pGia, Lev, &vRoots ); + nIters = Gia_ComputeEquivalencesLevel( p, pGiaLev, vRoots, Lev, fUseMiniSat ); + Gia_ManStop( pGiaLev ); + Vec_PtrFree( vRoots ); + printf( "Iters = %3d " ); + ABC_PRT( "Time", clock() - clk ); + } + Gia_GiarfPrintClasses( pGia ); + // clean up + Gia_ManEquivStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |