blob: fce7e4d7426a05a56fd5b303c29a92e73337e6cb [file] [log] [blame]
/**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