| /**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 = Abc_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 = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| 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 = Abc_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, Abc_Lit2Var(pLits[i])); |
| pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); |
| if ( Abc_InfoHasBit( pPres, iBit ) && |
| Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) |
| return 0; |
| } |
| for ( i = 0; i < nLits; i++ ) |
| { |
| pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); |
| pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); |
| Abc_InfoSetBit( pPres, iBit ); |
| if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) |
| Abc_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, Abc_Lit2Var(Lit) ); |
| pInfo = Hcd_ObjSimP( p, Gia_ObjId( p->pGia, pObj ) ); |
| if ( Abc_InfoHasBit( pInfo, k ) == Abc_LitIsCompl(Lit) ) |
| Abc_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 "proof/cec/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; |
| clock_t 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 = Abc_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 = Abc_LitNotCond( pMemberPrev->Value, pMemberPrev->fPhase ); |
| iMember = Abc_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; |
| clock_t 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 |
| |