summaryrefslogtreecommitdiffstats
path: root/src/aig/gia
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia')
-rw-r--r--src/aig/gia/gia.c5
-rw-r--r--src/aig/gia/gia.h300
-rw-r--r--src/aig/gia/giaAbs.c553
-rw-r--r--src/aig/gia/giaAbs.h89
-rw-r--r--src/aig/gia/giaAig.c247
-rw-r--r--src/aig/gia/giaAig.h22
-rw-r--r--src/aig/gia/giaAiger.c99
-rw-r--r--src/aig/gia/giaAiger_new.c1251
-rw-r--r--src/aig/gia/giaAiger_old.c1255
-rw-r--r--src/aig/gia/giaBidec.c308
-rw-r--r--src/aig/gia/giaCSat.c7
-rw-r--r--src/aig/gia/giaCSatOld.c5
-rw-r--r--src/aig/gia/giaCTas.c1788
-rw-r--r--src/aig/gia/giaCTas2.c208
-rw-r--r--src/aig/gia/giaCof.c11
-rw-r--r--src/aig/gia/giaConstr.c5
-rw-r--r--src/aig/gia/giaDfs.c104
-rw-r--r--src/aig/gia/giaDup.c227
-rw-r--r--src/aig/gia/giaEmbed.c10
-rw-r--r--src/aig/gia/giaEnable.c7
-rw-r--r--src/aig/gia/giaEquiv.c97
-rw-r--r--src/aig/gia/giaEra.c561
-rw-r--r--src/aig/gia/giaEra2.c1954
-rw-r--r--src/aig/gia/giaFanout.c5
-rw-r--r--src/aig/gia/giaForce.c10
-rw-r--r--src/aig/gia/giaFrames.c13
-rw-r--r--src/aig/gia/giaFront.c7
-rw-r--r--src/aig/gia/giaGiarf.c1077
-rw-r--r--src/aig/gia/giaGlitch.c5
-rw-r--r--src/aig/gia/giaHash.c27
-rw-r--r--src/aig/gia/giaHcd.c686
-rw-r--r--src/aig/gia/giaIf.c (renamed from src/aig/gia/giaMap.c)260
-rw-r--r--src/aig/gia/giaMan.c85
-rw-r--r--src/aig/gia/giaMem.c598
-rw-r--r--src/aig/gia/giaPat.c5
-rw-r--r--src/aig/gia/giaProp.c5
-rw-r--r--src/aig/gia/giaReparam.c201
-rw-r--r--src/aig/gia/giaRetime.c13
-rw-r--r--src/aig/gia/giaSat.c5
-rw-r--r--src/aig/gia/giaScl.c9
-rw-r--r--src/aig/gia/giaShrink.c151
-rw-r--r--src/aig/gia/giaSim.c95
-rw-r--r--src/aig/gia/giaSort.c5
-rw-r--r--src/aig/gia/giaSpeedup.c810
-rw-r--r--src/aig/gia/giaSupMin.c165
-rw-r--r--src/aig/gia/giaSwitch.c39
-rw-r--r--src/aig/gia/giaTsim.c24
-rw-r--r--src/aig/gia/giaUtil.c428
-rw-r--r--src/aig/gia/module.make8
49 files changed, 13546 insertions, 303 deletions
diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c
index 4cbb1731..4fb33a9b 100644
--- a/src/aig/gia/gia.c
+++ b/src/aig/gia/gia.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -45,3 +48,5 @@
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index f023366a..3358ca76 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -21,6 +21,7 @@
#ifndef __GIA_H__
#define __GIA_H__
+
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
@@ -37,9 +38,10 @@
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
-#ifdef __cplusplus
-extern "C" {
-#endif
+
+
+ABC_NAMESPACE_HEADER_START
+
#define GIA_NONE 0x1FFFFFFF
#define GIA_VOID 0x0FFFFFFF
@@ -48,6 +50,10 @@ extern "C" {
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Gia_MmFixed_t_ Gia_MmFixed_t;
+typedef struct Gia_MmFlex_t_ Gia_MmFlex_t;
+typedef struct Gia_MmStep_t_ Gia_MmStep_t;
+
typedef struct Gia_Rpr_t_ Gia_Rpr_t;
struct Gia_Rpr_t_
{
@@ -88,18 +94,6 @@ struct Gia_Obj_t_
// - traversal ID of the node during traversal
// - reference counter of the node (will not be used in the future)
-// sequential counter-example
-typedef struct Gia_Cex_t_ Gia_Cex_t;
-struct Gia_Cex_t_
-{
- int iPo; // the zero-based number of PO, for which verification failed
- int iFrame; // the zero-based number of the time-frame, for which verificaiton failed
- int nRegs; // the number of registers in the miter
- int nPis; // the number of primary inputs in the miter
- int nBits; // the number of words of bit data used
- unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis)
-};
-
// new AIG manager
typedef struct Gia_Man_t_ Gia_Man_t;
struct Gia_Man_t_
@@ -116,8 +110,10 @@ struct Gia_Man_t_
int nHTable; // hash table size
int fAddStrash; // performs additional structural hashing
int * pRefs; // the reference count
- int * pLevels; // levels of the nodes
+ int * pNodeRefs; // node references
+ Vec_Int_t * vLevels; // levels of the nodes
int nLevels; // the mamixum level
+ int nConstrs; // the number of constraints
int nTravIds; // the current traversal ID
int nFront; // frontier size
int * pReprsOld; // representatives (for CIs and ANDs)
@@ -129,9 +125,11 @@ struct Gia_Man_t_
int * pFanData; // the database to store fanout information
int nFansAlloc; // the size of fanout representation
int * pMapping; // mapping for each node
- Gia_Cex_t * pCexComb; // combinational counter-example
- Gia_Cex_t * pCexSeq; // sequential counter-example
+ Vec_Int_t * vLutConfigs; // LUT configurations
+ Abc_Cex_t * pCexComb; // combinational counter-example
+ Abc_Cex_t * pCexSeq; // sequential counter-example
int * pCopies; // intermediate copies
+ Vec_Int_t * vTruths; // used for truth table computation
Vec_Int_t * vFlopClasses; // classes of flops for retiming/merging/etc
unsigned char* pSwitching; // switching activity for each object
Gia_Plc_t * pPlacement; // placement of the objects
@@ -139,6 +137,12 @@ struct Gia_Man_t_
int nTravIdsAlloc; // the number of trav IDs allocated
Vec_Ptr_t * vNamesIn; // the input names
Vec_Ptr_t * vNamesOut; // the output names
+ Vec_Int_t * vCiNumsOrig; // original names of the CIs
+ Vec_Int_t * vCoNumsOrig; // original names of the COs
+ Vec_Vec_t * vClockDoms; // clock domains
+ Vec_Flt_t * vTiming; // arrival/required/slack
+ void * pManTime; // the timing manager
+ void * pLutLib; // LUT library
};
@@ -178,26 +182,31 @@ struct Gia_ParSim_t_
int TimeLimit; // time limit in seconds
int fCheckMiter; // check if miter outputs are non-zero
int fVerbose; // enables verbose output
+ int iOutFail; // index of the failed output
};
extern void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p );
extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars );
-static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; }
-static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); }
-static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); }
-static inline int Gia_Base2Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; }
-static inline int Gia_Base10Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; }
-static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; }
-static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
-static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
-static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
-static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
-static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
-static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); }
-static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
-static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; }
+static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; }
+//static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); }
+//static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); }
+static inline int Gia_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; }
+static inline float Gia_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; }
+static inline int Gia_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; }
+static inline int Gia_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; }
+static inline int Gia_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ); return r; }
+static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; }
+static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
+static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
+static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
+static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
+static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
+static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); }
+static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
+static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; }
+static inline int Gia_WordHasOnePair( unsigned uWord ) { return Gia_WordHasOneBit(uWord & (uWord>>1) & 0x55555555); }
static inline int Gia_WordCountOnes( unsigned uWord )
{
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
@@ -206,7 +215,7 @@ static inline int Gia_WordCountOnes( unsigned uWord )
uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
return (uWord & 0x0000FFFF) + (uWord>>16);
}
-static inline int Gia_WordFindFirstBit( unsigned uWord )
+static inline int Gia_WordFindFirstBit( unsigned uWord )
{
int i;
for ( i = 0; i < 32; i++ )
@@ -215,6 +224,46 @@ static inline int Gia_WordFindFirstBit( unsigned uWord )
return -1;
}
+static inline int Gia_ManTruthIsConst0( unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ if ( pIn[w] )
+ return 0;
+ return 1;
+}
+static inline int Gia_ManTruthIsConst1( unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ if ( pIn[w] != ~(unsigned)0 )
+ return 0;
+ return 1;
+}
+static inline void Gia_ManTruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = pIn[w];
+}
+static inline void Gia_ManTruthClear( unsigned * pOut, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = 0;
+}
+static inline void Gia_ManTruthFill( unsigned * pOut, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = ~(unsigned)0;
+}
+static inline void Gia_ManTruthNot( unsigned * pOut, unsigned * pIn, int nVars )
+{
+ int w;
+ for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- )
+ pOut[w] = ~pIn[w];
+}
static inline int Gia_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
static inline int Gia_Lit2Var( int Lit ) { return Lit >> 1; }
@@ -236,6 +285,7 @@ static inline int Gia_ManRegNum( Gia_Man_t * p ) { return p->nRegs
static inline int Gia_ManObjNum( Gia_Man_t * p ) { return p->nObjs; }
static inline int Gia_ManAndNum( Gia_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos) - 1; }
static inline int Gia_ManCandNum( Gia_Man_t * p ) { return Gia_ManCiNum(p) + Gia_ManAndNum(p); }
+static inline int Gia_ManConstrNum( Gia_Man_t * p ) { return p->nConstrs; }
static inline Gia_Obj_t * Gia_ManConst0( Gia_Man_t * p ) { return p->pObjs; }
static inline Gia_Obj_t * Gia_ManConst1( Gia_Man_t * p ) { return Gia_Not(Gia_ManConst0(p)); }
@@ -259,6 +309,8 @@ static inline int Gia_ManObjIsConst0( Gia_Man_t * p, Gia_Obj_t * pObj){
static inline int Gia_ObjId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pObjs <= pObj && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; }
static inline int Gia_ObjCioId( Gia_Obj_t * pObj ) { assert( Gia_ObjIsTerm(pObj) ); return pObj->iDiff1; }
static inline void Gia_ObjSetCioId( Gia_Obj_t * pObj, int v ) { assert( Gia_ObjIsTerm(pObj) ); pObj->iDiff1 = v; }
+static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; }
+static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; }
static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; }
static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); }
@@ -302,10 +354,14 @@ static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) {
static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, Gia_Regular(pObj)), Gia_IsComplement(pObj) ); }
static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); }
-static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; }
-static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; }
+static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntGetEntry(p->vLevels, Gia_ObjId(p,pObj)); }
+static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); }
+static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Vec_IntSetEntry(p->vLevels, Gia_ObjId(p,pObj), l); }
+static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); }
+static inline void Gia_ObjSetAndLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsAnd(pObj) ); Gia_ObjSetLevel( p, pObj, 1+ABC_MAX(Gia_ObjLevel(p,Gia_ObjFanin0(pObj)),Gia_ObjLevel(p,Gia_ObjFanin1(pObj))) ); }
static inline int Gia_ObjRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]; }
+static inline int Gia_ObjRefsId( Gia_Man_t * p, int Id ) { assert( p->pRefs); return p->pRefs[Id]; }
static inline int Gia_ObjRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]++; }
static inline int Gia_ObjRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return --p->pRefs[Gia_ObjId(p, pObj)]; }
static inline void Gia_ObjRefFanin0Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefInc(p, Gia_ObjFanin0(pObj)); }
@@ -313,37 +369,35 @@ static inline void Gia_ObjRefFanin1Inc(Gia_Man_t * p, Gia_Obj_t * pObj){
static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin0(pObj)); }
static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); }
-static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; }
-static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; }
-static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; }
-static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; }
-static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; }
-static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); }
-static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); }
-
-static inline void Gia_ManResetTravIdArray( Gia_Man_t * p )
-{
- ABC_FREE( p->pTravIds );
- p->nTravIdsAlloc = Gia_ManObjNum(p);
- p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc );
- p->nTravIds = 1;
-}
-static inline void Gia_ManIncrementTravIdArray( Gia_Man_t * p )
-{
- while ( p->nTravIdsAlloc < Gia_ManObjNum(p) )
- {
- p->nTravIdsAlloc *= 2;
- p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc );
- memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 );
- }
- p->nTravIds++;
-}
-static inline void Gia_ObjSetTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; }
-static inline void Gia_ObjSetTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; }
-static inline int Gia_ObjIsTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); }
-static inline int Gia_ObjIsTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
-static inline void Gia_ObjSetTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
-static inline int Gia_ObjIsTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
+static inline int Gia_ObjNodeRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]; }
+static inline int Gia_ObjNodeRefsId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]; }
+static inline int Gia_ObjNodeRefIncId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]++; }
+static inline int Gia_ObjNodeRefDecId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return --p->pNodeRefs[Id]; }
+static inline int Gia_ObjNodeRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]++; }
+static inline int Gia_ObjNodeRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return --p->pNodeRefs[Gia_ObjId(p, pObj)]; }
+
+static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; }
+static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; }
+static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); }
+static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
+static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
+static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
+
+static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); }
+static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); }
+static inline void Gia_ManTimeStop( Gia_Man_t * p ) { assert( p->vTiming != NULL ); Vec_FltFreeP(&p->vTiming); }
+static inline float Gia_ObjTimeArrival( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+0); }
+static inline float Gia_ObjTimeRequired( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+1); }
+static inline float Gia_ObjTimeSlack( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+2); }
+static inline float Gia_ObjTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeArrival( p, Gia_ObjId(p, pObj) ); }
+static inline float Gia_ObjTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeRequired( p, Gia_ObjId(p, pObj) ); }
+static inline float Gia_ObjTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeSlack( p, Gia_ObjId(p, pObj) ); }
+static inline void Gia_ObjSetTimeArrival( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+0, t ); }
+static inline void Gia_ObjSetTimeRequired( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+1, t ); }
+static inline void Gia_ObjSetTimeSlack( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+2, t ); }
+static inline void Gia_ObjSetTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeArrival( p, Gia_ObjId(p, pObj), t ); }
+static inline void Gia_ObjSetTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeRequired( p, Gia_ObjId(p, pObj), t ); }
+static inline void Gia_ObjSetTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeSlack( p, Gia_ObjId(p, pObj), t ); }
// AIG construction
extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
@@ -405,6 +459,12 @@ static inline int Gia_ManAppendCo( Gia_Man_t * p, int iLit0 )
Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj );
return Gia_ObjId( p, pObj ) << 1;
}
+static inline int Gia_ManAppendMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 )
+{
+ int iTemp0 = Gia_ManAppendAnd( p, Gia_LitNot(iCtrl), iData0 );
+ int iTemp1 = Gia_ManAppendAnd( p, iCtrl, iData1 );
+ return Gia_LitNotCond( Gia_ManAppendAnd( p, Gia_LitNot(iTemp0), Gia_LitNot(iTemp1) ), 1 );
+}
#define GIA_ZER 1
#define GIA_ONE 2
@@ -428,9 +488,10 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom
}
static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); }
-static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; }
-static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; }
-static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; }
+static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; }
+static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { assert( Num == GIA_VOID || Num < Id ); p->pReprs[Id].iRepr = Num; }
+static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; }
+static inline int Gia_ObjHasRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr != GIA_VOID; }
static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; }
static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; }
@@ -474,14 +535,17 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) )
-static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; }
-static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; }
-static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; }
+static inline int Gia_ObjIsLut( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; }
+static inline int Gia_ObjLutSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; }
+static inline int * Gia_ObjLutFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; }
+static inline int Gia_ObjLutFanin( Gia_Man_t * p, int Id, int i ) { return Gia_ObjLutFanins(p, Id)[i]; }
-#define Gia_ManForEachGate( p, i ) \
- for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else
-#define Gia_GateForEachFanin( p, i, iFan, k ) \
- for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ )
+#define Gia_ManForEachLut( p, i ) \
+ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsLut(p, i) ) {} else
+#define Gia_LutForEachFanin( p, i, iFan, k ) \
+ for ( k = 0; k < Gia_ObjLutSize(p,i) && ((iFan = Gia_ObjLutFanins(p,i)[k]),1); k++ )
+#define Gia_LutForEachFaninObj( p, i, pFanin, k ) \
+ for ( k = 0; k < Gia_ObjLutSize(p,i) && ((pFanin = Gia_ManObj(p, Gia_ObjLutFanins(p,i)[k])),1); k++ )
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@@ -525,9 +589,13 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re
////////////////////////////////////////////////////////////////////////
/*=== giaAiger.c ===========================================================*/
+extern int Gia_FileSize( char * pFileName );
extern Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck );
extern void Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact );
extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits );
+/*=== giaBidec.c ===========================================================*/
+extern unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited );
+extern Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose );
/*=== giaCsatOld.c ============================================================*/
extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
/*=== giaCsat.c ============================================================*/
@@ -542,14 +610,17 @@ extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVe
/*=== giaDfs.c ============================================================*/
extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp );
extern void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vNodes );
+extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes );
extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p );
+extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p );
/*=== giaDup.c ============================================================*/
extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop );
extern Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p );
-
extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState );
extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupSelf( Gia_Man_t * p );
@@ -562,32 +633,38 @@ extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj );
extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos );
+extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fDualOut, int fSeq, int fVerbose );
extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias );
/*=== giaEnable.c ==========================================================*/
extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose );
extern Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose );
extern Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p );
/*=== giaEquiv.c ==========================================================*/
+extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
extern void Gia_ManDeriveReprs( Gia_Man_t * p );
extern int Gia_ManEquivCountLits( Gia_Man_t * p );
+extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p );
extern int Gia_ManEquivCountClasses( Gia_Man_t * p );
extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter );
extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem );
extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose );
extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs );
extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose );
-extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose );
-extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut );
-extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs );
+extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose );
+extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut );
+extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs );
extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose );
extern void Gia_ManEquivImprove( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots );
+extern int Gia_ManCountChoiceNodes( Gia_Man_t * p );
+extern int Gia_ManCountChoices( Gia_Man_t * p );
/*=== giaFanout.c =========================================================*/
extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout );
@@ -611,12 +688,16 @@ extern int Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1,
extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 );
extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash );
extern void Gia_ManHashProfile( Gia_Man_t * p );
+extern int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 );
+/*=== giaIf.c ===========================================================*/
+extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
/*=== giaLogic.c ===========================================================*/
extern void Gia_ManTestDistance( Gia_Man_t * p );
extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars );
/*=== giaMan.c ===========================================================*/
extern Gia_Man_t * Gia_ManStart( int nObjsMax );
extern void Gia_ManStop( Gia_Man_t * p );
+extern void Gia_ManStopP( Gia_Man_t ** p );
extern void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch );
extern void Gia_ManPrintStatsShort( Gia_Man_t * p );
extern void Gia_ManPrintMiterStatus( Gia_Man_t * p );
@@ -624,8 +705,32 @@ extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
/*=== giaMap.c ===========================================================*/
extern void Gia_ManPrintMappingStats( Gia_Man_t * p );
+extern int Gia_ManLutFaninCount( Gia_Man_t * p );
+extern int Gia_ManLutSizeMax( Gia_Man_t * p );
+extern int Gia_ManLutNum( Gia_Man_t * p );
+extern int Gia_ManLutLevel( Gia_Man_t * p );
+/*=== giaMem.c ===========================================================*/
+extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
+extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
+extern char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p );
+extern void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry );
+extern void Gia_MmFixedRestart( Gia_MmFixed_t * p );
+extern int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p );
+extern int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p );
+extern Gia_MmFlex_t * Gia_MmFlexStart();
+extern void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose );
+extern char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes );
+extern void Gia_MmFlexRestart( Gia_MmFlex_t * p );
+extern int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p );
+extern Gia_MmStep_t * Gia_MmStepStart( int nSteps );
+extern void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose );
+extern char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes );
+extern void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes );
+extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p );
/*=== giaPat.c ===========================================================*/
extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit );
+/*=== giaReparam.c ===========================================================*/
+extern Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose );
/*=== giaRetime.c ===========================================================*/
extern Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose );
/*=== giaSat.c ============================================================*/
@@ -636,10 +741,16 @@ extern int Gia_ManCombMarkUsed( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose );
+/*=== giaShrink.c ===========================================================*/
+extern Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose );
/*=== giaSort.c ============================================================*/
extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize );
/*=== giaSim.c ============================================================*/
extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars );
+/*=== giaSpeedup.c ============================================================*/
+extern float Gia_ManDelayTraceLut( Gia_Man_t * p );
+extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose );
+extern Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose );
/*=== giaSwitch.c ============================================================*/
extern float Gia_ManEvaluateSwitching( Gia_Man_t * p );
extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
@@ -649,7 +760,9 @@ extern Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose );
extern unsigned Gia_ManRandom( int fReset );
extern void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop );
extern unsigned int Gia_PrimeCudd( unsigned int p );
+extern char * Gia_TimeStamp();
extern char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix );
+extern void Gia_ManIncrementTravId( Gia_Man_t * p );
extern void Gia_ManSetMark0( Gia_Man_t * p );
extern void Gia_ManCleanMark0( Gia_Man_t * p );
extern void Gia_ManCheckMark0( Gia_Man_t * p );
@@ -657,8 +770,12 @@ extern void Gia_ManSetMark1( Gia_Man_t * p );
extern void Gia_ManCleanMark1( Gia_Man_t * p );
extern void Gia_ManCheckMark1( Gia_Man_t * p );
extern void Gia_ManCleanValue( Gia_Man_t * p );
+extern void Gia_ManCleanLevels( Gia_Man_t * p, int Size );
+extern void Gia_ManCleanTruth( Gia_Man_t * p );
extern void Gia_ManFillValue( Gia_Man_t * p );
+extern void Gia_ObjSetPhase( Gia_Obj_t * pObj );
extern void Gia_ManSetPhase( Gia_Man_t * p );
+extern void Gia_ManSetPhase1( Gia_Man_t * p );
extern void Gia_ManCleanPhase( Gia_Man_t * p );
extern int Gia_ManLevelNum( Gia_Man_t * p );
extern void Gia_ManSetRefs( Gia_Man_t * p );
@@ -670,13 +787,18 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p );
extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode );
extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 );
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
-extern Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames );
-extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut );
-extern void Gia_ManPrintCounterExample( Gia_Cex_t * p );
+extern Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames );
+extern Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame );
+extern Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel );
+extern Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew );
+extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut );
+extern void Gia_ManPrintCounterExample( Abc_Cex_t * p );
extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode );
extern int Gia_ManHasChoices( Gia_Man_t * p );
-extern int Gia_ManHasDandling( Gia_Man_t * p );
-/*=== giaUtil.c ===========================================================*/
+extern int Gia_ManHasDangling( Gia_Man_t * p );
+extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p );
+extern void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj );
+/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit );
extern void Tas_ManStop( Tas_Man_t * p );
@@ -686,9 +808,11 @@ extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Ob
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
-#ifdef __cplusplus
-}
-#endif
+
+
+ABC_NAMESPACE_HEADER_END
+
+
#endif
diff --git a/src/aig/gia/giaAbs.c b/src/aig/gia/giaAbs.c
new file mode 100644
index 00000000..38e010f1
--- /dev/null
+++ b/src/aig/gia/giaAbs.c
@@ -0,0 +1,553 @@
+/**CFile****************************************************************
+
+ FileName [giaAbs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Counter-example-guided abstraction refinement.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "giaAbs.h"
+#include "saig.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars );
+extern Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars );
+extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p )
+{
+ memset( p, 0, sizeof(Gia_ParAbs_t) );
+ p->Algo = 0; // algorithm: CBA
+ p->nFramesMax = 10; // timeframes for PBA
+ p->nConfMax = 10000; // conflicts for PBA
+ p->fDynamic = 1; // dynamic unfolding for PBA
+ p->fConstr = 0; // use constraints
+ p->nFramesBmc = 250; // timeframes for BMC
+ p->nConfMaxBmc = 5000; // conflicts for BMC
+ p->nStableMax = 1000000; // the number of stable frames to quit
+ p->nRatio = 10; // ratio of flops to quit
+ p->nBobPar = 1000000; // the number of frames before trying to quit
+ p->fUseBdds = 0; // use BDDs to refine abstraction
+ p->fUseDprove = 0; // use 'dprove' to refine abstraction
+ p->fUseStart = 1; // use starting frame
+ p->fVerbose = 0; // verbose output
+ p->fVeryVerbose= 0; // printing additional information
+ p->Status = -1; // the problem status
+ p->nFramesDone = -1; // the number of rames covered
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flop list into flop map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops )
+{
+ Vec_Int_t * vFlopClasses;
+ int i, Entry;
+ vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) );
+ Vec_IntForEachEntry( vFlops, Entry, i )
+ Vec_IntWriteEntry( vFlopClasses, Entry, 1 );
+ return vFlopClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flop map into flop list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses )
+{
+ Vec_Int_t * vFlops;
+ int i, Entry;
+ vFlops = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vFlopClasses, Entry, i )
+ if ( Entry )
+ Vec_IntPush( vFlops, i );
+ return vFlops;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction on the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCexAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops )
+{
+ Gia_Man_t * pGia;
+ Aig_Man_t * pNew, * pTemp;
+ pNew = Gia_ManToAig( p, 0 );
+ pNew = Saig_ManDeriveAbstraction( pTemp = pNew, vFlops );
+ Aig_ManStop( pTemp );
+ pGia = Gia_ManFromAig( pNew );
+ pGia->vCiNumsOrig = pNew->vCiNumsOrig;
+ pNew->vCiNumsOrig = NULL;
+ Aig_ManStop( pNew );
+ return pGia;
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes abstracted flops for the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCexAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars )
+{
+ Vec_Int_t * vFlops;
+ Aig_Man_t * pNew;
+ pNew = Gia_ManToAig( p, 0 );
+ vFlops = Saig_ManCexAbstractionFlops( pNew, pPars );
+ p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
+ Aig_ManStop( pNew );
+ return vFlops;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes abstracted flops for the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManProofAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars )
+{
+ Vec_Int_t * vFlops;
+ Aig_Man_t * pNew;
+ pNew = Gia_ManToAig( p, 0 );
+ vFlops = Saig_ManProofAbstractionFlops( pNew, pPars );
+ p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
+ Aig_ManStop( pNew );
+ return vFlops;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts abstraction by computing latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCexAbstractionStart( Gia_Man_t * p, Gia_ParAbs_t * pPars )
+{
+ Vec_Int_t * vFlops;
+ if ( p->vFlopClasses != NULL )
+ {
+ printf( "Gia_ManCexAbstractionStart(): Abstraction latch map is present but will be rederived.\n" );
+ Vec_IntFreeP( &p->vFlopClasses );
+ }
+ vFlops = Gia_ManCexAbstractionFlops( p, pPars );
+ if ( vFlops )
+ {
+ p->vFlopClasses = Gia_ManFlops2Classes( p, vFlops );
+ Vec_IntFree( vFlops );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives abstraction using the latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCexAbstractionDerive( Gia_Man_t * pGia )
+{
+ Vec_Int_t * vFlops;
+ Gia_Man_t * pAbs = NULL;
+ if ( pGia->vFlopClasses == NULL )
+ {
+ printf( "Gia_ManCexAbstractionDerive(): Abstraction latch map is missing.\n" );
+ return NULL;
+ }
+ vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses );
+ pAbs = Gia_ManCexAbstraction( pGia, vFlops );
+ Vec_IntFree( vFlops );
+ return pAbs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines abstraction using the latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbose )
+{
+ Aig_Man_t * pNew;
+ Vec_Int_t * vFlops;
+ if ( pGia->vFlopClasses == NULL )
+ {
+ printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" );
+ return -1;
+ }
+ pNew = Gia_ManToAig( pGia, 0 );
+ vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses );
+ if ( !Saig_ManCexRefineStep( pNew, vFlops, pCex, fVerbose ) )
+ {
+ pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL;
+ Vec_IntFree( vFlops );
+ Aig_ManStop( pNew );
+ return 0;
+ }
+ Vec_IntFree( pGia->vFlopClasses );
+ pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops );
+ Vec_IntFree( vFlops );
+ Aig_ManStop( pNew );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts abstraction by computing latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManProofAbstractionStart( Gia_Man_t * pGia, Gia_ParAbs_t * pPars )
+{
+ Vec_Int_t * vFlops;
+ if ( pGia->vFlopClasses != NULL )
+ {
+ printf( "Gia_ManProofAbstractionStart(): Abstraction latch map is present but will be rederived.\n" );
+ Vec_IntFreeP( &pGia->vFlopClasses );
+ }
+ vFlops = Gia_ManProofAbstractionFlops( pGia, pPars );
+ if ( vFlops )
+ {
+ pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops );
+ Vec_IntFree( vFlops );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Read flop map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Gia_ManReadFile( char * pFileName )
+{
+ FILE * pFile;
+ Vec_Str_t * vStr;
+ int c;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ vStr = Vec_StrAlloc( 100 );
+ while ( (c = fgetc(pFile)) != EOF )
+ Vec_StrPush( vStr, (char)c );
+ Vec_StrPush( vStr, '\0' );
+ fclose( pFile );
+ return vStr;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read flop map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManReadBinary( char * pFileName, char * pToken )
+{
+ Vec_Int_t * vMap = NULL;
+ Vec_Str_t * vStr;
+ char * pStr;
+ int i, Length;
+ vStr = Gia_ManReadFile( pFileName );
+ if ( vStr == NULL )
+ return NULL;
+ pStr = Vec_StrArray( vStr );
+ pStr = strstr( pStr, pToken );
+ if ( pStr != NULL )
+ {
+ pStr += strlen( pToken );
+ vMap = Vec_IntAlloc( 100 );
+ Length = strlen( pStr );
+ for ( i = 0; i < Length; i++ )
+ {
+ if ( pStr[i] == '0' )
+ Vec_IntPush( vMap, 0 );
+ else if ( pStr[i] == '1' )
+ Vec_IntPush( vMap, 1 );
+ if ( ('a' <= pStr[i] && pStr[i] <= 'z') ||
+ ('A' <= pStr[i] && pStr[i] <= 'Z') )
+ break;
+ }
+ }
+ Vec_StrFree( vStr );
+ return vMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read flop map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManReadInteger( char * pFileName, char * pToken )
+{
+ int Result = -1;
+ Vec_Str_t * vStr;
+ char * pStr;
+ vStr = Gia_ManReadFile( pFileName );
+ if ( vStr == NULL )
+ return -1;
+ pStr = Vec_StrArray( vStr );
+ pStr = strstr( pStr, pToken );
+ if ( pStr != NULL )
+ Result = atoi( pStr + strlen(pToken) );
+ Vec_StrFree( vStr );
+ return Result;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Starts abstraction by computing latch map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCexAbstractionStartNew( Gia_Man_t * pGia, Gia_ParAbs_t * pPars )
+{
+ char BufTimeOut[100];
+ char BufTimeOutVT[100];
+ char Command[1000];
+ char * pFileNameIn = "cex_abstr_in_.aig";
+ char * pFileNameOut = "cex_abstr_out_.txt";
+ FILE * pFile;
+ Vec_Int_t * vCex;
+ int RetValue, clk;
+ if ( pGia->vFlopClasses != NULL )
+ {
+ printf( "Gia_ManCexAbstractionStartNew(): Abstraction latch map is present but will be rederived.\n" );
+ Vec_IntFreeP( &pGia->vFlopClasses );
+ }
+ Gia_WriteAiger( pGia, pFileNameIn, 0, 0 );
+ sprintf( BufTimeOut, "-timeout=%d", pPars->TimeOut );
+ sprintf( BufTimeOutVT, "-vt=%d", pPars->TimeOutVT );
+//ABC switch => cex_abstr switch
+//-cba => <input> <output>
+//-pba => ,bmc -pba-soft <input> <output>
+//-cba-then-pba => -pba-soft <input> <output>
+//-cba-with-pba => -pba <input> <output>
+ if ( pPars->Algo == 0 )
+ {
+ sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s",
+ pPars->fVerbose? "":"-quiet",
+ pPars->fVeryVerbose? "-sat-verbosity=1":"",
+ pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar,
+ pPars->TimeOut? BufTimeOut : "",
+ pPars->TimeOutVT? BufTimeOutVT : "",
+ pFileNameIn, pFileNameOut );
+ }
+ else if ( pPars->Algo == 1 )
+ {
+ sprintf( Command, "cex_abstr %s %s -depth=%d -confl=%d -bob=%d ,bmc -pba-soft %s %s %s %s",
+ pPars->fVerbose? "":"-quiet",
+ pPars->fVeryVerbose? "-sat-verbosity=1":"",
+ pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->nBobPar,
+ pPars->TimeOut? BufTimeOut : "",
+ pPars->TimeOutVT? BufTimeOutVT : "",
+ pFileNameIn, pFileNameOut );
+ }
+ else if ( pPars->Algo == 2 )
+ {
+ sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba-soft %s %s %s %s",
+ pPars->fVerbose? "":"-quiet",
+ pPars->fVeryVerbose? "-sat-verbosity=1":"",
+ pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar,
+ pPars->TimeOut? BufTimeOut : "",
+ pPars->TimeOutVT? BufTimeOutVT : "",
+ pFileNameIn, pFileNameOut );
+ }
+ else if ( pPars->Algo == 3 )
+ {
+ sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba %s %s %s %s",
+ pPars->fVerbose? "":"-quiet",
+ pPars->fVeryVerbose? "-sat-verbosity=1":"",
+ pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar,
+ pPars->TimeOut? BufTimeOut : "",
+ pPars->TimeOutVT? BufTimeOutVT : "",
+ pFileNameIn, pFileNameOut );
+ }
+ else
+ {
+ printf( "Unnknown option (algo=%d). CBA (algo=0) is assumed.\n", pPars->Algo );
+ sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s",
+ pPars->fVerbose? "":"-quiet",
+ pPars->fVeryVerbose? "-sat-verbosity=1":"",
+ pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar,
+ pPars->TimeOut? BufTimeOut : "",
+ pPars->TimeOutVT? BufTimeOutVT : "",
+ pFileNameIn, pFileNameOut );
+ }
+ // run the command
+ printf( "Executing command line \"%s\"\n", Command );
+ clk = clock();
+ RetValue = system( Command );
+ clk = clock() - clk;
+#ifdef WIN32
+ _unlink( pFileNameIn );
+#else
+ unlink( pFileNameIn );
+#endif
+ if ( RetValue == -1 )
+ {
+ fprintf( stdout, "Command \"%s\" did not succeed.\n", Command );
+ return;
+ }
+ // check that the input PostScript file is okay
+ if ( (pFile = fopen( pFileNameOut, "r" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileNameOut );
+ return;
+ }
+ fclose( pFile );
+ pPars->nFramesDone = Gia_ManReadInteger( pFileNameOut, "depth:" );
+ if ( pPars->nFramesDone == -1 )
+ printf( "Gia_ManCexAbstractionStartNew(): Cannot read the number of frames covered by BMC.\n" );
+ pGia->vFlopClasses = Gia_ManReadBinary( pFileNameOut, "abstraction:" );
+ vCex = Gia_ManReadBinary( pFileNameOut, "counter-example:" );
+ if ( vCex )
+ {
+ int nFrames = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) / Gia_ManPiNum(pGia);
+ int nRemain = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) % Gia_ManPiNum(pGia);
+ if ( nRemain != 0 )
+ {
+ printf( "Counter example has a wrong length.\n" );
+ }
+ else
+ {
+ printf( "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 );
+ Abc_PrintTime( 1, "Time", clk );
+ pGia->pCexSeq = Gia_ManDeriveCexFromArray( pGia, vCex, 0, nFrames-1 );
+ if ( !Gia_ManVerifyCounterExample( pGia, pGia->pCexSeq, 0 ) )
+ Abc_Print( 1, "Generated counter-example is INVALID.\n" );
+ pPars->Status = 0;
+ }
+ Vec_IntFreeP( &vCex );
+ }
+#ifdef WIN32
+ _unlink( pFileNameOut );
+#else
+ unlink( pFileNameOut );
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaAbs.h b/src/aig/gia/giaAbs.h
new file mode 100644
index 00000000..090d5dca
--- /dev/null
+++ b/src/aig/gia/giaAbs.h
@@ -0,0 +1,89 @@
+/**CFile****************************************************************
+
+ FileName [giaAbs.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaAbs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __GIA_ABS_H__
+#define __GIA_ABS_H__
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// abstraction parameters
+typedef struct Gia_ParAbs_t_ Gia_ParAbs_t;
+struct Gia_ParAbs_t_
+{
+ int Algo; // the algorithm to be used
+ int nFramesMax; // timeframes for PBA
+ int nConfMax; // conflicts for PBA
+ int fDynamic; // dynamic unfolding for PBA
+ int fConstr; // use constraints
+ int nFramesBmc; // timeframes for BMC
+ int nConfMaxBmc; // conflicts for BMC
+ int nStableMax; // the number of stable frames to quit
+ int nRatio; // ratio of flops to quit
+ int TimeOut; // approximate timeout in seconds
+ int TimeOutVT; // approximate timeout in seconds
+ int nBobPar; // Bob's parameter
+ int fUseBdds; // use BDDs to refine abstraction
+ int fUseDprove; // use 'dprove' to refine abstraction
+ int fUseStart; // use starting frame
+ int fVerbose; // verbose output
+ int fVeryVerbose; // printing additional information
+ int Status; // the problem status
+ int nFramesDone; // the number of frames covered
+};
+
+extern void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index fa9030c5..0e004f87 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -19,6 +19,12 @@
***********************************************************************/
#include "giaAig.h"
+#include "fra.h"
+#include "dch.h"
+#include "dar.h"
+
+ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -84,6 +90,7 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
// create the new manager
pNew = Gia_ManStart( Aig_ManObjNum(p) );
pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
// create room to store equivalences
if ( p->pEquivs )
pNew->pNexts = ABC_CALLOC( int, Aig_ManObjNum(p) );
@@ -122,6 +129,7 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p )
// create the new manager
pNew = Gia_ManStart( Aig_ManObjNum(p) );
pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
// create the PIs
Aig_ManCleanData( p );
Aig_ManForEachObj( p, pObj, i )
@@ -138,8 +146,6 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p )
assert( 0 );
}
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
- if ( pNew->pNexts )
- Gia_ManDeriveReprs( pNew );
return pNew;
}
@@ -162,6 +168,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p )
// create the new manager
pNew = Gia_ManStart( Aig_ManObjNum(p) );
pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
// create the PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->iData = 1;
@@ -178,7 +185,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p )
Aig_ManForEachPo( p, pObj, i )
Gia_ManFromAig_rec( pNew, p, Aig_ObjFanin0(pObj) );
Aig_ManForEachPo( p, pObj, i )
- Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
+ pObj->iData = Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
return pNew;
}
@@ -240,6 +247,7 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices )
// create the new manager
pNew = Aig_ManStart( Gia_ManAndNum(p) );
pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
// pNew->pSpec = Gia_UtilStrsav( p->pName );
// duplicate representation of choice nodes
if ( fChoices )
@@ -249,6 +257,10 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices )
ppNodes[0] = Aig_ManConst0(pNew);
Gia_ManForEachCi( p, pObj, i )
ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePi( pNew );
+ // transfer level
+ if ( p->vLevels )
+ Gia_ManForEachCi( p, pObj, i )
+ Aig_ObjSetLevel( ppNodes[Gia_ObjId(p, pObj)], Gia_ObjLevel(p, pObj) );
// add logic for the POs
Gia_ManForEachCo( p, pObj, i )
{
@@ -282,6 +294,7 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta )
// create the new manager
pNew = Aig_ManStart( Gia_ManAndNum(p) );
pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
// pNew->pSpec = Gia_UtilStrsav( p->pName );
// create the PIs
ppNodes = ABC_CALLOC( Aig_Obj_t *, Gia_ManObjNum(p) );
@@ -312,6 +325,48 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta )
SeeAlso []
***********************************************************************/
+Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p )
+{
+ Aig_Man_t * pNew;
+ Aig_Obj_t ** ppNodes;
+ Gia_Obj_t * pObj;
+ int i;
+ ppNodes = ABC_ALLOC( Aig_Obj_t *, Gia_ManObjNum(p) );
+ // create the new manager
+ pNew = Aig_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->nConstrs = p->nConstrs;
+ // create the PIs
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ ppNodes[i] = Aig_And( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)), Gia_ObjChild1Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) );
+ else if ( Gia_ObjIsCi(pObj) )
+ ppNodes[i] = Aig_ObjCreatePi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ ppNodes[i] = Aig_ObjCreatePo( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) );
+ else if ( Gia_ObjIsConst0(pObj) )
+ ppNodes[i] = Aig_ManConst0(pNew);
+ else
+ assert( 0 );
+ pObj->Value = Gia_Var2Lit( Aig_ObjId(Aig_Regular(ppNodes[i])), Aig_IsComplement(ppNodes[i]) );
+ }
+ Aig_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ ABC_FREE( ppNodes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit )
{
Aig_Man_t * pMan;
@@ -329,41 +384,69 @@ Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit )
Synopsis [Transfers representatives from pGia to pAig.]
- Description []
+ Description [Assumes that pGia was created from pAig.]
SideEffects []
SeeAlso []
***********************************************************************/
-void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia )
+void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia )
{
Aig_Obj_t * pObj;
Gia_Obj_t * pGiaObj, * pGiaRepr;
int i;
- assert( p->pReprs == NULL );
+ assert( pAig->pReprs == NULL );
assert( pGia->pReprs != NULL );
// move pointers from AIG to GIA
- Aig_ManForEachObj( p, pObj, i )
+ Aig_ManForEachObj( pAig, pObj, i )
{
assert( i == 0 || !Gia_LitIsCompl(pObj->iData) );
pGiaObj = Gia_ManObj( pGia, Gia_Lit2Var(pObj->iData) );
pGiaObj->Value = i;
}
// set the pointers to the nodes in AIG
- Aig_ManReprStart( p, Aig_ManObjNumMax(p) );
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
+ Gia_ManForEachObj( pGia, pGiaObj, i )
+ {
+ pGiaRepr = Gia_ObjReprObj( pGia, i );
+ if ( pGiaRepr == NULL )
+ continue;
+ Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, pGiaRepr->Value), Aig_ManObj(pAig, pGiaObj->Value) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers representatives from pGia to pAig.]
+
+ Description [Assumes that pAig was created from pGia.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia )
+{
+ Gia_Obj_t * pGiaObj, * pGiaRepr;
+ int i;
+ assert( pAig->pReprs == NULL );
+ assert( pGia->pReprs != NULL );
+ // set the pointers to the nodes in AIG
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
Gia_ManForEachObj( pGia, pGiaObj, i )
{
pGiaRepr = Gia_ObjReprObj( pGia, i );
if ( pGiaRepr == NULL )
continue;
- Aig_ObjCreateRepr( p, Aig_ManObj(p, pGiaRepr->Value), Aig_ManObj(p, pGiaObj->Value) );
+ Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, Gia_Lit2Var(pGiaRepr->Value)), Aig_ManObj(pAig, Gia_Lit2Var(pGiaObj->Value)) );
}
}
/**Function*************************************************************
- Synopsis [Applied DC2 to the GIA manager.]
+ Synopsis [Transfers representatives from pAig to pGia.]
Description []
@@ -372,21 +455,159 @@ void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p )
+void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia )
{
- extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose );
+ Gia_Obj_t * pObjGia;
+ Aig_Obj_t * pObjAig, * pReprAig;
+ int i;
+ assert( pAig->pReprs != NULL );
+ assert( pGia->pReprs == NULL );
+ assert( Gia_ManObjNum(pGia) - Gia_ManCoNum(pGia) == Aig_ManObjNum(pAig) - Aig_ManPoNum(pAig) );
+ pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pGia) );
+ for ( i = 0; i < Gia_ManObjNum(pGia); i++ )
+ Gia_ObjSetRepr( pGia, i, GIA_VOID );
+ Gia_ManForEachObj( pGia, pObjGia, i )
+ {
+// Abc_Print( 1, "%d -> %d %d\n", i, Gia_ObjValue(pObjGia), Gia_ObjValue(pObjGia)/2 );
+ if ( Gia_ObjIsCo(pObjGia) )
+ continue;
+ assert( i == 0 || !Gia_LitIsCompl(Gia_ObjValue(pObjGia)) );
+ pObjAig = Aig_ManObj( pAig, Gia_Lit2Var(Gia_ObjValue(pObjGia)) );
+ pObjAig->iData = i;
+ }
+ Aig_ManForEachObj( pAig, pObjAig, i )
+ {
+ if ( Aig_ObjIsPo(pObjAig) )
+ continue;
+ if ( pAig->pReprs[i] == NULL )
+ continue;
+ pReprAig = pAig->pReprs[i];
+ Gia_ObjSetRepr( pGia, pObjAig->iData, pReprAig->iData );
+ }
+ pGia->pNexts = Gia_ManDeriveNexts( pGia );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Applies DC2 to the GIA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose )
+{
+// extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose );
Gia_Man_t * pGia;
Aig_Man_t * pNew, * pTemp;
pNew = Gia_ManToAig( p, 0 );
- pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0, 0 );
+ pNew = Dar_ManCompress2( pTemp = pNew, 1, fUpdateLevel, 1, 0, fVerbose );
Aig_ManStop( pTemp );
pGia = Gia_ManFromAig( pNew );
Aig_ManStop( pNew );
return pGia;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
+{
+ Gia_Man_t * pGia;
+ Aig_Man_t * pNew;
+ pNew = Gia_ManToAig( p, 0 );
+ pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars );
+ pGia = Gia_ManFromAig( pNew );
+ Aig_ManStop( pNew );
+ return pGia;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes equivalences after structural sequential cleanup.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose )
+{
+ Aig_Man_t * pNew, * pTemp;
+ pNew = Gia_ManToAigSimple( p );
+ pTemp = Aig_ManScl( pNew, fConst, fEquiv, fVerbose );
+ Gia_ManReprFromAigRepr( pNew, p );
+ Aig_ManStop( pTemp );
+ Aig_ManStop( pNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solves SAT problem.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSolveSat( Gia_Man_t * p )
+{
+// extern int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fFlipBits, int fAndOuts, int fVerbose );
+ Aig_Man_t * pNew;
+ int RetValue, clk = clock();
+ pNew = Gia_ManToAig( p, 0 );
+ RetValue = Fra_FraigSat( pNew, 10000000, 0, 1, 1, 0 );
+ if ( RetValue == 0 )
+ {
+ Gia_Obj_t * pObj;
+ int i, * pInit = (int *)pNew->pData;
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->fMark0 = pInit[i];
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj));
+ Gia_ManForEachPo( p, pObj, i )
+ if ( pObj->fMark0 != 1 )
+ break;
+ if ( i != Gia_ManPoNum(p) )
+ Abc_Print( 1, "Counter-example verification has failed. " );
+// else
+// Abc_Print( 1, "Counter-example verification succeeded. " );
+ }
+/*
+ else if ( RetValue == 1 )
+ Abc_Print( 1, "The SAT problem is unsatisfiable. " );
+ else if ( RetValue == -1 )
+ Abc_Print( 1, "The SAT problem is undecided. " );
+ Abc_PrintTime( 1, "Time", clock() - clk );
+*/
+ Aig_ManStop( pNew );
+ return RetValue;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaAig.h b/src/aig/gia/giaAig.h
index 8cef5c7e..1c0a24d5 100644
--- a/src/aig/gia/giaAig.h
+++ b/src/aig/gia/giaAig.h
@@ -21,6 +21,7 @@
#ifndef __GIA_AIG_H__
#define __GIA_AIG_H__
+
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
@@ -28,6 +29,9 @@
#include "aig.h"
#include "gia.h"
+ABC_NAMESPACE_HEADER_START
+
+
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
@@ -51,12 +55,18 @@ extern Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p );
extern Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p );
extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices );
extern Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta );
-extern void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia );
-extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p );
-
-#ifdef __cplusplus
-}
-#endif
+extern Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p );
+extern void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia );
+extern void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia );
+extern void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia );
+extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose );
+extern Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars );
+extern Gia_Man_t * Gia_ManAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops );
+extern void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose );
+extern int Gia_ManSolveSat( Gia_Man_t * p );
+
+
+ABC_NAMESPACE_HEADER_END
#endif
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c
index 6c8ace8a..e201cbb9 100644
--- a/src/aig/gia/giaAiger.c
+++ b/src/aig/gia/giaAiger.c
@@ -21,6 +21,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -41,7 +44,7 @@
SeeAlso []
***********************************************************************/
-unsigned Gia_ReadAigerDecode( char ** ppPos )
+unsigned Gia_ReadAigerDecode( unsigned char ** ppPos )
{
unsigned x = 0, i = 0;
unsigned char ch;
@@ -61,7 +64,7 @@ unsigned Gia_ReadAigerDecode( char ** ppPos )
SeeAlso []
***********************************************************************/
-Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries )
+Vec_Int_t * Gia_WriteDecodeLiterals( unsigned char ** ppPos, int nEntries )
{
Vec_Int_t * vLits;
int Lit, LitPrev, Diff, i;
@@ -151,30 +154,6 @@ char * Gia_FileNameGeneric( char * FileName )
/**Function*************************************************************
- Synopsis [Returns the time stamp.]
-
- Description [The file should be closed.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-char * Gia_TimeStamp()
-{
- static char Buffer[100];
- char * TimeStamp;
- time_t ltime;
- // get the current time
- time( &ltime );
- TimeStamp = asctime( localtime( &ltime ) );
- TimeStamp[ strlen(TimeStamp) - 1 ] = 0;
- strcpy( Buffer, TimeStamp );
- return Buffer;
-}
-
-/**Function*************************************************************
-
Synopsis [Read integer from the string.]
Description []
@@ -203,7 +182,7 @@ int Gia_ReadInt( unsigned char * pPos )
SeeAlso []
***********************************************************************/
-unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev )
+unsigned Gia_ReadDiffValue( unsigned char ** ppPos, int iPrev )
{
int Item = Gia_ReadAigerDecode( ppPos );
if ( Item & 1 )
@@ -371,7 +350,8 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
Vec_Int_t * vNodes, * vDrivers;//, * vTerms;
int iObj, iNode0, iNode1;
int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits;
- char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType;
+ unsigned char * pDrivers, * pSymbols, * pCur;//, * pType;
+ char * pContents, * pName;
unsigned uLit0, uLit1, uLit;
// read the file into the buffer
@@ -391,17 +371,17 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
}
// read the file type
- pCur = pContents; while ( *pCur++ != ' ' );
+ pCur = (unsigned char *)pContents; while ( *pCur++ != ' ' );
// read the number of objects
- nTotal = atoi( pCur ); while ( *pCur++ != ' ' );
+ nTotal = atoi( (char *)pCur ); while ( *pCur++ != ' ' );
// read the number of inputs
- nInputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ nInputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' );
// read the number of latches
- nLatches = atoi( pCur ); while ( *pCur++ != ' ' );
+ nLatches = atoi( (char *)pCur ); while ( *pCur++ != ' ' );
// read the number of outputs
- nOutputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ nOutputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' );
// read the number of nodes
- nAnds = atoi( pCur ); while ( *pCur++ != '\n' );
+ nAnds = atoi( (char *)pCur ); while ( *pCur++ != '\n' );
// check the parameters
if ( nTotal != nInputs + nLatches + nAnds )
{
@@ -465,14 +445,14 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
pCur = pDrivers;
for ( i = 0; i < nLatches; i++ )
{
- uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' );
iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
Vec_IntPush( vDrivers, iNode0 );
}
// read the PO driver literals
for ( i = 0; i < nOutputs; i++ )
{
- uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' );
iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
Vec_IntPush( vDrivers, iNode0 );
}
@@ -509,7 +489,7 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
// check if there are other types of information to read
pCur = pSymbols;
- if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
+ if ( (char *)pCur + 1 < pContents + nFileSize && *pCur == 'c' )
{
pCur++;
if ( *pCur == 'e' )
@@ -539,17 +519,23 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) );
}
if ( *pCur == 's' )
- {
+ {
pCur++;
// read switching activity
pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) );
}
+ if ( *pCur == 'c' )
+ {
+ pCur++;
+ // read number of constraints
+ pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4;
+ }
if ( *pCur == 'n' )
{
pCur++;
// read model name
ABC_FREE( pNew->pName );
- pNew->pName = Gia_UtilStrsav( pCur );
+ pNew->pName = Gia_UtilStrsav( (char *)pCur );
}
}
@@ -710,7 +696,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize )
Gia_ClassForEachObj( p, iRepr, iNode )
nItems++;
}
- pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) );
// write constant class
iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) );
//printf( "\nRepr = %d ", 0 );
@@ -754,7 +740,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize )
SeeAlso []
***********************************************************************/
-int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis )
+int Gia_WriteDiffValue( unsigned char * pPos, int iPos, int iPrev, int iThis )
{
if ( iPrev < iThis )
return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) );
@@ -779,16 +765,16 @@ unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize )
assert( p->pMapping );
// count the number of entries to be written
nItems = 0;
- Gia_ManForEachGate( p, i )
- nItems += 2 + Gia_ObjGateSize( p, i );
- pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ Gia_ManForEachLut( p, i )
+ nItems += 2 + Gia_ObjLutSize( p, i );
+ pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) );
// write non-constant classes
iPrev = 0;
- Gia_ManForEachGate( p, i )
+ Gia_ManForEachLut( p, i )
{
-//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) );
- iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) );
- Gia_GateForEachFanin( p, i, iFan, k )
+//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFanin( p, i, iFan, k )
{
//printf( "Fan = %d ", iFan );
iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan );
@@ -915,8 +901,9 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
// write flop classes
if ( p->vFlopClasses )
{
- char Buffer[10];
+ unsigned char Buffer[10];
int nSize = 4*Gia_ManRegNum(p);
+ Gia_WriteInt( Buffer, nSize );
fprintf( pFile, "f" );
fwrite( Buffer, 1, 4, pFile );
fwrite( Vec_IntArray(p->vFlopClasses), 1, nSize, pFile );
@@ -933,7 +920,7 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
// write placement
if ( p->pPlacement )
{
- char Buffer[10];
+ unsigned char Buffer[10];
int nSize = 4*Gia_ManObjNum(p);
Gia_WriteInt( Buffer, nSize );
fprintf( pFile, "p" );
@@ -943,13 +930,21 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
// write flop classes
if ( p->pSwitching )
{
- char Buffer[10];
+ unsigned char Buffer[10];
int nSize = Gia_ManObjNum(p);
Gia_WriteInt( Buffer, nSize );
fprintf( pFile, "s" );
fwrite( Buffer, 1, 4, pFile );
fwrite( p->pSwitching, 1, nSize, pFile );
}
+ // write constraints
+ if ( p->nConstrs )
+ {
+ unsigned char Buffer[10];
+ Gia_WriteInt( Buffer, p->nConstrs );
+ fprintf( pFile, "c" );
+ fwrite( Buffer, 1, 4, pFile );
+ }
// write name
if ( p->pName )
fprintf( pFile, "n%s%c", p->pName, '\0' );
@@ -983,3 +978,5 @@ void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNu
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaAiger_new.c b/src/aig/gia/giaAiger_new.c
new file mode 100644
index 00000000..67981b26
--- /dev/null
+++ b/src/aig/gia/giaAiger_new.c
@@ -0,0 +1,1251 @@
+/**CFile****************************************************************
+
+ FileName [giaAiger.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Procedures to read/write binary AIGER format developed by
+ Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef ABC_UINT64_T word;
+
+static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Extracts one unsigned AIG edge from the input buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "unsigned decode (FILE * file)". ]
+
+ SideEffects [Updates the current reading position.]
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_ReadAigerDecode( char ** ppPos )
+{
+ unsigned x = 0, i = 0;
+ unsigned char ch;
+ while ((ch = *(*ppPos)++) & 0x80)
+ x |= (ch & 0x7f) << (7 * i++);
+ return x | (ch << (7 * i));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts one signed AIG edge from the input buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ReadAigerDecodeInt( char ** ppPos )
+{
+ unsigned Res;
+ Res = Gia_ReadAigerDecode( ppPos );
+ if ( Res & 1 )
+ return -((int)(Res >> 1));
+ return Res >> 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Decodes the encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries )
+{
+ Vec_Int_t * vLits;
+ int Lit, LitPrev, Diff, i;
+ vLits = Vec_IntAlloc( nEntries );
+ LitPrev = Gia_ReadAigerDecode( ppPos );
+ Vec_IntPush( vLits, LitPrev );
+ for ( i = 1; i < nEntries; i++ )
+ {
+// Diff = Lit - LitPrev;
+// Diff = (Lit < LitPrev)? -Diff : Diff;
+// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev);
+ Diff = Gia_ReadAigerDecode( ppPos );
+ Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1;
+ Lit = Diff + LitPrev;
+ Vec_IntPush( vLits, Lit );
+ LitPrev = Lit;
+ }
+ return vLits;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the file size.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_FixFileName( char * pFileName )
+{
+ char * pName;
+ for ( pName = pFileName; *pName; pName++ )
+ if ( *pName == '>' )
+ *pName = '\\';
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the file size.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_FileSize( char * pFileName )
+{
+ FILE * pFile;
+ int nFileSize;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Gia_FileSize(): The file is unavailable (absent or open).\n" );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ fclose( pFile );
+ return nFileSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_FileNameGeneric( char * FileName )
+{
+ char * pDot, * pRes;
+ pRes = Gia_UtilStrsav( FileName );
+ if ( (pDot = strrchr( pRes, '.' )) )
+ *pDot = 0;
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ReadInt( unsigned char * pPos )
+{
+ int i, Value = 0;
+ for ( i = 0; i < 4; i++ )
+ Value |= ((unsigned)(*pPos++)) << (i << 3);
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev )
+{
+ int Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ return iPrev + (Item >> 1);
+ return iPrev - (Item >> 1);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize )
+{
+ Gia_Rpr_t * pReprs;
+ unsigned char * pStop;
+ int i, Item, fProved, iRepr, iNode;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ pReprs = ABC_CALLOC( Gia_Rpr_t, nSize );
+ for ( i = 0; i < nSize; i++ )
+ pReprs[i].iRepr = GIA_VOID;
+ iRepr = iNode = 0;
+ while ( *ppPos < pStop )
+ {
+ Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ {
+ iRepr += (Item >> 1);
+ iNode = iRepr;
+//printf( "\nRepr = %d ", iRepr );
+ continue;
+ }
+ Item >>= 1;
+ fProved = (Item & 1);
+ Item >>= 1;
+ iNode += Item;
+ pReprs[iNode].fProved = fProved;
+ pReprs[iNode].iRepr = iRepr;
+ assert( iRepr < iNode );
+//printf( "Node = %d ", iNode );
+ }
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc )
+{
+ Gia_Rpr_t * pReprs;
+ unsigned char * pStop;
+ int i, k, iRepr, iNode, nMembers;
+ // find place to stop
+ pStop = *ppPos + nSize;
+ // prepare equivalence classes
+ pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc );
+ for ( i = 0; i < nAlloc; i++ )
+ pReprs[i].iRepr = GIA_VOID;
+ // skip the number of classes
+ Gia_ReadAigerDecode( ppPos );
+ // read classes
+ iRepr = 0;
+ while ( *ppPos < pStop )
+ {
+ nMembers = Gia_ReadAigerDecode( ppPos );
+ iRepr += Gia_ReadAigerDecode( ppPos );
+ iNode = iRepr;
+ for ( k = 1; k < nMembers; k++ )
+ {
+ iNode += Gia_ReadAigerDecode( ppPos );
+ pReprs[ Gia_Lit2Var(iNode) ].iRepr = Gia_Lit2Var(iRepr);
+ assert( Gia_Lit2Var(iRepr) < Gia_Lit2Var(iNode) );
+//if ( !iRepr )
+//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr );
+ }
+ }
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read flop classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize )
+{
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc/4 == nSize );
+ assert( Vec_IntSize(vClasses) == nSize );
+ memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize );
+ *ppPos += 4 * nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ReadMapping( unsigned char ** ppPos, int nSize )
+{
+ int * pMapping;
+ unsigned char * pStop;
+ int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ nAlloc = nSize + pStop - *ppPos;
+ pMapping = ABC_CALLOC( int, nAlloc );
+ while ( *ppPos < pStop )
+ {
+ k = iOffset;
+ pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos );
+ for ( j = 0; j <= nFanins; j++ )
+ pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode );
+ pMapping[iNode] = iOffset;
+ iOffset = k;
+ }
+ assert( iOffset <= nAlloc );
+ return pMapping;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read switching from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize )
+{
+ unsigned char * pSwitching;
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc == nSize );
+ pSwitching = ABC_ALLOC( unsigned char, nSize );
+ memcpy( pSwitching, *ppPos, nSize );
+ *ppPos += nSize;
+ return pSwitching;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read placement from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize )
+{
+ Gia_Plc_t * pPlacement;
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc/4 == nSize );
+ pPlacement = ABC_ALLOC( Gia_Plc_t, nSize );
+ memcpy( pPlacement, *ppPos, 4*nSize );
+ *ppPos += 4 * nSize;
+ return pPlacement;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads char and 64-bit int using little-endian style.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char Gia_ReadBlockHeader( char ** ppCur, word * pWord )
+{
+ int i;
+ char Char = *(*ppCur)++;
+ *pWord = 0;
+ for ( i = 0; i < 8; i++ )
+ {
+// printf( "%d\n", (unsigned char)(*(*ppCur)) );
+ *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3);
+ }
+ return Char;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
+{
+ FILE * pFile;
+ Gia_Man_t * pNew;
+ Vec_Int_t * vLits = NULL;
+ Vec_Int_t * vNodes, * vDrivers;//, * vTerms;
+ int iObj, iNode0, iNode1;
+ int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits;
+ char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType;
+ unsigned uLit0, uLit1, uLit;
+
+ // read the file into the buffer
+ Gia_FixFileName( pFileName );
+ nFileSize = Gia_FileSize( pFileName );
+ pFile = fopen( pFileName, "rb" );
+ pContents = ABC_ALLOC( char, nFileSize );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+
+ // check if the input file format is correct
+ if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') )
+ {
+ fprintf( stdout, "Wrong input file format.\n" );
+ free( pContents );
+ return NULL;
+ }
+
+ // read the file type
+ pCur = pContents; while ( *pCur++ != ' ' );
+ // read the number of objects
+ nTotal = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of inputs
+ nInputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of latches
+ nLatches = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of outputs
+ nOutputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of nodes
+ nAnds = atoi( pCur ); while ( *pCur++ != '\n' );
+ // check the parameters
+ if ( nTotal != nInputs + nLatches + nAnds )
+ {
+ fprintf( stdout, "The paramters are wrong.\n" );
+ return NULL;
+ }
+
+ // allocate the empty AIG
+ pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 );
+ pName = Gia_FileNameGeneric( pFileName );
+ pNew->pName = Gia_UtilStrsav( pName );
+// pNew->pSpec = Gia_UtilStrsav( pFileName );
+ ABC_FREE( pName );
+
+ // prepare the array of nodes
+ vNodes = Vec_IntAlloc( 1 + nTotal );
+ Vec_IntPush( vNodes, 0 );
+
+ // create the PIs
+ for ( i = 0; i < nInputs + nLatches; i++ )
+ {
+ iObj = Gia_ManAppendCi(pNew);
+ Vec_IntPush( vNodes, iObj );
+ }
+
+ // remember the beginning of latch/PO literals
+ pDrivers = pCur;
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ // scroll to the beginning of the binary data
+ for ( i = 0; i < nLatches + nOutputs; )
+ if ( *pCur++ == '\n' )
+ i++;
+ }
+ else // modified AIGER
+ {
+ vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs );
+ }
+
+ // create the AND gates
+ for ( i = 0; i < nAnds; i++ )
+ {
+ uLit = ((i + 1 + nInputs + nLatches) << 1);
+ uLit1 = uLit - Gia_ReadAigerDecode( &pCur );
+ uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur );
+// assert( uLit1 > uLit0 );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
+ iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
+ assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches );
+// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) );
+ Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) );
+ }
+
+ // remember the place where symbols begin
+ pSymbols = pCur;
+
+ // read the latch driver literals
+ vDrivers = Vec_IntAlloc( nLatches + nOutputs );
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ pCur = pDrivers;
+ for ( i = 0; i < nLatches; i++ )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ // read the PO driver literals
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+
+ }
+ else
+ {
+ // read the latch driver literals
+ for ( i = 0; i < nLatches; i++ )
+ {
+ uLit0 = Vec_IntEntry( vLits, i );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ // read the PO driver literals
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ uLit0 = Vec_IntEntry( vLits, i+nLatches );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ Vec_IntFree( vLits );
+ }
+
+ // create the POs
+ for ( i = 0; i < nOutputs; i++ )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) );
+ for ( i = 0; i < nLatches; i++ )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) );
+ Vec_IntFree( vDrivers );
+
+ // create the latches
+ Gia_ManSetRegNum( pNew, nLatches );
+
+ // check if there are other types of information to read
+ pCur = pSymbols;
+ if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
+ {
+ char Char;
+ word Size;
+ pCur++;
+
+ // read model name (old style)
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ ABC_FREE( pNew->pName );
+ pNew->pName = Gia_UtilStrsav( pCur );
+ pCur += (int)(strlen(pNew->pName) + 1);
+ }
+
+ Char = Gia_ReadBlockHeader( &pCur, &Size );
+ if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE )
+ {
+ while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) )
+ {
+ switch (Char)
+ {
+ case 'N':
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = ABC_ALLOC( char, (int)Size + 1 );
+ strncpy( pNew->pName, pCur, (int)Size );
+ pNew->pName[(int)Size] = '\0';
+ pCur += (int)Size;
+ break;
+ case '=':
+ // read equivalence classes
+ pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ break;
+ case 'c':
+ // read number of constraints
+ pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4;
+ break;
+ default:
+ printf( "Unrecognized data.\n" );
+ break;
+ }
+ }
+ }
+ else
+ {
+ printf( "Extended AIGER reader: Internal signature does not match.\n" );
+ }
+
+/*
+ if ( *pCur == 'e' )
+ {
+ pCur++;
+ // read equivalence classes
+ pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ }
+ if ( *pCur == 'f' )
+ {
+ pCur++;
+ // read flop classes
+ pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
+ Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) );
+ }
+ if ( *pCur == 'm' )
+ {
+ pCur++;
+ // read mapping
+ pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 'p' )
+ {
+ pCur++;
+ // read placement
+ pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 's' )
+ {
+ pCur++;
+ // read switching activity
+ pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 'c' )
+ {
+ pCur++;
+ // read number of constraints
+ pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4;
+ }
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = Gia_UtilStrsav( pCur );
+ }
+*/
+ }
+
+ // skipping the comments
+ ABC_FREE( pContents );
+ Vec_IntFree( vNodes );
+/*
+ // check the result
+ if ( fCheck && !Gia_ManCheck( pNew ) )
+ {
+ printf( "Gia_ReadAiger: The network check has failed.\n" );
+ Gia_ManStop( pNew );
+ return NULL;
+ }
+*/
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds one unsigned AIG edge to the output buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "void encode (FILE * file, unsigned x)" ]
+
+ SideEffects [Returns the current writing position.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+ pBuffer[Pos++] = ch;
+ x >>= 7;
+ }
+ ch = x;
+ pBuffer[Pos++] = ch;
+ return Pos;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one signed int to the output buffer.]
+
+ Description []
+
+ SideEffects [Returns the current writing position.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x )
+{
+ if ( x >= 0 )
+ return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) );
+ return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the array of literals to be written.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p )
+{
+ Vec_Int_t * vLits;
+ Gia_Obj_t * pObj;
+ int i;
+ vLits = Vec_IntAlloc( Gia_ManPoNum(p) );
+ Gia_ManForEachRi( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
+ return vLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the binary encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits )
+{
+ Vec_Str_t * vBinary;
+ int Pos = 0, Lit, LitPrev, Diff, i;
+ vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) );
+ LitPrev = Vec_IntEntry( vLits, 0 );
+ Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev );
+ Vec_IntForEachEntryStart( vLits, Lit, i, 1 )
+ {
+ Diff = Lit - LitPrev;
+ Diff = (Lit < LitPrev)? -Diff : Diff;
+ Diff = (Diff << 1) | (int)(Lit < LitPrev);
+ Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff );
+ LitPrev = Lit;
+ if ( Pos + 10 > vBinary->nCap )
+ Vec_StrGrow( vBinary, vBinary->nCap+1 );
+ }
+ vBinary->nSize = Pos;
+/*
+ // verify
+ {
+ extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries );
+ char * pPos = Vec_StrArray( vBinary );
+ Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) );
+ for ( i = 0; i < Vec_IntSize(vLits); i++ )
+ {
+ int Entry1 = Vec_IntEntry(vLits,i);
+ int Entry2 = Vec_IntEntry(vTemp,i);
+ assert( Entry1 == Entry2 );
+ }
+ Vec_IntFree( vTemp );
+ }
+*/
+ return vBinary;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteInt( char * pBuffer, int Value )
+{
+ int i;
+ for ( i = 0; i < 4; i++ )
+ pBuffer[i] = (char)(0xff & (Value >> (i<<3)));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize )
+{
+ unsigned char * pBuffer;
+ int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos;
+ assert( p->pReprs && p->pNexts );
+ // count the number of entries to be written
+ nItems = 0;
+ for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ )
+ {
+ nItems += Gia_ObjIsConst( p, iRepr );
+ if ( !Gia_ObjIsHead(p, iRepr) )
+ continue;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nItems++;
+ }
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write constant class
+ iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) );
+ iPrevNode = 0;
+ for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ )
+ if ( Gia_ObjIsConst(p, iNode) )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ // write non-constant classes
+ iPrevRepr = 0;
+ Gia_ManForEachClass( p, iRepr )
+ {
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) );
+ iPrevRepr = iPrevNode = iRepr;
+ Gia_ClassForEachObj1( p, iRepr, iNode )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ }
+ Gia_WriteInt( pBuffer, iPos );
+ *pEquivSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize )
+{
+ unsigned char * pBuffer;
+ int k, iNode, iRepr, iPrevLit, iNodeLit, iPrevReprLit, iReprLit;
+ int nItems, iPos, nClasses, nMembers;
+ assert( p->pReprs && p->pNexts );
+ Gia_ManSetPhase(p);
+ // count the number of entries to be written
+ nItems = 0;
+ nMembers = 0;
+ nClasses = 0;
+ for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ )
+ {
+ nItems += Gia_ObjIsConst( p, iRepr );
+ nMembers += Gia_ObjIsConst( p, iRepr );
+ if ( !Gia_ObjIsHead(p, iRepr) )
+ continue;
+ nClasses++;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nItems++;
+ }
+ nClasses += (nMembers > 0);
+ // allocate place for data
+ pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 );
+ // write the number of classes
+ iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses );
+ // write constant class
+ if ( nMembers )
+ {
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) );
+ iPrevLit = Gia_Var2Lit(0,0);
+ k = 1;
+ for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ )
+ if ( Gia_ObjIsConst(p, iNode) )
+ {
+ iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit );
+ iPrevLit = iNodeLit;
+//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 );
+ }
+ }
+ // write non-constant classes
+ iPrevReprLit = 0;
+ Gia_ManForEachClass( p, iRepr )
+ {
+ // write number of members
+ nMembers = 0;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nMembers++;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers );
+ // write representative
+ iReprLit = Gia_Var2Lit( iRepr, Gia_ObjPhase(Gia_ManObj(p, iRepr)) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, iReprLit - iPrevReprLit );
+ iPrevReprLit = iReprLit;
+ // write members
+ iPrevLit = iReprLit;
+ Gia_ClassForEachObj1( p, iRepr, iNode )
+ {
+ iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit );
+ iPrevLit = iNodeLit;
+//printf( "Writing equiv %d -> %d\n", iNode, iRepr );
+ }
+ }
+ *pEquivSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis )
+{
+ if ( iPrev < iThis )
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) );
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize )
+{
+ unsigned char * pBuffer;
+ int i, k, iPrev, iFan, nItems, iPos = 4;
+ assert( p->pMapping );
+ // count the number of entries to be written
+ nItems = 0;
+ Gia_ManForEachLut( p, i )
+ nItems += 2 + Gia_ObjLutSize( p, i );
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write non-constant classes
+ iPrev = 0;
+ Gia_ManForEachLut( p, i )
+ {
+//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+//printf( "Fan = %d ", iFan );
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan );
+ iPrev = iFan;
+ }
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i );
+ iPrev = i;
+//printf( "Node = %d ", i );
+ }
+//printf( "\n" );
+ Gia_WriteInt( pBuffer, iPos );
+ *pMapSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes char and 64-bit int using little-endian style.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word )
+{
+ int i;
+ fprintf( pFile, "%c", Char );
+ for ( i = 0; i < 8; i++ )
+ fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteIntF( FILE * pFile, int Value )
+{
+ int i;
+ for ( i = 0; i < 4; i++ )
+ fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact )
+{
+ FILE * pFile;
+ Gia_Man_t * p;
+ Gia_Obj_t * pObj;
+ int i, nBufferSize, Pos;
+ unsigned char * pBuffer;
+ unsigned uLit0, uLit1, uLit;
+
+ if ( Gia_ManCoNum(pInit) == 0 )
+ {
+ printf( "AIG cannot be written because it has no POs.\n" );
+ return;
+ }
+
+ // start the output stream
+ pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // create normalized AIG
+ if ( !Gia_ManIsNormalized(pInit) )
+ {
+// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" );
+ p = Gia_ManDupNormalized( pInit );
+ }
+ else
+ p = pInit;
+
+ // write the header "M I L O A" where M = I + L + A
+ fprintf( pFile, "aig%s %u %u %u %u %u\n",
+ fCompact? "2" : "",
+ Gia_ManCiNum(p) + Gia_ManAndNum(p),
+ Gia_ManPiNum(p),
+ Gia_ManRegNum(p),
+ Gia_ManPoNum(p),
+ Gia_ManAndNum(p) );
+
+ if ( !fCompact )
+ {
+ // write latch drivers
+ Gia_ManForEachRi( p, pObj, i )
+ fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
+ // write PO drivers
+ Gia_ManForEachPo( p, pObj, i )
+ fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
+ }
+ else
+ {
+ Vec_Int_t * vLits = Gia_WriteAigerLiterals( p );
+ Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits );
+ fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile );
+ Vec_StrFree( vBinary );
+ Vec_IntFree( vLits );
+ }
+
+ // write the nodes into the buffer
+ Pos = 0;
+ nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge
+ pBuffer = ABC_ALLOC( unsigned char, nBufferSize );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ uLit = Gia_Var2Lit( i, 0 );
+ uLit0 = Gia_ObjFaninLit0( pObj, i );
+ uLit1 = Gia_ObjFaninLit1( pObj, i );
+ assert( uLit0 < uLit1 );
+ Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 );
+ Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 );
+ if ( Pos > nBufferSize - 10 )
+ {
+ printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" );
+ fclose( pFile );
+ if ( p != pInit )
+ Gia_ManStop( p );
+ return;
+ }
+ }
+ assert( Pos < nBufferSize );
+
+ // write the buffer
+ fwrite( pBuffer, 1, Pos, pFile );
+ ABC_FREE( pBuffer );
+
+ // write the comment
+ fprintf( pFile, "c" );
+ // write signature
+ Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE );
+ // write name
+ if ( p->pName )
+ {
+ Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) );
+ fwrite( pInit->pName, 1, strlen(pInit->pName), pFile );
+ }
+ // write equivalences
+ if ( p->pReprs && p->pNexts )
+ {
+ int nEquivSize;
+ unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize );
+ Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize );
+ fwrite( pEquivs, 1, nEquivSize, pFile );
+ ABC_FREE( pEquivs );
+ }
+/*
+ // write flop classes
+ if ( p->vFlopClasses )
+ {
+ Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) );
+ fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
+ }
+ // write mapping
+ if ( p->pMapping )
+ {
+ int nMapSize;
+ unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize );
+ Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize );
+ fwrite( pMaps, 1, nMapSize, pFile );
+ ABC_FREE( pMaps );
+ }
+ // write placement
+ if ( p->pPlacement )
+ {
+ Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) );
+ fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile );
+ }
+ // write switching activity
+ if ( p->pSwitching )
+ {
+ Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) );
+ fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile );
+ }
+ // write name
+ if ( p->pName )
+ fprintf( pFile, "n%s%c", p->pName, '\0' );
+*/
+ // write constraints
+ if ( p->nConstrs )
+ {
+ Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs );
+ Gia_WriteIntF( pFile, p->nConstrs );
+ }
+ // write the closing statement
+ Gia_WriteBlockHeader( pFile, '\0', (word)0 );
+ // write comment
+ fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
+ fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
+ fclose( pFile );
+ if ( p != pInit )
+ Gia_ManStop( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits )
+{
+ char Buffer[100];
+ sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum );
+ Gia_WriteAiger( p, Buffer, 0, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaAiger_old.c b/src/aig/gia/giaAiger_old.c
new file mode 100644
index 00000000..9a5ba5cd
--- /dev/null
+++ b/src/aig/gia/giaAiger_old.c
@@ -0,0 +1,1255 @@
+/**CFile****************************************************************
+
+ FileName [giaAiger.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Procedures to read/write binary AIGER format developed by
+ Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef ABC_UINT64_T word;
+
+static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Extracts one unsigned AIG edge from the input buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "unsigned decode (FILE * file)". ]
+
+ SideEffects [Updates the current reading position.]
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_ReadAigerDecode( char ** ppPos )
+{
+ unsigned x = 0, i = 0;
+ unsigned char ch;
+ while ((ch = *(*ppPos)++) & 0x80)
+ x |= (ch & 0x7f) << (7 * i++);
+ return x | (ch << (7 * i));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts one signed AIG edge from the input buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ReadAigerDecodeInt( char ** ppPos )
+{
+ unsigned Res;
+ Res = Gia_ReadAigerDecode( ppPos );
+ if ( Res & 1 )
+ return -((int)(Res >> 1));
+ return Res >> 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Decodes the encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries )
+{
+ Vec_Int_t * vLits;
+ int Lit, LitPrev, Diff, i;
+ vLits = Vec_IntAlloc( nEntries );
+ LitPrev = Gia_ReadAigerDecode( ppPos );
+ Vec_IntPush( vLits, LitPrev );
+ for ( i = 1; i < nEntries; i++ )
+ {
+// Diff = Lit - LitPrev;
+// Diff = (Lit < LitPrev)? -Diff : Diff;
+// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev);
+ Diff = Gia_ReadAigerDecode( ppPos );
+ Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1;
+ Lit = Diff + LitPrev;
+ Vec_IntPush( vLits, Lit );
+ LitPrev = Lit;
+ }
+ return vLits;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the file size.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_FixFileName( char * pFileName )
+{
+ char * pName;
+ for ( pName = pFileName; *pName; pName++ )
+ if ( *pName == '>' )
+ *pName = '\\';
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the file size.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_FileSize( char * pFileName )
+{
+ FILE * pFile;
+ int nFileSize;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Gia_FileSize(): The file is unavailable (absent or open).\n" );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ fclose( pFile );
+ return nFileSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_FileNameGeneric( char * FileName )
+{
+ char * pDot, * pRes;
+ pRes = Gia_UtilStrsav( FileName );
+ if ( (pDot = strrchr( pRes, '.' )) )
+ *pDot = 0;
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ReadInt( unsigned char * pPos )
+{
+ int i, Value = 0;
+ for ( i = 0; i < 4; i++ )
+ Value |= ((unsigned)(*pPos++)) << (i << 3);
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev )
+{
+ int Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ return iPrev + (Item >> 1);
+ return iPrev - (Item >> 1);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize )
+{
+ Gia_Rpr_t * pReprs;
+ unsigned char * pStop;
+ int i, Item, fProved, iRepr, iNode;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ pReprs = ABC_CALLOC( Gia_Rpr_t, nSize );
+ for ( i = 0; i < nSize; i++ )
+ pReprs[i].iRepr = GIA_VOID;
+ iRepr = iNode = 0;
+ while ( *ppPos < pStop )
+ {
+ Item = Gia_ReadAigerDecode( ppPos );
+ if ( Item & 1 )
+ {
+ iRepr += (Item >> 1);
+ iNode = iRepr;
+//printf( "\nRepr = %d ", iRepr );
+ continue;
+ }
+ Item >>= 1;
+ fProved = (Item & 1);
+ Item >>= 1;
+ iNode += Item;
+ pReprs[iNode].fProved = fProved;
+ pReprs[iNode].iRepr = iRepr;
+ assert( iRepr < iNode );
+//printf( "Node = %d ", iNode );
+ }
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc )
+{
+ Gia_Rpr_t * pReprs;
+ unsigned char * pStop;
+ int i, k, iRepr, iNode, nMembers;
+ // find place to stop
+ pStop = *ppPos + nSize;
+ // prepare equivalence classes
+ pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc );
+ for ( i = 0; i < nAlloc; i++ )
+ pReprs[i].iRepr = GIA_VOID;
+ // skip the number of classes
+ Gia_ReadAigerDecode( ppPos );
+ // read classes
+ iRepr = iNode = 0;
+ while ( *ppPos < pStop )
+ {
+ nMembers = Gia_ReadAigerDecode( ppPos );
+ iRepr += Gia_ReadAigerDecode( ppPos ) >> 1;
+ iNode = iRepr;
+ for ( k = 1; k < nMembers; k++ )
+ {
+ iNode += Gia_ReadAigerDecode( ppPos ) >> 1;
+ pReprs[ iNode ].iRepr = iRepr;
+ assert( iRepr < iNode );
+//if ( !iRepr )
+//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr );
+ }
+ }
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read flop classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize )
+{
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc/4 == nSize );
+ assert( Vec_IntSize(vClasses) == nSize );
+ memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize );
+ *ppPos += 4 * nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ReadMapping( unsigned char ** ppPos, int nSize )
+{
+ int * pMapping;
+ unsigned char * pStop;
+ int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize;
+ pStop = *ppPos;
+ pStop += Gia_ReadInt( *ppPos ); *ppPos += 4;
+ nAlloc = nSize + pStop - *ppPos;
+ pMapping = ABC_CALLOC( int, nAlloc );
+ while ( *ppPos < pStop )
+ {
+ k = iOffset;
+ pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos );
+ for ( j = 0; j <= nFanins; j++ )
+ pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode );
+ pMapping[iNode] = iOffset;
+ iOffset = k;
+ }
+ assert( iOffset <= nAlloc );
+ return pMapping;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read switching from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize )
+{
+ unsigned char * pSwitching;
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc == nSize );
+ pSwitching = ABC_ALLOC( unsigned char, nSize );
+ memcpy( pSwitching, *ppPos, nSize );
+ *ppPos += nSize;
+ return pSwitching;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read placement from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize )
+{
+ Gia_Plc_t * pPlacement;
+ int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4;
+ assert( nAlloc/4 == nSize );
+ pPlacement = ABC_ALLOC( Gia_Plc_t, nSize );
+ memcpy( pPlacement, *ppPos, 4*nSize );
+ *ppPos += 4 * nSize;
+ return pPlacement;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads char and 64-bit int using little-endian style.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char Gia_ReadBlockHeader( char ** ppCur, word * pWord )
+{
+ int i;
+ char Char = *(*ppCur)++;
+ *pWord = 0;
+ for ( i = 0; i < 8; i++ )
+ {
+// printf( "%d\n", (unsigned char)(*(*ppCur)) );
+ *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3);
+ }
+ return Char;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )
+{
+ FILE * pFile;
+ Gia_Man_t * pNew;
+ Vec_Int_t * vLits = NULL;
+ Vec_Int_t * vNodes, * vDrivers;//, * vTerms;
+ int iObj, iNode0, iNode1;
+ int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits;
+ char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType;
+ unsigned uLit0, uLit1, uLit;
+
+ // read the file into the buffer
+ Gia_FixFileName( pFileName );
+ nFileSize = Gia_FileSize( pFileName );
+ pFile = fopen( pFileName, "rb" );
+ pContents = ABC_ALLOC( char, nFileSize );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+
+ // check if the input file format is correct
+ if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') )
+ {
+ fprintf( stdout, "Wrong input file format.\n" );
+ free( pContents );
+ return NULL;
+ }
+
+ // read the file type
+ pCur = pContents; while ( *pCur++ != ' ' );
+ // read the number of objects
+ nTotal = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of inputs
+ nInputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of latches
+ nLatches = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of outputs
+ nOutputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of nodes
+ nAnds = atoi( pCur ); while ( *pCur++ != '\n' );
+ // check the parameters
+ if ( nTotal != nInputs + nLatches + nAnds )
+ {
+ fprintf( stdout, "The paramters are wrong.\n" );
+ return NULL;
+ }
+
+ // allocate the empty AIG
+ pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 );
+ pName = Gia_FileNameGeneric( pFileName );
+ pNew->pName = Gia_UtilStrsav( pName );
+// pNew->pSpec = Gia_UtilStrsav( pFileName );
+ ABC_FREE( pName );
+
+ // prepare the array of nodes
+ vNodes = Vec_IntAlloc( 1 + nTotal );
+ Vec_IntPush( vNodes, 0 );
+
+ // create the PIs
+ for ( i = 0; i < nInputs + nLatches; i++ )
+ {
+ iObj = Gia_ManAppendCi(pNew);
+ Vec_IntPush( vNodes, iObj );
+ }
+
+ // remember the beginning of latch/PO literals
+ pDrivers = pCur;
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ // scroll to the beginning of the binary data
+ for ( i = 0; i < nLatches + nOutputs; )
+ if ( *pCur++ == '\n' )
+ i++;
+ }
+ else // modified AIGER
+ {
+ vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs );
+ }
+
+ // create the AND gates
+ for ( i = 0; i < nAnds; i++ )
+ {
+ uLit = ((i + 1 + nInputs + nLatches) << 1);
+ uLit1 = uLit - Gia_ReadAigerDecode( &pCur );
+ uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur );
+// assert( uLit1 > uLit0 );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
+ iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
+ assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches );
+// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) );
+ Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) );
+ }
+
+ // remember the place where symbols begin
+ pSymbols = pCur;
+
+ // read the latch driver literals
+ vDrivers = Vec_IntAlloc( nLatches + nOutputs );
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ pCur = pDrivers;
+ for ( i = 0; i < nLatches; i++ )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ // read the PO driver literals
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+
+ }
+ else
+ {
+ // read the latch driver literals
+ for ( i = 0; i < nLatches; i++ )
+ {
+ uLit0 = Vec_IntEntry( vLits, i );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ // read the PO driver literals
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ uLit0 = Vec_IntEntry( vLits, i+nLatches );
+ iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Vec_IntPush( vDrivers, iNode0 );
+ }
+ Vec_IntFree( vLits );
+ }
+
+ // create the POs
+ for ( i = 0; i < nOutputs; i++ )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) );
+ for ( i = 0; i < nLatches; i++ )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) );
+ Vec_IntFree( vDrivers );
+
+ // create the latches
+ Gia_ManSetRegNum( pNew, nLatches );
+
+ // check if there are other types of information to read
+ pCur = pSymbols;
+ if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' )
+ {
+ char Char;
+ word Size;
+ pCur++;
+
+ // read model name (old style)
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ ABC_FREE( pNew->pName );
+ pNew->pName = Gia_UtilStrsav( pCur );
+ pCur += (int)(strlen(pNew->pName) + 1);
+ }
+
+ Char = Gia_ReadBlockHeader( &pCur, &Size );
+ if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE )
+ {
+ while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) )
+ {
+ switch (Char)
+ {
+ case 'N':
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = ABC_ALLOC( char, (int)Size + 1 );
+ strncpy( pNew->pName, pCur, (int)Size );
+ pNew->pName[(int)Size] = '\0';
+ pCur += (int)Size;
+ break;
+ case 'n':
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = Gia_UtilStrsav( pCur );
+ pCur += (int)(strlen(pNew->pName) + 1);
+ break;
+ case '=':
+ // read equivalence classes
+ pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ break;
+ case 'c':
+ // read number of constraints
+ pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4;
+ break;
+ default:
+ printf( "Unrecognized data.\n" );
+ break;
+ }
+ }
+ }
+ else
+ {
+ printf( "Extended AIGER reader: Internal signature does not match.\n" );
+ }
+
+/*
+ if ( *pCur == 'e' )
+ {
+ pCur++;
+ // read equivalence classes
+ pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+ }
+ if ( *pCur == 'f' )
+ {
+ pCur++;
+ // read flop classes
+ pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
+ Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) );
+ }
+ if ( *pCur == 'm' )
+ {
+ pCur++;
+ // read mapping
+ pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 'p' )
+ {
+ pCur++;
+ // read placement
+ pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 's' )
+ {
+ pCur++;
+ // read switching activity
+ pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) );
+ }
+ if ( *pCur == 'c' )
+ {
+ pCur++;
+ // read number of constraints
+ pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4;
+ }
+ if ( *pCur == 'n' )
+ {
+ pCur++;
+ // read model name
+ ABC_FREE( pNew->pName );
+ pNew->pName = Gia_UtilStrsav( pCur );
+ }
+*/
+ }
+
+ // skipping the comments
+ ABC_FREE( pContents );
+ Vec_IntFree( vNodes );
+/*
+ // check the result
+ if ( fCheck && !Gia_ManCheck( pNew ) )
+ {
+ printf( "Gia_ReadAiger: The network check has failed.\n" );
+ Gia_ManStop( pNew );
+ return NULL;
+ }
+*/
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds one unsigned AIG edge to the output buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "void encode (FILE * file, unsigned x)" ]
+
+ SideEffects [Returns the current writing position.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+ pBuffer[Pos++] = ch;
+ x >>= 7;
+ }
+ ch = x;
+ pBuffer[Pos++] = ch;
+ return Pos;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one signed int to the output buffer.]
+
+ Description []
+
+ SideEffects [Returns the current writing position.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x )
+{
+ if ( x >= 0 )
+ return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) );
+ return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the array of literals to be written.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p )
+{
+ Vec_Int_t * vLits;
+ Gia_Obj_t * pObj;
+ int i;
+ vLits = Vec_IntAlloc( Gia_ManPoNum(p) );
+ Gia_ManForEachRi( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
+ return vLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the binary encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits )
+{
+ Vec_Str_t * vBinary;
+ int Pos = 0, Lit, LitPrev, Diff, i;
+ vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) );
+ LitPrev = Vec_IntEntry( vLits, 0 );
+ Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev );
+ Vec_IntForEachEntryStart( vLits, Lit, i, 1 )
+ {
+ Diff = Lit - LitPrev;
+ Diff = (Lit < LitPrev)? -Diff : Diff;
+ Diff = (Diff << 1) | (int)(Lit < LitPrev);
+ Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff );
+ LitPrev = Lit;
+ if ( Pos + 10 > vBinary->nCap )
+ Vec_StrGrow( vBinary, vBinary->nCap+1 );
+ }
+ vBinary->nSize = Pos;
+/*
+ // verify
+ {
+ extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries );
+ char * pPos = Vec_StrArray( vBinary );
+ Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) );
+ for ( i = 0; i < Vec_IntSize(vLits); i++ )
+ {
+ int Entry1 = Vec_IntEntry(vLits,i);
+ int Entry2 = Vec_IntEntry(vTemp,i);
+ assert( Entry1 == Entry2 );
+ }
+ Vec_IntFree( vTemp );
+ }
+*/
+ return vBinary;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteInt( char * pBuffer, int Value )
+{
+ int i;
+ for ( i = 0; i < 4; i++ )
+ pBuffer[i] = (char)(0xff & (Value >> (i<<3)));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize )
+{
+ unsigned char * pBuffer;
+ int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos;
+ assert( p->pReprs && p->pNexts );
+ // count the number of entries to be written
+ nItems = 0;
+ for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ )
+ {
+ nItems += Gia_ObjIsConst( p, iRepr );
+ if ( !Gia_ObjIsHead(p, iRepr) )
+ continue;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nItems++;
+ }
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write constant class
+ iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) );
+ iPrevNode = 0;
+ for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ )
+ if ( Gia_ObjIsConst(p, iNode) )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ // write non-constant classes
+ iPrevRepr = 0;
+ Gia_ManForEachClass( p, iRepr )
+ {
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) );
+ iPrevRepr = iPrevNode = iRepr;
+ Gia_ClassForEachObj1( p, iRepr, iNode )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) );
+ iPrevNode = iNode;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) );
+ }
+ }
+ Gia_WriteInt( pBuffer, iPos );
+ *pEquivSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize )
+{
+ unsigned char * pBuffer;
+ int k, iRepr, iNode, iPrevRepr, iPrevNode, iLit;
+ int nItems, iPos, nClasses, nMembers;
+ assert( p->pReprs && p->pNexts );
+ Gia_ManSetPhase(p);
+ // count the number of entries to be written
+ nItems = 0;
+ nMembers = 0;
+ nClasses = 0;
+ for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ )
+ {
+ nItems += Gia_ObjIsConst( p, iRepr );
+ nMembers += Gia_ObjIsConst( p, iRepr );
+ if ( !Gia_ObjIsHead(p, iRepr) )
+ continue;
+ nClasses++;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nItems++;
+ }
+ nClasses += (nMembers > 0);
+ // allocate place for data
+ pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 );
+ // write the number of classes
+ iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses );
+ // write constant class
+ if ( nMembers )
+ {
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) );
+ iPrevNode = 0;
+ k = 1;
+ for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ )
+ if ( Gia_ObjIsConst(p, iNode) )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, 0) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit );
+ iPrevNode = iNode;
+//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 );
+ }
+ }
+ // write non-constant classes
+ iPrevRepr = 0;
+ Gia_ManForEachClass( p, iRepr )
+ {
+ // write number of members
+ nMembers = 0;
+ Gia_ClassForEachObj( p, iRepr, iNode )
+ nMembers++;
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers );
+ // write representatives
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 0) );
+ // write members
+ iPrevRepr = iPrevNode = iRepr;
+ Gia_ClassForEachObj1( p, iRepr, iNode )
+ {
+ iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, iRepr) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit );
+ iPrevNode = iNode;
+//printf( "Writing equiv %d -> %d\n", iNode, iRepr );
+ }
+ }
+ *pEquivSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads decoded value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis )
+{
+ if ( iPrev < iThis )
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) );
+ return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read equivalence classes from the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize )
+{
+ unsigned char * pBuffer;
+ int i, k, iPrev, iFan, nItems, iPos = 4;
+ assert( p->pMapping );
+ // count the number of entries to be written
+ nItems = 0;
+ Gia_ManForEachLut( p, i )
+ nItems += 2 + Gia_ObjLutSize( p, i );
+ pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) );
+ // write non-constant classes
+ iPrev = 0;
+ Gia_ManForEachLut( p, i )
+ {
+//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) );
+ iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+//printf( "Fan = %d ", iFan );
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan );
+ iPrev = iFan;
+ }
+ iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i );
+ iPrev = i;
+//printf( "Node = %d ", i );
+ }
+//printf( "\n" );
+ Gia_WriteInt( pBuffer, iPos );
+ *pMapSize = iPos;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes char and 64-bit int using little-endian style.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word )
+{
+ int i;
+ fprintf( pFile, "%c", Char );
+ for ( i = 0; i < 8; i++ )
+ fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write integer into the string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteIntF( FILE * pFile, int Value )
+{
+ int i;
+ for ( i = 0; i < 4; i++ )
+ fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact )
+{
+ FILE * pFile;
+ Gia_Man_t * p;
+ Gia_Obj_t * pObj;
+ int i, nBufferSize, Pos;
+ unsigned char * pBuffer;
+ unsigned uLit0, uLit1, uLit;
+
+ if ( Gia_ManCoNum(pInit) == 0 )
+ {
+ printf( "AIG cannot be written because it has no POs.\n" );
+ return;
+ }
+
+ // start the output stream
+ pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // create normalized AIG
+ if ( !Gia_ManIsNormalized(pInit) )
+ {
+// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" );
+ p = Gia_ManDupNormalized( pInit );
+ }
+ else
+ p = pInit;
+
+ // write the header "M I L O A" where M = I + L + A
+ fprintf( pFile, "aig%s %u %u %u %u %u\n",
+ fCompact? "2" : "",
+ Gia_ManCiNum(p) + Gia_ManAndNum(p),
+ Gia_ManPiNum(p),
+ Gia_ManRegNum(p),
+ Gia_ManPoNum(p),
+ Gia_ManAndNum(p) );
+
+ if ( !fCompact )
+ {
+ // write latch drivers
+ Gia_ManForEachRi( p, pObj, i )
+ fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
+ // write PO drivers
+ Gia_ManForEachPo( p, pObj, i )
+ fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
+ }
+ else
+ {
+ Vec_Int_t * vLits = Gia_WriteAigerLiterals( p );
+ Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits );
+ fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile );
+ Vec_StrFree( vBinary );
+ Vec_IntFree( vLits );
+ }
+
+ // write the nodes into the buffer
+ Pos = 0;
+ nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge
+ pBuffer = ABC_ALLOC( unsigned char, nBufferSize );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ uLit = Gia_Var2Lit( i, 0 );
+ uLit0 = Gia_ObjFaninLit0( pObj, i );
+ uLit1 = Gia_ObjFaninLit1( pObj, i );
+ assert( uLit0 < uLit1 );
+ Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 );
+ Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 );
+ if ( Pos > nBufferSize - 10 )
+ {
+ printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" );
+ fclose( pFile );
+ if ( p != pInit )
+ Gia_ManStop( p );
+ return;
+ }
+ }
+ assert( Pos < nBufferSize );
+
+ // write the buffer
+ fwrite( pBuffer, 1, Pos, pFile );
+ ABC_FREE( pBuffer );
+
+ // write the comment
+ fprintf( pFile, "c" );
+ // write signature
+ Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE );
+ // write name
+ if ( p->pName )
+ {
+ Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) );
+ fwrite( pInit->pName, 1, strlen(pInit->pName), pFile );
+ }
+ // write equivalences
+ if ( p->pReprs && p->pNexts )
+ {
+ int nEquivSize;
+ unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize );
+ Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize );
+ fwrite( pEquivs, 1, nEquivSize, pFile );
+ ABC_FREE( pEquivs );
+ }
+ // write flop classes
+ if ( p->vFlopClasses )
+ {
+ Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) );
+ fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
+ }
+/*
+ // write mapping
+ if ( p->pMapping )
+ {
+ int nMapSize;
+ unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize );
+ Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize );
+ fwrite( pMaps, 1, nMapSize, pFile );
+ ABC_FREE( pMaps );
+ }
+ // write placement
+ if ( p->pPlacement )
+ {
+ Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) );
+ fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile );
+ }
+ // write switching activity
+ if ( p->pSwitching )
+ {
+ Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) );
+ fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile );
+ }
+ // write name
+ if ( p->pName )
+ fprintf( pFile, "n%s%c", p->pName, '\0' );
+*/
+ // write constraints
+ if ( p->nConstrs )
+ {
+ Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs );
+ Gia_WriteIntF( pFile, p->nConstrs );
+ }
+ // write the closing statement
+ Gia_WriteBlockHeader( pFile, '\0', (word)0 );
+ // write comment
+ fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
+ fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
+ fclose( pFile );
+ if ( p != pInit )
+ Gia_ManStop( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits )
+{
+ char Buffer[100];
+ sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum );
+ Gia_WriteAiger( p, Buffer, 0, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaBidec.c b/src/aig/gia/giaBidec.c
new file mode 100644
index 00000000..fc17b582
--- /dev/null
+++ b/src/aig/gia/giaBidec.c
@@ -0,0 +1,308 @@
+/**CFile****************************************************************
+
+ FileName [giaBidec.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Application of bi-decomposition to AIG minimization.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "bdc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Bdc_FunObjCopy( Bdc_Fun_t * pObj ) { return Gia_LitNotCond( Bdc_FuncCopyInt(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); }
+static inline int Bdc_FunFanin0Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin0(pObj) ); }
+static inline int Bdc_FunFanin1Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin1(pObj) ); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Gia_ManConvertAigToTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vTruth, int nWords, Vec_Int_t * vVisited )
+{
+ unsigned * pTruth, * pTruth0, * pTruth1;
+ int i;
+ assert( !Gia_IsComplement(pObj) );
+ if ( Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) != -1 )
+ return (unsigned *)Vec_IntEntryP( vTruth, nWords * Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) );
+ // compute the truth tables of the fanins
+ pTruth0 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin0(pObj), vTruth, nWords, vVisited );
+ pTruth1 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin1(pObj), vTruth, nWords, vVisited );
+ // get room for the truth table
+ pTruth = Vec_IntFetch( vTruth, nWords );
+ // create the truth table of the node
+ if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = pTruth0[i] & pTruth1[i];
+ else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = pTruth0[i] & ~pTruth1[i];
+ else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ~pTruth0[i] & pTruth1[i];
+ else // if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ~pTruth0[i] & ~pTruth1[i];
+ // save the visited node
+ Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) );
+ Vec_IntPush( vVisited, Gia_ObjId(p, pObj) );
+ return pTruth;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the node.]
+
+ Description [Assumes that the structural support is no more than 8 inputs.
+ Uses array vTruth to store temporary truth tables. The returned pointer should
+ be used immediately.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited )
+{
+ static unsigned uTruths[8][8] = { // elementary truth tables
+ { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
+ { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
+ { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
+ { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
+ { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
+ { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
+ };
+ Gia_Obj_t * pObj;
+ Vec_Ptr_t * vTtElems = NULL;
+ unsigned * pTruth;//, * pTruth2;
+ int i, nWords, nVars;
+ // get the number of variables and words
+ nVars = Vec_IntSize( vLeaves );
+ nWords = Gia_TruthWordNum( nVars );
+ // check the case of a constant
+ if ( Gia_ObjIsConst0( Gia_Regular(pRoot) ) )
+ {
+ Vec_IntClear( vTruth );
+ // get room for the truth table
+ pTruth = Vec_IntFetch( vTruth, nWords );
+ if ( !Gia_IsComplement(pRoot) )
+ Gia_ManTruthClear( pTruth, nVars );
+ else
+ Gia_ManTruthFill( pTruth, nVars );
+ return pTruth;
+ }
+ // if the number of variables is more than 8, allocate truth tables
+ if ( nVars > 8 )
+ vTtElems = Vec_PtrAllocTruthTables( nVars );
+ // assign elementary truth tables
+ Vec_IntClear( vTruth );
+ Vec_IntClear( vVisited );
+ Gia_ManForEachObjVec( vLeaves, p, pObj, i )
+ {
+ // get room for the truth table
+ pTruth = Vec_IntFetch( vTruth, nWords );
+ // assign elementary variable
+ if ( vTtElems )
+ Gia_ManTruthCopy( pTruth, (unsigned *)Vec_PtrEntry(vTtElems, i), nVars );
+ else
+ Gia_ManTruthCopy( pTruth, uTruths[i], nVars );
+ // save the visited node
+ Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) );
+ Vec_IntPush( vVisited, Gia_ObjId(p, pObj) );
+ }
+ if ( vTtElems )
+ Vec_PtrFree( vTtElems );
+ // clear the marks and compute the truth table
+// pTruth2 = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited );
+ pTruth = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited );
+ // copy the result
+// Gia_ManTruthCopy( pTruth, pTruth2, nVars );
+ if ( Gia_IsComplement(pRoot) )
+ Gia_ManTruthNot( pTruth, pTruth, nVars );
+ // clean truth tables
+ Gia_ManForEachObjVec( vVisited, p, pObj, i )
+ Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), -1 );
+ return pTruth;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resynthesizes nodes using bi-decomposition.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ObjPerformBidec( Bdc_Man_t * pManDec,
+ Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pRoot,
+ Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited )
+{
+ unsigned * pTruth;
+ Bdc_Fun_t * pFunc;
+ Gia_Obj_t * pFanin;
+ int i, iFan, nVars, nNodes;
+ // collect leaves of this gate
+ Vec_IntClear( vLeaves );
+ Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i )
+ Vec_IntPush( vLeaves, iFan );
+ nVars = Vec_IntSize( vLeaves );
+ assert( nVars < 16 );
+ // derive truth table
+ pTruth = Gia_ManConvertAigToTruth( p, pRoot, vLeaves, vTruth, vVisited );
+//Extra_PrintBinary( stdout, pTruth, (1<<nVars) ); printf( "\n" );
+ if ( Gia_ManTruthIsConst0(pTruth, nVars) )
+ {
+//printf( "Node %d is const0\n", Gia_ObjId(p, pRoot) );
+ return 0;
+ }
+ if ( Gia_ManTruthIsConst1(pTruth, nVars) )
+ {
+//printf( "Node %d is const1\n", Gia_ObjId(p, pRoot) );
+ return 1;
+ }
+ // decompose truth table
+ Bdc_ManDecompose( pManDec, pTruth, NULL, nVars, NULL, 1000 );
+/*
+if ( Bdc_ManNodeNum(pManDec) == 0 )
+ printf( "Node %d has 0 bidec nodes\n", Gia_ObjId(p, pRoot) );
+if ( Kit_TruthSupportSize(pTruth, nVars) != nVars )
+{
+ printf( "Node %d has %d fanins and %d supp size\n", Gia_ObjId(p, pRoot), nVars, Kit_TruthSupportSize(pTruth, nVars) );
+ Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i )
+ {
+ printf( "%d ", Kit_TruthVarInSupport(pTruth, nVars, i) );
+ Gia_ObjPrint( p, Gia_ManObj(p, iFan) );
+ }
+// Gia_ManPrintStats( p, 0 );
+}
+*/
+ // convert back into HOP
+ Bdc_FuncSetCopy( Bdc_ManFunc( pManDec, 0 ), Gia_ManConst1(pNew) );
+ Gia_ManForEachObjVec( vLeaves, p, pFanin, i )
+ Bdc_FuncSetCopyInt( Bdc_ManFunc( pManDec, i+1 ), Gia_ObjValue(pFanin) );
+ nNodes = Bdc_ManNodeNum( pManDec );
+ for ( i = nVars + 1; i < nNodes; i++ )
+ {
+ pFunc = Bdc_ManFunc( pManDec, i );
+ Bdc_FuncSetCopyInt( pFunc, Gia_ManHashAnd( pNew, Bdc_FunFanin0Copy(pFunc), Bdc_FunFanin1Copy(pFunc) ) );
+ }
+ return Bdc_FunObjCopy( Bdc_ManRoot(pManDec) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose )
+{
+ Bdc_Man_t * pManDec;
+ Bdc_Par_t Pars = {0}, * pPars = &Pars;
+ Vec_Int_t * vLeaves, * vTruth, * vVisited;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, clk = clock();
+ pPars->nVarsMax = Gia_ManLutSizeMax( p );
+ pPars->fVerbose = fVerbose;
+ if ( pPars->nVarsMax < 2 )
+ {
+ printf( "Resynthesis is not performed when nodes have less than 2 inputs.\n" );
+ return NULL;
+ }
+ if ( pPars->nVarsMax > 15 )
+ {
+ printf( "Resynthesis is not performed when nodes have more than 15 inputs.\n" );
+ return NULL;
+ }
+ vLeaves = Vec_IntAlloc( 0 );
+ vTruth = Vec_IntAlloc( (1<<16) );
+ vVisited = Vec_IntAlloc( 0 );
+ // clean the old manager
+ Gia_ManCleanTruth( p );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ // start the new manager
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+// Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) );
+ pManDec = Bdc_ManAlloc( pPars );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) ) // transfer the CI level (is it needed?)
+ pObj->Value = Gia_ManAppendCi( pNew );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ else if ( Gia_ObjIsLut(p, i) )
+ pObj->Value = Gia_ObjPerformBidec( pManDec, pNew, p, pObj, vLeaves, vTruth, vVisited );
+ }
+ Bdc_ManFree( pManDec );
+ // cleanup the AIG
+ Gia_ManHashStop( pNew );
+ // check the presence of dangling nodes
+ if ( Gia_ManHasDangling(pNew) )
+ {
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) )
+ printf( "Gia_ManPerformBidec() node count before and after: %6d and %6d.\n", Gia_ManAndNum(pNew), Gia_ManAndNum(pTemp) );
+ Gia_ManStop( pTemp );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vTruth );
+ Vec_IntFree( vVisited );
+ if ( fVerbose )
+ {
+// printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) );
+// ABC_PRT( "Total runtime", clock() - clk );
+ }
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c
index e3aca7df..1c5b05fe 100644
--- a/src/aig/gia/giaCSat.c
+++ b/src/aig/gia/giaCSat.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
//#define gia_assert(exp) ((void)0)
//#define gia_assert(exp) (assert(exp))
@@ -627,7 +630,7 @@ static inline void Cbs_ManDeriveReason( Cbs_Man_t * p, int Level )
assert( pQue->pData[pQue->iHead] != NULL );
pQue->iTail = k;
// clear the marks
- Vec_PtrForEachEntry( p->vTemp, pObj, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i )
pObj->fMark0 = 1;
}
@@ -1094,3 +1097,5 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCSatOld.c b/src/aig/gia/giaCSatOld.c
index bd8f061b..983081f0 100644
--- a/src/aig/gia/giaCSatOld.c
+++ b/src/aig/gia/giaCSatOld.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -796,3 +799,5 @@ Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStat
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCTas.c b/src/aig/gia/giaCTas.c
new file mode 100644
index 00000000..c6aa3fec
--- /dev/null
+++ b/src/aig/gia/giaCTas.c
@@ -0,0 +1,1788 @@
+/**CFile****************************************************************
+
+ FileName [giaCSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [A simple circuit-based solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+//#define gia_assert(exp) ((void)0)
+//#define gia_assert(exp) (assert(exp))
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Tas_Par_t_ Tas_Par_t;
+struct Tas_Par_t_
+{
+ // conflict limits
+ int nBTLimit; // limit on the number of conflicts
+ int nJustLimit; // limit on the size of justification queue
+ // current parameters
+ int nBTThis; // number of conflicts
+ int nBTThisNc; // number of conflicts
+ int nJustThis; // max size of the frontier
+ int nBTTotal; // total number of conflicts
+ int nJustTotal; // total size of the frontier
+ // activity
+ float VarDecay; // variable activity decay
+ int VarInc; // variable increment
+ // decision heuristics
+ int fUseActive; // use most active
+ int fUseHighest; // use node with the highest ID
+ int fUseLowest; // use node with the highest ID
+ int fUseMaxFF; // use node with the largest fanin fanout
+ // other
+ int fVerbose;
+};
+
+typedef struct Tas_Cls_t_ Tas_Cls_t;
+struct Tas_Cls_t_
+{
+ int iNext[2]; // beginning of the queue
+ int nLits; // the number of literals
+ int pLits[0]; // clause literals
+};
+
+typedef struct Tas_Sto_t_ Tas_Sto_t;
+struct Tas_Sto_t_
+{
+ int iCur; // current position
+ int nSize; // allocated size
+ int * pData; // clause information
+};
+
+typedef struct Tas_Que_t_ Tas_Que_t;
+struct Tas_Que_t_
+{
+ int iHead; // beginning of the queue
+ int iTail; // end of the queue
+ int nSize; // allocated size
+ Gia_Obj_t ** pData; // nodes stored in the queue
+};
+
+struct Tas_Man_t_
+{
+ Tas_Par_t Pars; // parameters
+ Gia_Man_t * pAig; // AIG manager
+ Tas_Que_t pProp; // propagation queue
+ Tas_Que_t pJust; // justification queue
+ Tas_Que_t pClauses; // clause queue
+ Gia_Obj_t ** pIter; // iterator through clause vars
+ Vec_Int_t * vLevReas; // levels and decisions
+ Vec_Int_t * vModel; // satisfying assignment
+ Vec_Ptr_t * vTemp; // temporary storage
+ // watched clauses
+ Tas_Sto_t pStore; // storage for watched clauses
+ int * pWatches; // watched lists for each literal
+ Vec_Int_t * vWatchLits; // lits whose watched are assigned
+ int nClauses; // the counter of clauses
+ // activity
+ float * pActivity; // variable activity
+ Vec_Int_t * vActiveVars; // variables with activity
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ // runtime stats
+ int timeSatUnsat; // unsat
+ int timeSatSat; // sat
+ int timeSatUndec; // undecided
+ int timeTotal; // total runtime
+};
+
+static inline int Tas_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; }
+static inline void Tas_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; }
+static inline void Tas_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; pVar->fMark1 = 0; pVar->Value = ~0; }
+static inline int Tas_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; }
+static inline void Tas_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; }
+static inline int Tas_VarIsJust( Gia_Obj_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); }
+static inline int Tas_VarFanin0Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); }
+static inline int Tas_VarFanin1Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); }
+static inline int Tas_VarToLit( Tas_Man_t * p, Gia_Obj_t * pObj ) { assert( Tas_VarIsAssigned(pObj) ); return Gia_Var2Lit( Gia_ObjId(p->pAig, pObj), !Tas_VarValue(pObj) ); }
+static inline int Tas_LitIsTrue( Gia_Obj_t * pObj, int Lit ) { assert( Tas_VarIsAssigned(pObj) ); return Tas_VarValue(pObj) != Gia_LitIsCompl(Lit); }
+
+static inline int Tas_ClsHandle( Tas_Man_t * p, Tas_Cls_t * pClause ) { return ((int *)pClause) - p->pStore.pData; }
+static inline Tas_Cls_t * Tas_ClsFromHandle( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pStore.pData + h); }
+
+static inline int Tas_VarDecLevel( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); }
+static inline Gia_Obj_t * Tas_VarReason0( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); }
+static inline Gia_Obj_t * Tas_VarReason1( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); }
+static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); }
+
+static inline int Tas_VarHasReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value+1) == 0 && Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) != 0; }
+static inline Tas_Cls_t * Tas_VarReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Tas_ClsFromHandle( p, Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) ); }
+
+#define Tas_QueForEachEntry( Que, pObj, i ) \
+ for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ )
+
+#define Tas_ClauseForEachVar( p, hClause, pObj ) \
+ for ( (p)->pIter = (p)->pClauses.pData + hClause; (pObj = *pIter); (p)->pIter++ )
+#define Tas_ClauseForEachVar1( p, hClause, pObj ) \
+ for ( (p)->pIter = (p)->pClauses.pData+hClause+1; (pObj = *pIter); (p)->pIter++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets default values of the parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Tas_SetDefaultParams( Tas_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(Tas_Par_t) );
+ pPars->nBTLimit = 2000; // limit on the number of conflicts
+ pPars->nJustLimit = 2000; // limit on the size of justification queue
+ pPars->fUseActive = 0; // use node with the highest activity
+ pPars->fUseHighest = 1; // use node with the highest ID
+ pPars->fUseLowest = 0; // use node with the lowest ID
+ pPars->fUseMaxFF = 0; // use node with the largest fanin fanout
+ pPars->fVerbose = 1; // print detailed statistics
+ pPars->VarDecay = (float)0.95; // variable decay
+ pPars->VarInc = 1.0; // variable increment
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit )
+{
+ Tas_Man_t * p;
+ p = ABC_CALLOC( Tas_Man_t, 1 );
+ Tas_SetDefaultParams( &p->Pars );
+ p->pAig = pAig;
+ p->Pars.nBTLimit = nBTLimit;
+ p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000;
+ p->pProp.pData = ABC_ALLOC( Gia_Obj_t *, p->pProp.nSize );
+ p->pJust.pData = ABC_ALLOC( Gia_Obj_t *, p->pJust.nSize );
+ p->pClauses.pData = ABC_ALLOC( Gia_Obj_t *, p->pClauses.nSize );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->vModel = Vec_IntAlloc( 1000 );
+ p->vLevReas = Vec_IntAlloc( 1000 );
+ p->vTemp = Vec_PtrAlloc( 1000 );
+ p->pStore.iCur = 16;
+ p->pStore.nSize = 10000;
+ p->pStore.pData = ABC_ALLOC( int, p->pStore.nSize );
+ p->pWatches = ABC_CALLOC( int, 2 * Gia_ManObjNum(pAig) );
+ p->vWatchLits = Vec_IntAlloc( 100 );
+ p->pActivity = ABC_CALLOC( float, Gia_ManObjNum(pAig) );
+ p->vActiveVars = Vec_IntAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Tas_ManStop( Tas_Man_t * p )
+{
+ Vec_IntFree( p->vActiveVars );
+ Vec_IntFree( p->vWatchLits );
+ Vec_IntFree( p->vLevReas );
+ Vec_IntFree( p->vModel );
+ Vec_PtrFree( p->vTemp );
+ ABC_FREE( p->pActivity );
+ ABC_FREE( p->pWatches );
+ ABC_FREE( p->pStore.pData );
+ ABC_FREE( p->pClauses.pData );
+ ABC_FREE( p->pProp.pData );
+ ABC_FREE( p->pJust.pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Tas_ReadModel( Tas_Man_t * p )
+{
+ return p->vModel;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the solver is out of limits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManCheckLimits( Tas_Man_t * p )
+{
+ return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves the satisfying assignment as an array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex )
+{
+ Gia_Obj_t * pVar;
+ int i;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+// printf( "\n" );
+ Tas_QueForEachEntry( p->pProp, pVar, i )
+ {
+ if ( Gia_ObjIsCi(pVar) )
+// Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Tas_VarValue(pVar)) );
+ Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pVar), !Tas_VarValue(pVar)) );
+/*
+ printf( "%5d(%d) = ", Gia_ObjId(p->pAig, pVar), Tas_VarValue(pVar) );
+ if ( Gia_ObjIsCi(pVar) )
+ printf( "pi %d\n", Gia_ObjCioId(pVar) );
+ else
+ {
+ printf( "%5d %d & ", Gia_ObjFaninId0p(p->pAig, pVar), Gia_ObjFaninC0(pVar) );
+ printf( "%5d %d ", Gia_ObjFaninId1p(p->pAig, pVar), Gia_ObjFaninC1(pVar) );
+ printf( "\n" );
+ }
+*/
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_QueIsEmpty( Tas_Que_t * p )
+{
+ return p->iHead == p->iTail;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_QuePush( Tas_Que_t * p, Gia_Obj_t * pObj )
+{
+ if ( p->iTail == p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( Gia_Obj_t *, p->pData, p->nSize );
+ }
+ p->pData[p->iTail++] = pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the object in the queue.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_QueHasNode( Tas_Que_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pTemp;
+ int i;
+ Tas_QueForEachEntry( *p, pTemp, i )
+ if ( pTemp == pObj )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_QueStore( Tas_Que_t * p, int * piHeadOld, int * piTailOld )
+{
+ int i;
+ *piHeadOld = p->iHead;
+ *piTailOld = p->iTail;
+ for ( i = *piHeadOld; i < *piTailOld; i++ )
+ Tas_QuePush( p, p->pData[i] );
+ p->iHead = *piTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_QueRestore( Tas_Que_t * p, int iHeadOld, int iTailOld )
+{
+ p->iHead = iHeadOld;
+ p->iTail = iTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalized the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_QueFinish( Tas_Que_t * p )
+{
+ int iHeadOld = p->iHead;
+ assert( p->iHead < p->iTail );
+ Tas_QuePush( p, NULL );
+ p->iHead = p->iTail;
+ return iHeadOld;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Max number of fanins fanouts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_VarFaninFanoutMax( Tas_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Count0, Count1;
+ assert( !Gia_IsComplement(pObj) );
+ assert( Gia_ObjIsAnd(pObj) );
+ Count0 = Gia_ObjRefs( p->pAig, Gia_ObjFanin0(pObj) );
+ Count1 = Gia_ObjRefs( p->pAig, Gia_ObjFanin1(pObj) );
+ return ABC_MAX( Count0, Count1 );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest activity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManFindActive( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ float BestCost = 0.0;
+ int i, ObjId;
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ ObjId = Gia_ObjId( p->pAig, pObj );
+ if ( pObjMax == NULL ||
+ p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] > BestCost ||
+ (p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin0(pObj)) )
+ {
+ pObjMax = Gia_ObjFanin0(pObj);
+ BestCost = p->pActivity[Gia_ObjFaninId0(pObj,ObjId)];
+ }
+ if ( p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] > BestCost ||
+ (p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin1(pObj)) )
+ {
+ pObjMax = Gia_ObjFanin1(pObj);
+ BestCost = p->pActivity[Gia_ObjFaninId1(pObj,ObjId)];
+ }
+ }
+ return pObjMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest activity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManDecideHighestFanin( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i, ObjId;
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ ObjId = Gia_ObjId( p->pAig, pObj );
+ if ( pObjMax == NULL || pObjMax < Gia_ObjFanin0(pObj) )
+ pObjMax = Gia_ObjFanin0(pObj);
+ if ( pObjMax < Gia_ObjFanin1(pObj) )
+ pObjMax = Gia_ObjFanin1(pObj);
+ }
+ return pObjMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManDecideHighest( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i;
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ {
+//printf( "%d %6.2f ", Gia_ObjId(p->pAig, pObj), p->pActivity[Gia_ObjId(p->pAig, pObj)] );
+ if ( pObjMax == NULL || pObjMax < pObj )
+ pObjMax = pObj;
+ }
+//printf( "\n" );
+ return pObjMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManDecideHighestA( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i;
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ {
+ if ( pObjMax == NULL ||
+ p->pActivity[Gia_ObjId(p->pAig, pObjMax)] < p->pActivity[Gia_ObjId(p->pAig, pObj)] )
+ pObjMax = pObj;
+ }
+ return pObjMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the lowest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManDecideLowest( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMin = NULL;
+ int i;
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ if ( pObjMin == NULL || pObjMin > pObj )
+ pObjMin = pObj;
+ return pObjMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the maximum number of fanin fanouts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Tas_ManDecideMaxFF( Tas_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i, iMaxFF = 0, iCurFF;
+ assert( p->pAig->pRefs != NULL );
+ Tas_QueForEachEntry( p->pJust, pObj, i )
+ {
+ iCurFF = Tas_VarFaninFanoutMax( p, pObj );
+ assert( iCurFF > 0 );
+ if ( iMaxFF < iCurFF )
+ {
+ iMaxFF = iCurFF;
+ pObjMax = pObj;
+ }
+ }
+ return pObjMax;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManCancelUntil( Tas_Man_t * p, int iBound )
+{
+ Gia_Obj_t * pVar;
+ int i;
+ assert( iBound <= p->pProp.iTail );
+ p->pProp.iHead = iBound;
+ Tas_QueForEachEntry( p->pProp, pVar, i )
+ Tas_VarUnassign( pVar );
+ p->pProp.iTail = iBound;
+ Vec_IntShrink( p->vLevReas, 3*iBound );
+}
+
+int s_Counter2 = 0;
+int s_Counter3 = 0;
+int s_Counter4 = 0;
+
+/**Function*************************************************************
+
+ Synopsis [Assigns the variables a value.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManAssign( Tas_Man_t * p, Gia_Obj_t * pObj, int Level, Gia_Obj_t * pRes0, Gia_Obj_t * pRes1 )
+{
+ Gia_Obj_t * pObjR = Gia_Regular(pObj);
+ assert( Gia_ObjIsCand(pObjR) );
+ assert( !Tas_VarIsAssigned(pObjR) );
+ Tas_VarAssign( pObjR );
+ Tas_VarSetValue( pObjR, !Gia_IsComplement(pObj) );
+ assert( pObjR->Value == ~0 );
+ pObjR->Value = p->pProp.iTail;
+ Tas_QuePush( &p->pProp, pObjR );
+ Vec_IntPush( p->vLevReas, Level );
+ if ( pRes0 == NULL && pRes1 != 0 ) // clause
+ {
+ Vec_IntPush( p->vLevReas, 0 );
+ Vec_IntPush( p->vLevReas, Tas_ClsHandle( p, (Tas_Cls_t *)pRes1 ) );
+ }
+ else
+ {
+ Vec_IntPush( p->vLevReas, pRes0 ? pRes0-pObjR : 0 );
+ Vec_IntPush( p->vLevReas, pRes1 ? pRes1-pObjR : 0 );
+ }
+ assert( Vec_IntSize(p->vLevReas) == 3 * p->pProp.iTail );
+ s_Counter2++;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns clause size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManClauseSize( Tas_Man_t * p, int hClause )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t ** pIter;
+ for ( pIter = pQue->pData + hClause; *pIter; pIter++ );
+ return pIter - pQue->pData - hClause ;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManPrintClause( Tas_Man_t * p, int Level, int hClause )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Tas_QueIsEmpty( pQue ) );
+ printf( "Level %2d : ", Level );
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ printf( "%d=%d(%d) ", Gia_ObjId(p->pAig, pObj), Tas_VarValue(pObj), Tas_VarDecLevel(p, pObj) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManPrintClauseNew( Tas_Man_t * p, int Level, int hClause )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Tas_QueIsEmpty( pQue ) );
+ printf( "Level %2d : ", Level );
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ printf( "%c%d ", Tas_VarValue(pObj)? '+':'-', Gia_ObjId(p->pAig, pObj) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManDeriveReason( Tas_Man_t * p, int Level )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj, * pReason;
+ int i, k, j, iLitLevel, iLitLevel2;//, Id;
+ assert( pQue->pData[pQue->iHead] == NULL );
+ assert( pQue->iHead + 1 < pQue->iTail );
+/*
+ for ( i = pQue->iHead + 1; i < pQue->iTail; i++ )
+ {
+ pObj = pQue->pData[i];
+ assert( pObj->fPhase == 0 );
+ }
+*/
+ // compact literals
+ Vec_PtrClear( p->vTemp );
+ for ( i = k = pQue->iHead + 1; i < pQue->iTail; i++ )
+ {
+ pObj = pQue->pData[i];
+ if ( pObj->fPhase ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fPhase = 1;
+ Vec_PtrPush( p->vTemp, pObj );
+ // bump activity
+// Id = Gia_ObjId( p->pAig, pObj );
+// if ( p->pActivity[Id] == 0.0 )
+// Vec_IntPush( p->vActiveVars, Id );
+// p->pActivity[Id] += p->Pars.VarInc;
+ // check decision level
+ iLitLevel = Tas_VarDecLevel( p, pObj );
+ if ( iLitLevel < Level )
+ {
+ pQue->pData[k++] = pObj;
+ continue;
+ }
+ assert( iLitLevel == Level );
+ if ( Tas_VarHasReasonCls( p, pObj ) )
+ {
+ Tas_Cls_t * pCls = Tas_VarReasonCls( p, pObj );
+ pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[0]) );
+ assert( pReason == pObj );
+ for ( j = 1; j < pCls->nLits; j++ )
+ {
+ pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[j]) );
+ iLitLevel2 = Tas_VarDecLevel( p, pReason );
+ assert( Tas_VarIsAssigned( pReason ) );
+ assert( !Tas_LitIsTrue( pReason, pCls->pLits[j] ) );
+ Tas_QuePush( pQue, pReason );
+ }
+ }
+ else
+ {
+ pReason = Tas_VarReason0( p, pObj );
+ if ( pReason == pObj ) // no reason
+ {
+ assert( pQue->pData[pQue->iHead] == NULL || Level == 0 );
+ if ( pQue->pData[pQue->iHead] == NULL )
+ pQue->pData[pQue->iHead] = pObj;
+ else
+ Tas_QuePush( pQue, pObj );
+ continue;
+ }
+ Tas_QuePush( pQue, pReason );
+ pReason = Tas_VarReason1( p, pObj );
+ if ( pReason != pObj ) // second reason
+ Tas_QuePush( pQue, pReason );
+ }
+ }
+ assert( pQue->pData[pQue->iHead] != NULL );
+ if ( pQue->pData[pQue->iHead] == NULL )
+ printf( "Tas_ManDeriveReason(): Failed to derive the clause!!!\n" );
+ pQue->iTail = k;
+ // clear the marks
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i )
+ pObj->fPhase = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManAnalyze( Tas_Man_t * p, int Level, Gia_Obj_t * pVar, Gia_Obj_t * pFan0, Gia_Obj_t * pFan1 )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ assert( Tas_VarIsAssigned(pVar) );
+ assert( Tas_VarIsAssigned(pFan0) );
+ assert( pFan1 == NULL || Tas_VarIsAssigned(pFan1) );
+ assert( Tas_QueIsEmpty( pQue ) );
+ Tas_QuePush( pQue, NULL );
+ Tas_QuePush( pQue, pVar );
+ Tas_QuePush( pQue, pFan0 );
+ if ( pFan1 )
+ Tas_QuePush( pQue, pFan1 );
+ Tas_ManDeriveReason( p, Level );
+ return Tas_QueFinish( pQue );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs resolution of two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManResolve( Tas_Man_t * p, int Level, int hClause0, int hClause1 )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i, LevelMax = -1, LevelCur;
+ assert( pQue->pData[hClause0] != NULL );
+ assert( pQue->pData[hClause0] == pQue->pData[hClause1] );
+/*
+ for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ )
+ assert( pObj->fPhase == 0 );
+ for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ )
+ assert( pObj->fPhase == 0 );
+*/
+ assert( Tas_QueIsEmpty( pQue ) );
+ Tas_QuePush( pQue, NULL );
+ for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ )
+ {
+ if ( pObj->fPhase ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fPhase = 1;
+ Tas_QuePush( pQue, pObj );
+ LevelCur = Tas_VarDecLevel( p, pObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ )
+ {
+ if ( pObj->fPhase ) // unassigned - seen again
+ continue;
+ // assigned - seen first time
+ pObj->fPhase = 1;
+ Tas_QuePush( pQue, pObj );
+ LevelCur = Tas_VarDecLevel( p, pObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = pQue->iHead + 1; i < pQue->iTail; i++ )
+ pQue->pData[i]->fPhase = 0;
+ Tas_ManDeriveReason( p, LevelMax );
+ return Tas_QueFinish( pQue );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates clause of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Tas_Cls_t * Tas_ManAllocCls( Tas_Man_t * p, int nSize )
+{
+ Tas_Cls_t * pCls;
+ if ( p->pStore.iCur + nSize > p->pStore.nSize )
+ {
+ p->pStore.nSize *= 2;
+ p->pStore.pData = ABC_REALLOC( int, p->pStore.pData, p->pStore.nSize );
+ }
+ pCls = Tas_ClsFromHandle( p, p->pStore.iCur ); p->pStore.iCur += nSize;
+ memset( pCls, 0, sizeof(int) * nSize );
+ p->nClauses++;
+ return pCls;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one clause to the watcher list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Tas_ManWatchClause( Tas_Man_t * p, Tas_Cls_t * pClause, int Lit )
+{
+ assert( Gia_Lit2Var(Lit) < Gia_ManObjNum(p->pAig) );
+ assert( pClause->nLits >= 2 );
+ assert( pClause->pLits[0] == Lit || pClause->pLits[1] == Lit );
+ if ( pClause->pLits[0] == Lit )
+ pClause->iNext[0] = p->pWatches[Gia_LitNot(Lit)];
+ else
+ pClause->iNext[1] = p->pWatches[Gia_LitNot(Lit)];
+ if ( p->pWatches[Gia_LitNot(Lit)] == 0 )
+ Vec_IntPush( p->vWatchLits, Gia_LitNot(Lit) );
+ p->pWatches[Gia_LitNot(Lit)] = Tas_ClsHandle( p, pClause );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates clause of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Tas_Cls_t * Tas_ManCreateCls( Tas_Man_t * p, int hClause )
+{
+ Tas_Cls_t * pClause;
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i, nLits = 0;
+ assert( Tas_QueIsEmpty( pQue ) );
+ assert( pQue->pData[hClause] != NULL );
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ nLits++;
+ if ( nLits == 1 )
+ return NULL;
+ // create this clause
+ pClause = Tas_ManAllocCls( p, nLits + 3 );
+ pClause->nLits = nLits;
+ for ( i = hClause; (pObj = pQue->pData[i]); i++ )
+ {
+ assert( Tas_VarIsAssigned( pObj ) );
+ pClause->pLits[i-hClause] = Gia_LitNot( Tas_VarToLit(p, pObj) );
+ }
+ // add the clause as watched one
+ if ( nLits >= 2 )
+ {
+ Tas_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Tas_ManWatchClause( p, pClause, pClause->pLits[1] );
+ }
+ // increment activity
+// p->Pars.VarInc /= p->Pars.VarDecay;
+ return pClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates clause of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManCreateFromCls( Tas_Man_t * p, Tas_Cls_t * pCls, int Level )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Tas_QueIsEmpty( pQue ) );
+ Tas_QuePush( pQue, NULL );
+ for ( i = 0; i < pCls->nLits; i++ )
+ {
+ pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[i]) );
+ assert( Tas_VarIsAssigned(pObj) );
+ assert( !Tas_LitIsTrue( pObj, pCls->pLits[i] ) );
+ Tas_QuePush( pQue, pObj );
+ }
+ Tas_ManDeriveReason( p, Level );
+ return Tas_QueFinish( pQue );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManPropagateWatch( Tas_Man_t * p, int Level, int Lit )
+{
+ Gia_Obj_t * pObj;
+ Tas_Cls_t * pCur;
+ int * piPrev, iCur, iTemp;
+ int i, LitF = Gia_LitNot(Lit);
+ // iterate through the clauses
+ piPrev = p->pWatches + Lit;
+ for ( iCur = p->pWatches[Lit]; iCur; iCur = *piPrev )
+ {
+ pCur = Tas_ClsFromHandle( p, iCur );
+ // make sure the false literal is in the second literal of the clause
+ if ( pCur->pLits[0] == LitF )
+ {
+ pCur->pLits[0] = pCur->pLits[1];
+ pCur->pLits[1] = LitF;
+ iTemp = pCur->iNext[0];
+ pCur->iNext[0] = pCur->iNext[1];
+ pCur->iNext[1] = iTemp;
+ }
+ assert( pCur->pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+// if ( pCur->pLits[0] == p->pAssigns[Gia_Lit2Var(pCur->pLits[0])] )
+ pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) );
+ if ( Tas_VarIsAssigned(pObj) && Tas_LitIsTrue( pObj, pCur->pLits[0] ) )
+ {
+ piPrev = &pCur->iNext[1];
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < (int)pCur->nLits; i++ )
+ {
+ // skip the case when the literal is false
+// if ( Gia_LitNot(pCur->pLits[i]) == p->pAssigns[Gia_Lit2Var(pCur->pLits[i])] )
+ pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) );
+ if ( Tas_VarIsAssigned(pObj) && !Tas_LitIsTrue( pObj, pCur->pLits[i] ) )
+ continue;
+ // the literal is either true or unassigned - watch it
+ pCur->pLits[1] = pCur->pLits[i];
+ pCur->pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ *piPrev = pCur->iNext[1];
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ Tas_ManWatchClause( p, pCur, pCur->pLits[1] );
+ break;
+ }
+ if ( i < (int)pCur->nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) );
+ if ( !Tas_VarIsAssigned(pObj) )
+ {
+/*
+ {
+ int iLitLevel, iPlace;
+ for ( i = 1; i < (int)pCur->nLits; i++ )
+ {
+ pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) );
+ iLitLevel = Tas_VarDecLevel( p, pObj );
+ iPlace = pObj->Value;
+ printf( "Lit = %d. Level = %d. Place = %d.\n", pCur->pLits[i], iLitLevel, iPlace );
+ i = i;
+ }
+ }
+*/
+ Tas_ManAssign( p, Gia_ObjFromLit(p->pAig, pCur->pLits[0]), Level, NULL, (Gia_Obj_t *)pCur );
+ piPrev = &pCur->iNext[1];
+ continue;
+ }
+ // conflict detected - return the conflict clause
+ assert( !Tas_LitIsTrue( pObj, pCur->pLits[0] ) );
+ return Tas_ManCreateFromCls( p, pCur, Level );
+ }
+ return 0;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns clause handle if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManPropagateOne( Tas_Man_t * p, Gia_Obj_t * pVar, int Level )
+{
+ int Value0, Value1, hClause;
+ assert( !Gia_IsComplement(pVar) );
+ assert( Tas_VarIsAssigned(pVar) );
+ s_Counter3++;
+ if ( (hClause = Tas_ManPropagateWatch( p, Level, Tas_VarToLit(p, pVar) )) )
+ return hClause;
+ if ( Gia_ObjIsCi(pVar) )
+ return 0;
+/*
+ if ( pVar->iDiff0 == 570869 && pVar->iDiff1 == 546821 && Level == 3 )
+ {
+ Gia_Obj_t * pFan0 = Gia_ObjFanin0(pVar);
+ Gia_Obj_t * pFan1 = Gia_ObjFanin1(pVar);
+ int s = 0;
+ }
+*/
+ assert( Gia_ObjIsAnd(pVar) );
+ Value0 = Tas_VarFanin0Value(pVar);
+ Value1 = Tas_VarFanin1Value(pVar);
+ if ( Tas_VarValue(pVar) )
+ { // value is 1
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ {
+ if ( Value0 == 0 && Value1 != 0 )
+ return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), NULL );
+ if ( Value0 != 0 && Value1 == 0 )
+ return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin1(pVar), NULL );
+ assert( Value0 == 0 && Value1 == 0 );
+ return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ }
+ if ( Value0 == 2 ) // first is unassigned
+ Tas_ManAssign( p, Gia_ObjChild0(pVar), Level, pVar, NULL );
+ if ( Value1 == 2 ) // first is unassigned
+ Tas_ManAssign( p, Gia_ObjChild1(pVar), Level, pVar, NULL );
+ return 0;
+ }
+ // value is 0
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ return 0;
+ if ( Value0 == 1 && Value1 == 1 ) // both are 1
+ return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ if ( Value0 == 1 || Value1 == 1 ) // one is 1
+ {
+ if ( Value0 == 2 ) // first is unassigned
+ Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) );
+ if ( Value1 == 2 ) // second is unassigned
+ Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) );
+ return 0;
+ }
+ assert( Tas_VarIsJust(pVar) );
+ assert( !Tas_QueHasNode( &p->pJust, pVar ) );
+ Tas_QuePush( &p->pJust, pVar );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Tas_ManPropagateTwo( Tas_Man_t * p, Gia_Obj_t * pVar, int Level )
+{
+ int Value0, Value1;
+ s_Counter4++;
+ assert( !Gia_IsComplement(pVar) );
+ assert( Gia_ObjIsAnd(pVar) );
+ assert( Tas_VarIsAssigned(pVar) );
+ assert( !Tas_VarValue(pVar) );
+ Value0 = Tas_VarFanin0Value(pVar);
+ Value1 = Tas_VarFanin1Value(pVar);
+ // value is 0
+ if ( Value0 == 0 || Value1 == 0 ) // one is 0
+ return 0;
+ if ( Value0 == 1 && Value1 == 1 ) // both are 1
+ return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) );
+ assert( Value0 == 1 || Value1 == 1 );
+ if ( Value0 == 2 ) // first is unassigned
+ Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) );
+ if ( Value1 == 2 ) // first is unassigned
+ Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates all variables.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Tas_ManPropagate( Tas_Man_t * p, int Level )
+{
+ int hClause;
+ Gia_Obj_t * pVar;
+ int i, k, nIter = 0;
+ while ( 1 )
+ {
+// nIter++;
+ Tas_QueForEachEntry( p->pProp, pVar, i )
+ {
+ if ( (hClause = Tas_ManPropagateOne( p, pVar, Level )) )
+ return hClause;
+ }
+ p->pProp.iHead = p->pProp.iTail;
+ k = p->pJust.iHead;
+ Tas_QueForEachEntry( p->pJust, pVar, i )
+ {
+ if ( Tas_VarIsJust( pVar ) )
+ p->pJust.pData[k++] = pVar;
+ else if ( (hClause = Tas_ManPropagateTwo( p, pVar, Level )) )
+ return hClause;
+ }
+ if ( k == p->pJust.iTail )
+ break;
+ p->pJust.iTail = k;
+ }
+// printf( "%d ", nIter );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solve the problem recursively.]
+
+ Description [Returns learnt clause if unsat, NULL if sat or undecided.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Tas_ManSolve_rec( Tas_Man_t * p, int Level )
+{
+ Tas_Que_t * pQue = &(p->pClauses);
+ Gia_Obj_t * pVar, * pDecVar;
+ int hClause, hLearn0, hLearn1;
+ int iPropHead, iJustHead, iJustTail;
+ // propagate assignments
+ assert( !Tas_QueIsEmpty(&p->pProp) );
+ if ( (hClause = Tas_ManPropagate( p, Level )) )
+ {
+ Tas_ManCreateCls( p, hClause );
+ return hClause;
+ }
+ // check for satisfying assignment
+ assert( Tas_QueIsEmpty(&p->pProp) );
+ if ( Tas_QueIsEmpty(&p->pJust) )
+ return 0;
+ // quit using resource limits
+ p->Pars.nJustThis = ABC_MAX( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead );
+ if ( Tas_ManCheckLimits( p ) )
+ return 0;
+ // remember the state before branching
+ iPropHead = p->pProp.iHead;
+ Tas_QueStore( &p->pJust, &iJustHead, &iJustTail );
+ // find the decision variable
+ if ( p->Pars.fUseActive )
+ pVar = NULL, pDecVar = Tas_ManFindActive( p );
+ else if ( p->Pars.fUseHighest )
+// pVar = NULL, pDecVar = Tas_ManDecideHighestFanin( p );
+ pVar = Tas_ManDecideHighest( p );
+ else if ( p->Pars.fUseLowest )
+ pVar = Tas_ManDecideLowest( p );
+ else if ( p->Pars.fUseMaxFF )
+ pVar = Tas_ManDecideMaxFF( p );
+ else assert( 0 );
+ // chose decision variable using fanout count
+ if ( pVar != NULL )
+ {
+ assert( Tas_VarIsJust( pVar ) );
+ if ( Gia_ObjRefs(p->pAig, Gia_ObjFanin0(pVar)) > Gia_ObjRefs(p->pAig, Gia_ObjFanin1(pVar)) )
+ pDecVar = Gia_Not(Gia_ObjChild0(pVar));
+ else
+ pDecVar = Gia_Not(Gia_ObjChild1(pVar));
+// pDecVar = Gia_NotCond( pDecVar, Gia_Regular(pDecVar)->fMark1 ^ !Gia_IsComplement(pDecVar) );
+ }
+ // decide on first fanin
+ Tas_ManAssign( p, pDecVar, Level+1, NULL, NULL );
+ if ( !(hLearn0 = Tas_ManSolve_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn0] != Gia_Regular(pDecVar) )
+ return hLearn0;
+ Tas_ManCancelUntil( p, iPropHead );
+ Tas_QueRestore( &p->pJust, iJustHead, iJustTail );
+ // decide on second fanin
+ Tas_ManAssign( p, Gia_Not(pDecVar), Level+1, NULL, NULL );
+ if ( !(hLearn1 = Tas_ManSolve_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn1] != Gia_Regular(pDecVar) )
+ return hLearn1;
+ hClause = Tas_ManResolve( p, Level, hLearn0, hLearn1 );
+ Tas_ManCreateCls( p, hClause );
+// Tas_ManPrintClauseNew( p, Level, hClause );
+// if ( Level > Tas_ClauseDecLevel(p, hClause) )
+// p->Pars.nBTThisNc++;
+ p->Pars.nBTThis++;
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Looking for a satisfying assignment of the node.]
+
+ Description [Assumes that each node has flag pObj->fMark0 set to 0.
+ Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided.
+ The node may be complemented. ]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 )
+{
+ int i, Entry, RetValue = 0;
+ s_Counter2 = 0;
+ Vec_IntClear( p->vModel );
+ if ( pObj == Gia_ManConst0(p->pAig) || pObj2 == Gia_ManConst0(p->pAig) || pObj == Gia_Not(pObj2) )
+ return 1;
+ if ( pObj == Gia_ManConst1(p->pAig) && (pObj2 == NULL || pObj2 == Gia_ManConst1(p->pAig)) )
+ return 0;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
+ Tas_ManAssign( p, pObj, 0, NULL, NULL );
+ if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) )
+ Tas_ManAssign( p, pObj2, 0, NULL, NULL );
+ if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
+ Tas_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ Tas_ManCancelUntil( p, 0 );
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ // clauses
+ if ( p->nClauses > 0 )
+ {
+ p->pStore.iCur = 16;
+ Vec_IntForEachEntry( p->vWatchLits, Entry, i )
+ p->pWatches[Entry] = 0;
+ Vec_IntClear( p->vWatchLits );
+ p->nClauses = 0;
+ }
+ // activity
+ Vec_IntForEachEntry( p->vActiveVars, Entry, i )
+ p->pActivity[Entry] = 0.0;
+ Vec_IntClear( p->vActiveVars );
+ // statistics
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( Tas_ManCheckLimits( p ) )
+ RetValue = -1;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Looking for a satisfying assignment of the node.]
+
+ Description [Assumes that each node has flag pObj->fMark0 set to 0.
+ Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided.
+ The node may be complemented. ]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs )
+{
+ Gia_Obj_t * pObj;
+ int i, Entry, RetValue = 0;
+ s_Counter2 = 0;
+ s_Counter3 = 0;
+ s_Counter4 = 0;
+ Vec_IntClear( p->vModel );
+ Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i )
+ if ( pObj == Gia_ManConst0(p->pAig) )
+ return 1;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
+ Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i )
+ if ( pObj != Gia_ManConst1(p->pAig) && !Tas_VarIsAssigned(Gia_Regular(pObj)) )
+ Tas_ManAssign( p, pObj, 0, NULL, NULL );
+ if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
+ Tas_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ Tas_ManCancelUntil( p, 0 );
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ // clauses
+ if ( p->nClauses > 0 )
+ {
+ p->pStore.iCur = 16;
+ Vec_IntForEachEntry( p->vWatchLits, Entry, i )
+ p->pWatches[Entry] = 0;
+ Vec_IntClear( p->vWatchLits );
+ p->nClauses = 0;
+ }
+ // activity
+ Vec_IntForEachEntry( p->vActiveVars, Entry, i )
+ p->pActivity[Entry] = 0.0;
+ Vec_IntClear( p->vActiveVars );
+ // statistics
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( Tas_ManCheckLimits( p ) )
+ RetValue = -1;
+
+// printf( "%d ", Gia_ManObjNum(p->pAig) );
+// printf( "%d ", p->Pars.nBTThis );
+// printf( "%d ", p->Pars.nJustThis );
+// printf( "%d ", s_Counter2 );
+// printf( "%d ", s_Counter3 );
+// printf( "%d ", s_Counter4 );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Tas_ManSatPrintStats( Tas_Man_t * p )
+{
+ printf( "CO = %8d ", Gia_ManCoNum(p->pAig) );
+ printf( "AND = %8d ", Gia_ManAndNum(p->pAig) );
+ printf( "Conf = %6d ", p->Pars.nBTLimit );
+ printf( "JustMax = %5d ", p->Pars.nJustLimit );
+ printf( "\n" );
+ printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
+ printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
+ printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+ ABC_PRT( "Total time", p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure to test the new SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
+{
+ extern void Gia_ManCollectTest( Gia_Man_t * pAig );
+ extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
+ Tas_Man_t * p;
+ Vec_Int_t * vCex, * vVisit, * vCexStore;
+ Vec_Str_t * vStatus;
+ Gia_Obj_t * pRoot;//, * pRootCopy;
+// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp;
+
+ int i, status, clk, clkTotal = clock();
+ assert( Gia_ManRegNum(pAig) == 0 );
+// Gia_ManCollectTest( pAig );
+ // prepare AIG
+ Gia_ManCreateRefs( pAig );
+ Gia_ManCleanMark0( pAig );
+ Gia_ManCleanMark1( pAig );
+ Gia_ManFillValue( pAig ); // maps nodes into trail ids
+ Gia_ManCleanPhase( pAig ); // maps nodes into trail ids
+ // create logic network
+ p = Tas_ManAlloc( pAig, nConfs );
+ p->pAig = pAig;
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ vVisit = Vec_IntAlloc( 100 );
+ vCex = Tas_ReadModel( p );
+ // solve for each output
+ Gia_ManForEachCo( pAig, pRoot, i )
+ {
+// printf( "%d=", i );
+
+ Vec_IntClear( vCex );
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) )
+ {
+ if ( Gia_ObjFaninC0(pRoot) )
+ {
+// printf( "Constant 1 output of SRM!!!\n" );
+ Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example
+ Vec_StrPush( vStatus, 0 );
+ }
+ else
+ {
+// printf( "Constant 0 output of SRM!!!\n" );
+ Vec_StrPush( vStatus, 1 );
+ }
+ continue;
+ }
+ clk = clock();
+// p->Pars.fUseActive = 1;
+ p->Pars.fUseHighest = 1;
+ p->Pars.fUseLowest = 0;
+ status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
+// printf( "\n" );
+/*
+ if ( status == -1 )
+ {
+ p->Pars.fUseHighest = 0;
+ p->Pars.fUseLowest = 1;
+ status = Tas_ManSolve( p, Gia_ObjChild0(pRoot) );
+ }
+*/
+ Vec_StrPush( vStatus, (char)status );
+ if ( status == -1 )
+ {
+// printf( "Unsolved %d.\n", i );
+
+ p->nSatUndec++;
+ p->nConfUndec += p->Pars.nBTThis;
+ Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
+ p->timeSatUndec += clock() - clk;
+ continue;
+ }
+
+// pRootCopy = Gia_ManCo( pAigCopy, i );
+// pRootCopy->iDiff0 = Gia_ObjId( pAigCopy, pRootCopy );
+// pRootCopy->fCompl0 = 0;
+
+ if ( status == 1 )
+ {
+ p->nSatUnsat++;
+ p->nConfUnsat += p->Pars.nBTThis;
+ p->timeSatUnsat += clock() - clk;
+ continue;
+ }
+ p->nSatSat++;
+ p->nConfSat += p->Pars.nBTThis;
+// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit );
+ Cec_ManSatAddToStore( vCexStore, vCex, i );
+ p->timeSatSat += clock() - clk;
+
+// printf( "%d ", Vec_IntSize(vCex) );
+ }
+// pAigCopy = Gia_ManCleanup( pAigTemp = pAigCopy );
+// Gia_ManStop( pAigTemp );
+// Gia_DumpAiger( pAigCopy, "test", 0, 2 );
+// Gia_ManStop( pAigCopy );
+
+ Vec_IntFree( vVisit );
+ p->nSatTotal = Gia_ManPoNum(pAig);
+ p->timeTotal = clock() - clkTotal;
+ if ( fVerbose )
+ Tas_ManSatPrintStats( p );
+// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
+ Tas_ManStop( p );
+ *pvStatus = vStatus;
+
+// printf( "Total number of cex literals = %d. (Ave = %d)\n",
+// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
+// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat );
+ return vCexStore;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+int Tas_StorePatternTry( 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 Tas_StorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex )
+{
+ int k;
+ for ( k = 1; k < 32; k++ )
+ if ( Tas_StorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) )
+ break;
+ return (int)(k < 32);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure to test the new SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Vec_Ptr_t * vOldRoots, Vec_Ptr_t * vSimInfo )
+{
+ int nPatMax = 1000;
+ int fVerbose = 1;
+ extern void Gia_ManCollectTest( Gia_Man_t * pAig );
+ extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
+ Tas_Man_t * p;
+ Vec_Ptr_t * vPres;
+ Vec_Int_t * vCex, * vVisit, * vCexStore;
+ Vec_Str_t * vStatus;
+ Gia_Obj_t * pRoot, * pOldRoot;
+ int i, status, clk, clkTotal = clock();
+ int Tried = 0, Stored = 0, Step = Gia_ManCoNum(pAig) / nPatMax;
+ assert( Gia_ManRegNum(pAig) == 0 );
+// Gia_ManCollectTest( pAig );
+ // prepare AIG
+ Gia_ManCreateRefs( pAig );
+ Gia_ManCleanMark0( pAig );
+ Gia_ManCleanMark1( pAig );
+ Gia_ManFillValue( pAig ); // maps nodes into trail ids
+ Gia_ManCleanPhase( pAig ); // maps nodes into trail ids
+ // create logic network
+ p = Tas_ManAlloc( pAig, nConfs );
+ p->pAig = pAig;
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ vVisit = Vec_IntAlloc( 100 );
+ vCex = Tas_ReadModel( p );
+ // solve for each output
+ vPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pAig), 1 );
+ Vec_PtrCleanSimInfo( vPres, 0, 1 );
+
+ Gia_ManForEachCo( pAig, pRoot, i )
+ {
+ assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) );
+ Vec_IntClear( vCex );
+ clk = clock();
+ p->Pars.fUseHighest = 1;
+ p->Pars.fUseLowest = 0;
+ status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
+ Vec_StrPush( vStatus, (char)status );
+ if ( status == -1 )
+ {
+ p->nSatUndec++;
+ p->nConfUndec += p->Pars.nBTThis;
+// Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
+ p->timeSatUndec += clock() - clk;
+
+ i += Step;
+ continue;
+ }
+ if ( status == 1 )
+ {
+ p->nSatUnsat++;
+ p->nConfUnsat += p->Pars.nBTThis;
+ p->timeSatUnsat += clock() - clk;
+ // record proved
+ pOldRoot = (Gia_Obj_t *)Vec_PtrEntry( vOldRoots, i );
+ assert( !Gia_ObjProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) ) );
+ Gia_ObjSetProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) );
+
+ i += Step;
+ continue;
+ }
+ p->nSatSat++;
+ p->nConfSat += p->Pars.nBTThis;
+// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit );
+// Cec_ManSatAddToStore( vCexStore, vCex, i );
+
+ // save pattern
+ Tried++;
+ Stored += Tas_StorePattern( vSimInfo, vPres, vCex );
+ p->timeSatSat += clock() - clk;
+ i += Step;
+ }
+ printf( "Tried = %d Stored = %d\n", Tried, Stored );
+ Vec_IntFree( vVisit );
+ p->nSatTotal = Gia_ManPoNum(pAig);
+ p->timeTotal = clock() - clkTotal;
+ if ( fVerbose )
+ Tas_ManSatPrintStats( p );
+ Tas_ManStop( p );
+ Vec_PtrFree( vPres );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCTas2.c b/src/aig/gia/giaCTas2.c
new file mode 100644
index 00000000..855dcdd3
--- /dev/null
+++ b/src/aig/gia/giaCTas2.c
@@ -0,0 +1,208 @@
+/**CFile****************************************************************
+
+ FileName [giaCSat2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Circuit-based SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Tas_Par_t_ Tas_Par_t;
+struct Tas_Par_t_
+{
+ // conflict limits
+ int nBTLimit; // limit on the number of conflicts
+ // current parameters
+ int nBTThis; // number of conflicts
+ int nBTTotal; // total number of conflicts
+ // decision heuristics
+ int fUseHighest; // use node with the highest ID
+ // other parameters
+ int fVerbose;
+};
+
+typedef struct Tas_Sto_t_ Tas_Sto_t;
+struct Tas_Sto_t_
+{
+ int iCur; // currently used
+ int nSize; // allocated size
+ char * pBuffer; // handles of objects stored in the queue
+};
+
+typedef struct Tas_Que_t_ Tas_Que_t;
+struct Tas_Que_t_
+{
+ int iHead; // beginning of the queue
+ int iTail; // end of the queue
+ int nSize; // allocated size
+ int * pData; // handles of objects stored in the queue
+};
+
+typedef struct Tas_Var_t_ Tas_Var_t;
+struct Tas_Var_t_
+{
+ unsigned fTerm : 1; // terminal node
+ unsigned fVal : 1; // current value
+ unsigned fValOld : 1; // previous value
+ unsigned fAssign : 1; // assigned status
+ unsigned fJQueue : 1; // part of J-frontier
+ unsigned fCompl0 : 1; // complemented attribute
+ unsigned fCompl1 : 1; // complemented attribute
+ unsigned fMark0 : 1; // multi-purpose mark
+ unsigned fMark1 : 1; // multi-purpose mark
+ unsigned fPhase : 1; // polarity
+ unsigned Level : 22; // decision level
+ int Id; // unique ID of this variable
+ int IdAig; // original ID of this variable
+ int Reason0; // reason of this variable
+ int Reason1; // reason of this variable
+ int Diff0; // difference for the first fanin
+ int Diff1; // difference for the second fanin
+ int Watch0; // handle of first watch
+ int Watch1; // handle of second watch
+};
+
+typedef struct Tas_Cls_t_ Tas_Cls_t;
+struct Tas_Cls_t_
+{
+ int Watch0; // next clause to watch
+ int Watch1; // next clause to watch
+ int pVars[0]; // variable handles
+};
+
+typedef struct Tas_Man_t_ Tas_Man_t;
+struct Tas_Man_t_
+{
+ // user data
+ Gia_Man_t * pAig; // AIG manager
+ Tas_Par_t Pars; // parameters
+ // solver data
+ Tas_Sto_t * pVars; // variables
+ Tas_Sto_t * pClauses; // clauses
+ // state representation
+ Tas_Que_t pProp; // propagation queue
+ Tas_Que_t pJust; // justification queue
+ Vec_Int_t * vModel; // satisfying assignment
+ Vec_Ptr_t * vTemp; // temporary storage
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ int nConfTotal; // total conflicts
+ // runtime stats
+ int timeSatUnsat; // unsat
+ int timeSatSat; // sat
+ int timeSatUndec; // undecided
+ int timeTotal; // total runtime
+};
+
+static inline int Tas_VarIsAssigned( Tas_Var_t * pVar ) { return pVar->fAssign; }
+static inline void Tas_VarAssign( Tas_Var_t * pVar ) { assert(!pVar->fAssign); pVar->fAssign = 1; }
+static inline void Tas_VarUnassign( Tas_Var_t * pVar ) { assert(pVar->fAssign); pVar->fAssign = 0; pVar->fVal = 0; }
+static inline int Tas_VarValue( Tas_Var_t * pVar ) { assert(pVar->fAssign); return pVar->fVal; }
+static inline void Tas_VarSetValue( Tas_Var_t * pVar, int v ) { assert(pVar->fAssign); pVar->fVal = v; }
+static inline int Tas_VarIsJust( Tas_Var_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); }
+static inline int Tas_VarFanin0Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); }
+static inline int Tas_VarFanin1Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); }
+
+static inline int Tas_VarDecLevel( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); }
+static inline Tas_Var_t * Tas_VarReason0( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); }
+static inline Tas_Var_t * Tas_VarReason1( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); }
+static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); }
+
+static inline Tas_Var_t * Tas_ManVar( Tas_Man_t * p, int h ) { return (Tas_Var_t *)(p->pVars->pBuffer + h); }
+static inline Tas_Cls_t * Tas_ManClause( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pClauses->pBuffer + h); }
+
+#define Tas_ClaForEachVar( p, pClause, pVar, i ) \
+ for ( pVar = Tas_ManVar(p, pClause->pVars[(i=0)]); pClause->pVars[i]; pVar = (Tas_Var_t *)(((char *)pVar + pClause->pVars[++i])) )
+
+#define Tas_QueForEachVar( p, pQue, pVar, i ) \
+ for ( pVar = Tas_ManVar(p, pQue->pVars[(i=pQue->iHead)]); i < pQue->iTail; pVar = Tas_ManVar(p, pQue->pVars[i++]) )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Tas_Var_t * Tas_ManCreateVar( Tas_Man_t * p )
+{
+ Tas_Var_t * pVar;
+ if ( p->pVars->iCur + sizeof(Tas_Var_t) > p->pVars->nSize )
+ {
+ p->pVars->nSize *= 2;
+ p->pVars->pData = ABC_REALLOC( char, p->pVars->pData, p->pVars->nSize );
+ }
+ pVar = p->pVars->pData + p->pVars->iCur;
+ p->pVars->iCur += sizeof(Tas_Var_t);
+ memset( pVar, 0, sizeof(Tas_Var_t) );
+ pVar->Id = pVar - ((Tas_Var_t *)p->pVars->pData);
+ return pVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Tas_Var_t * Tas_ManObj2Var( Tas_Man_t * p, Gia_Obj_t * pObj )
+{
+ Tas_Var_t * pVar;
+ assert( !Gia_ObjIsComplement(pObj) );
+ if ( pObj->Value == 0 )
+ {
+ pVar = Tas_ManCreateVar( p );
+ pVar->
+
+ }
+ return Tas_ManVar( p, pObj->Value );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c
index da48c1b0..5a04d9d3 100644
--- a/src/aig/gia/giaCof.c
+++ b/src/aig/gia/giaCof.c
@@ -21,6 +21,9 @@
#include <math.h>
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -390,7 +393,7 @@ void Cof_ManInsertEntry_rec( Vec_Ptr_t * vNodes, Cof_Obj_t * pNode, int nNodeMax
Vec_PtrPush(vNodes, pNode);
return;
}
- pLast = Vec_PtrPop(vNodes);
+ pLast = (Cof_Obj_t *)Vec_PtrPop(vNodes);
if ( Cof_ObjFanoutNum(pLast) < Cof_ObjFanoutNum(pNode) )
{
Cof_ManInsertEntry_rec( vNodes, pNode, nNodeMax );
@@ -541,7 +544,7 @@ void Cof_ManPrintHighFanout( Cof_Man_t * p, int nNodes )
Cof_Obj_t * pObj;
int i;
vNodes = Cof_ManCollectHighFanout( p, nNodes );
- Vec_PtrForEachEntry( vNodes, pObj, i )
+ Vec_PtrForEachEntry( Cof_Obj_t *, vNodes, pObj, i )
Cof_ManPrintHighFanoutOne( p, pObj );
Vec_PtrFree( vNodes );
}
@@ -633,7 +636,7 @@ void Cof_ManPrintFanio( Cof_Man_t * p )
printf( "%15d : ", k );
else
{
- sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 );
+ sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 );
printf( "%15s : ", Buffer );
}
if ( vFanins->pArray[k] == 0 )
@@ -916,3 +919,5 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaConstr.c b/src/aig/gia/giaConstr.c
index 14768cc2..60432072 100644
--- a/src/aig/gia/giaConstr.c
+++ b/src/aig/gia/giaConstr.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -45,3 +48,5 @@
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c
index bcc1748f..3b591aee 100644
--- a/src/aig/gia/giaDfs.c
+++ b/src/aig/gia/giaDfs.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -136,6 +139,63 @@ void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vN
/**Function*************************************************************
+ Synopsis [Counts the support size of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCollectNodesCis_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes );
+ Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin1(pObj), vNodes );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects support nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes )
+{
+ Vec_Int_t * vNodes;
+ Gia_Obj_t * pObj;
+ int i;
+ vNodes = Vec_IntAlloc( 10000 );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ for ( i = 0; i < nNodes; i++ )
+ {
+ pObj = Gia_ManObj( p, pNodes[i] );
+ if ( Gia_ObjIsCo(pObj) )
+ Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes );
+ else
+ Gia_ManCollectNodesCis_rec( p, pObj, vNodes );
+ }
+ return vNodes;
+}
+
+/**Function*************************************************************
+
Synopsis [Collects support nodes.]
Description []
@@ -151,7 +211,6 @@ void Gia_ManCollectTest( Gia_Man_t * p )
Gia_Obj_t * pObj;
int i, iNode, clk = clock();
vNodes = Vec_IntAlloc( 100 );
- Gia_ManResetTravId( p );
Gia_ManIncrementTravId( p );
Gia_ManForEachCo( p, pObj, i )
{
@@ -276,7 +335,7 @@ int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes )
***********************************************************************/
Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p )
-{
+{
Gia_Obj_t * pObj;
Vec_Vec_t * vLevels;
int nLevels, Level, i;
@@ -291,8 +350,49 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p )
return vLevels;
}
+/**Function*************************************************************
+
+ Synopsis [Computes reverse topological order.]
+
+ Description [Assumes that levels are already assigned.
+ The levels of CO nodes may not be assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Vec_t * vLevels;
+ Vec_Ptr_t * vLevel;
+ Vec_Int_t * vResult;
+ int i, k;
+ vLevels = Vec_VecStart( 100 );
+ // make sure levels are assigned
+ Gia_ManForEachAnd( p, pObj, i )
+ assert( Gia_ObjLevel(p, pObj) > 0 );
+ // add CO nodes based on the level of their fanin
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_VecPush( vLevels, Gia_ObjLevel(p, Gia_ObjFanin0(pObj)), pObj );
+ // add other nodes based on their level
+ Gia_ManForEachObj( p, pObj, i )
+ if ( !Gia_ObjIsCo(pObj) )
+ Vec_VecPush( vLevels, Gia_ObjLevel(p, pObj), pObj );
+ // put the nodes in the reverse topological order
+ vResult = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Vec_VecForEachLevelReverse( vLevels, vLevel, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vLevel, pObj, k )
+ Vec_IntPush( vResult, Gia_ObjId(p, pObj) );
+ Vec_VecFree( vLevels );
+ return vResult;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index cde19a22..4ded9a78 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -143,6 +146,8 @@ int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
return pObj->Value;
if ( Gia_ObjIsCi(pObj) )
return pObj->Value = Gia_ManAppendCi(pNew);
+// if ( p->pNexts && Gia_ObjNext(p, Gia_ObjId(p, pObj)) )
+// Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjNextObj(p, Gia_ObjId(p, pObj)) );
Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
if ( Gia_ObjIsCo(pObj) )
return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
@@ -193,6 +198,98 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ for ( i = iOutStart; i < iOutStop; i++ )
+ {
+ pObj = Gia_ManCo( p, i );
+ Gia_ManDupOrderDfs_rec( pNew, p, pObj );
+ }
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupOrderDfsChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pNext;
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ pNext = Gia_ObjNextObj( p, Gia_ObjId(p, pObj) );
+ if ( pNext )
+ Gia_ManDupOrderDfsChoices_rec( pNew, p, pNext );
+ Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( pNext )
+ {
+ pNew->pNexts[Gia_Lit2Var(pObj->Value)] = Gia_Lit2Var( Gia_Lit2Var(pNext->Value) );
+ assert( Gia_Lit2Var(pObj->Value) > Gia_Lit2Var(pNext->Value) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG while putting objects in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pReprs && p->pNexts );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+// Gia_ManDeriveReprs( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG while putting objects in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p )
{
Gia_Man_t * pNew;
@@ -274,13 +371,13 @@ Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState )
{
pObj->Value = Gia_ManAppendCi( pNew );
if ( Gia_ObjCioId(pObj) >= Gia_ManPiNum(p) )
- pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) );
+ pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) );
}
else if ( Gia_ObjIsCo(pObj) )
{
pObj->Value = Gia_ObjFanin0Copy(pObj);
if ( Gia_ObjCioId(pObj) >= Gia_ManPoNum(p) )
- pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) );
+ pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) );
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
}
}
@@ -318,6 +415,8 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
}
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ if ( p->pCexSeq )
+ pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) );
return pNew;
}
@@ -664,6 +763,8 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p )
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ if ( p->pCexSeq )
+ pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) );
return pNew;
}
@@ -719,7 +820,8 @@ Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pRoot )
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
- Gia_ManDupDfs_rec( pNew, p, pRoot );
+ Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pRoot) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pRoot) );
Gia_ManSetRegNum( pNew, 0 );
return pNew;
}
@@ -820,6 +922,49 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos )
/**Function*************************************************************
+ Synopsis [Duplicates AIG in the DFS order while putting CIs first.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 )
+{
+ Gia_Man_t * pTemp, * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Gia_ManPoNum(p) == Gia_ManPiNum(p2) );
+ assert( Gia_ManRegNum(p) == 0 );
+ assert( Gia_ManRegNum(p2) == 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p)+Gia_ManObjNum(p2) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ // dup first AIG
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // dup second AIG
+ Gia_ManConst0(p2)->Value = 0;
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManPi(p2, i)->Value = Gia_ObjFanin0Copy(pObj);
+ Gia_ManForEachAnd( p2, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p2, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+// Gia_ManPrintStats( pGiaNew, 0 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Print representatives.]
Description []
@@ -1243,8 +1388,84 @@ Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ if ( Gia_ObjIsCo(pObj) )
+ return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of several AIGs for choice computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias )
+{
+ Gia_Man_t * pNew, * pGia, * pGia0;
+ int i, k, iNode, nNodes;
+ // make sure they have equal parameters
+ assert( Vec_PtrSize(vGias) > 0 );
+ pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 );
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ {
+ assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) );
+ assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) );
+ assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) );
+ Gia_ManFillValue( pGia );
+ Gia_ManConst0(pGia)->Value = 0;
+ }
+ // start the new manager
+ pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) );
+ pNew->pName = Gia_UtilStrsav( pGia0->pName );
+ // create new CIs and assign them to the old manager CIs
+ for ( k = 0; k < Gia_ManCiNum(pGia0); k++ )
+ {
+ iNode = Gia_ManAppendCi(pNew);
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ Gia_ManCi( pGia, k )->Value = iNode;
+ }
+ // create internal nodes
+ Gia_ManHashAlloc( pNew );
+ for ( k = 0; k < Gia_ManCoNum(pGia0); k++ )
+ {
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ Gia_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) );
+ }
+ Gia_ManHashStop( pNew );
+ // check the presence of dangling nodes
+ nNodes = Gia_ManHasDangling( pNew );
+ assert( nNodes == 0 );
+ // finalize
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia0) );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c
index bd14eea9..5c7092a3 100644
--- a/src/aig/gia/giaEmbed.c
+++ b/src/aig/gia/giaEmbed.c
@@ -20,6 +20,10 @@
#include <math.h>
#include "gia.h"
+#include "ioa.h"
+
+ABC_NAMESPACE_IMPL_START
+
/*
The code is based on the paper by D. Harel and Y. Koren,
@@ -743,7 +747,7 @@ void Emb_ManPrintFanio( Emb_Man_t * p )
printf( "%15d : ", k );
else
{
- sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 );
+ sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 );
printf( "%15s : ", Buffer );
}
if ( vFanins->pArray[k] == 0 )
@@ -1692,7 +1696,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowI
extern void Gia_ManGnuplotShow( char * pPlotFileName );
// char * pDirectory = "place\\";
char * pDirectory = "";
- extern char * Ioa_TimeStamp();
+// extern char * Ioa_TimeStamp();
FILE * pFile;
char Buffer[1000];
Emb_Obj_t * pThis, * pNext;
@@ -1865,3 +1869,5 @@ ABC_PRT( "Image dump", clock() - clk );
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c
index c768bb43..37f0c94f 100644
--- a/src/aig/gia/giaEnable.c
+++ b/src/aig/gia/giaEnable.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -620,7 +623,7 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p )
}
Gia_ManForEachRi( p, pObj, i )
{
- pData = Vec_PtrEntry(vDatas, i);
+ pData = (Gia_Obj_t *)Vec_PtrEntry(vDatas, i);
if ( pData == NULL )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
else
@@ -641,3 +644,5 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index 0f680e31..668bc4a2 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -19,6 +19,9 @@
***********************************************************************/
#include "gia.h"
+#include "cec.h"
+
+ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -221,6 +224,8 @@ int Gia_ManEquivCountLitsAll( Gia_Man_t * p )
int Gia_ManEquivCountClasses( Gia_Man_t * p )
{
int i, Counter = 0;
+ if ( p->pReprs == NULL )
+ return 0;
for ( i = 1; i < Gia_ManObjNum(p); i++ )
Counter += Gia_ObjIsHead(p, i);
return Counter;
@@ -448,14 +453,14 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fV
{
printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" );
return NULL;
- }
+ }
// check if there are any equivalences defined
Gia_ManForEachObj( p, pObj, i )
if ( Gia_ObjReprObj(p, i) != NULL )
break;
if ( i == Gia_ManObjNum(p) )
{
- printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" );
+// printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" );
return NULL;
}
/*
@@ -815,7 +820,7 @@ void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, V
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose )
+Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose )
{
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj;
@@ -858,6 +863,11 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose )
Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut );
Gia_ManForEachCo( p, pObj, i )
Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut );
+ if ( !fSynthesis )
+ {
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
Vec_IntForEachEntry( vXorLits, iLitNew, i )
Gia_ManAppendCo( pNew, iLitNew );
if ( Vec_IntSize(vXorLits) == 0 )
@@ -935,7 +945,7 @@ void Gia_ManSpecReduceInit_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut )
+Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut )
{
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj, * pObjRi, * pObjRo;
@@ -1024,7 +1034,7 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs )
+Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs )
{
Gia_Man_t * pFrames;
int f, nLits;
@@ -1225,7 +1235,7 @@ int Gia_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode )
assert( !Gia_IsComplement(pNode) );
vVisited = Vec_PtrAlloc( 100 );
RetValue = Gia_ObjCheckTfi_rec( p, pOld, pNode, vVisited );
- Vec_PtrForEachEntry( vVisited, pObj, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i )
pObj->fMark0 = 0;
Vec_PtrFree( vVisited );
return RetValue;
@@ -1293,7 +1303,9 @@ void Gia_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb
pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) );
if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) )
{
- assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew );
+// assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew );
+ if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) != pReprNew )
+ return;
pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
return;
}
@@ -1373,9 +1385,11 @@ void Gia_ManRemoveBadChoices( Gia_Man_t * p )
***********************************************************************/
Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
{
+ Vec_Int_t * vNodes;
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj, * pRepr;
int i;
+//Gia_ManEquivPrintClasses( p, 0, 0 );
assert( (Gia_ManCoNum(p) % nSnapshots) == 0 );
Gia_ManSetPhase( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
@@ -1397,24 +1411,77 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
Gia_ManHashAlloc( pNew );
Gia_ManForEachCo( p, pObj, i )
Gia_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ vNodes = Gia_ManGetDangling( p );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Gia_ManEquivToChoices_rec( pNew, p, pObj );
+ Vec_IntFree( vNodes );
Gia_ManForEachCo( p, pObj, i )
if ( i % nSnapshots == 0 )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManHashStop( pNew );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
Gia_ManRemoveBadChoices( pNew );
-// Gia_ManEquivPrintClasses( pNew, 0, 0 );
+//Gia_ManEquivPrintClasses( pNew, 0, 0 );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
-// Gia_ManEquivPrintClasses( pNew, 0, 0 );
+//Gia_ManEquivPrintClasses( pNew, 0, 0 );
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Counts the number of choice nodes]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountChoiceNodes( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ if ( p->pReprs == NULL || p->pNexts == NULL )
+ return 0;
+ Gia_ManForEachObj( p, pObj, i )
+ Counter += Gia_ObjIsHead( p, i );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of choices]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountChoices( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, Counter = 0;
+ if ( p->pReprs == NULL || p->pNexts == NULL )
+ return 0;
+ Gia_ManForEachObj( p, pObj, i )
+ Counter += (int)(Gia_ObjNext( p, i ) > 0);
+ return Counter;
+}
+
+ABC_NAMESPACE_IMPL_END
+
#include "aig.h"
#include "saig.h"
#include "cec.h"
#include "giaAig.h"
+ABC_NAMESPACE_IMPL_START
+
+
/**Function*************************************************************
Synopsis [Implements iteration during speculation.]
@@ -1428,7 +1495,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
***********************************************************************/
int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int fStart, int fCheckMiter, int fVerbose )
{
- extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig );
+// extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig );
Aig_Man_t * pTemp;
Gia_Man_t * pSrm, * pReduce, * pAux;
int nIter, nStart = 0;
@@ -1460,10 +1527,10 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f
printf( "Gia_CommandSpecI: There are only trivial equiv candidates left (PO drivers). Quitting.\n" );
break;
}
- pSrm = Gia_ManSpecReduce( pGia, 0, 0 );
+ pSrm = Gia_ManSpecReduce( pGia, 0, 0, 0 );
// bmc2 -F 100 -C 25000
{
- Gia_Cex_t * pCex;
+ Abc_Cex_t * pCex;
int nFrames = nFramesInit; // different from default
int nNodeDelta = 2000;
int nBTLimit = nBTLimitInit; // different from default
@@ -1471,7 +1538,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f
pTemp = Gia_ManToAig( pSrm, 0 );
// Aig_ManPrintStats( pTemp );
Gia_ManStop( pSrm );
- Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 20, nBTLimit, nBTLimitAll, fVerbose, 0 );
+ Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVerbose, 0, NULL );
pCex = pTemp->pSeqModel; pTemp->pSeqModel = NULL;
Aig_ManStop( pTemp );
if ( pCex == NULL )
@@ -1497,7 +1564,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f
// write equivalence classes
Gia_WriteAiger( pGia, "gore.aig", 0, 0 );
// reduce the model
- pReduce = Gia_ManSpecReduce( pGia, 0, 0 );
+ pReduce = Gia_ManSpecReduce( pGia, 0, 0, 0 );
if ( pReduce )
{
pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 );
@@ -1516,3 +1583,5 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaEra.c b/src/aig/gia/giaEra.c
new file mode 100644
index 00000000..ec3e1b1b
--- /dev/null
+++ b/src/aig/gia/giaEra.c
@@ -0,0 +1,561 @@
+/**CFile****************************************************************
+
+ FileName [giaEra.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Explicit reachability analysis.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaEra.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "mem.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// explicit state representation
+typedef struct Gia_ObjEra_t_ Gia_ObjEra_t;
+struct Gia_ObjEra_t_
+{
+ int Num; // ID of this state
+ int Cond; // input condition
+ int iPrev; // previous state
+ int iNext; // next state in the hash table
+ unsigned pData[0]; // state bits
+};
+
+// explicit state reachability
+typedef struct Gia_ManEra_t_ Gia_ManEra_t;
+struct Gia_ManEra_t_
+{
+ Gia_Man_t * pAig; // user's AIG manager
+ int nWordsSim; // 2^(PInum)
+ int nWordsDat; // Gia_BitWordNum
+ unsigned * pDataSim; // simulation data
+ Mem_Fixed_t * pMemory; // memory manager
+ Vec_Ptr_t * vStates; // reached states
+ Gia_ObjEra_t * pStateNew; // temporary state
+ int iCurState; // the current state
+ Vec_Int_t * vBugTrace; // the sequence of transitions
+ // hash table for states
+ int nBins;
+ unsigned * pBins;
+};
+
+static inline unsigned * Gia_ManEraData( Gia_ManEra_t * p, int i ) { return p->pDataSim + i * p->nWordsSim; }
+static inline Gia_ObjEra_t * Gia_ManEraState( Gia_ManEra_t * p, int i ) { return (Gia_ObjEra_t *)Vec_PtrEntry(p->vStates, i); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates reachability manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_ManEra_t * Gia_ManEraCreate( Gia_Man_t * pAig )
+{
+ Vec_Ptr_t * vTruths;
+ Gia_ManEra_t * p;
+ unsigned * pTruth, * pSimInfo;
+ int i;
+ p = ABC_CALLOC( Gia_ManEra_t, 1 );
+ p->pAig = pAig;
+ p->nWordsSim = Gia_TruthWordNum( Gia_ManPiNum(pAig) );
+ p->nWordsDat = Gia_BitWordNum( Gia_ManRegNum(pAig) );
+ p->pDataSim = ABC_ALLOC( unsigned, p->nWordsSim*Gia_ManObjNum(pAig) );
+ p->pMemory = Mem_FixedStart( sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat );
+ p->vStates = Vec_PtrAlloc( 100000 );
+ p->nBins = Gia_PrimeCudd( 100000 );
+ p->pBins = ABC_CALLOC( unsigned, p->nBins );
+ Vec_PtrPush( p->vStates, NULL );
+ // assign primary input values
+ vTruths = Vec_PtrAllocTruthTables( Gia_ManPiNum(pAig) );
+ Vec_PtrForEachEntry( unsigned *, vTruths, pTruth, i )
+ {
+ pSimInfo = Gia_ManEraData( p, Gia_ObjId(pAig, Gia_ManPi(pAig, i)) );
+ memcpy( pSimInfo, pTruth, sizeof(unsigned) * p->nWordsSim );
+ }
+ Vec_PtrFree( vTruths );
+ // assign constant zero node
+ pSimInfo = Gia_ManEraData( p, 0 );
+ memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes reachability manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEraFree( Gia_ManEra_t * p )
+{
+ Mem_FixedStop( p->pMemory, 0 );
+ Vec_PtrFree( p->vStates );
+ if ( p->vBugTrace ) Vec_IntFree( p->vBugTrace );
+ ABC_FREE( p->pDataSim );
+ ABC_FREE( p->pBins );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates new state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_ObjEra_t * Gia_ManEraCreateState( Gia_ManEra_t * p )
+{
+ Gia_ObjEra_t * pNew;
+ pNew = (Gia_ObjEra_t *)Mem_FixedEntryFetch( p->pMemory );
+ pNew->Num = Vec_PtrSize( p->vStates );
+ pNew->iPrev = 0;
+ Vec_PtrPush( p->vStates, pNew );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash value of the node using its simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEraStateHash( unsigned * pState, int nWordsSim, int nTableSize )
+{
+ static int s_FPrimes[128] = {
+ 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
+ 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
+ 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
+ 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
+ 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
+ 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
+ 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
+ 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
+ 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
+ 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
+ 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
+ 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
+ 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
+ };
+ unsigned uHash;
+ int i;
+ uHash = 0;
+ for ( i = 0; i < nWordsSim; i++ )
+ uHash ^= pState[i] * s_FPrimes[i & 0x7F];
+ return uHash % nTableSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the place of this state in the table or NULL if it exists.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned * Gia_ManEraHashFind( Gia_ManEra_t * p, Gia_ObjEra_t * pState )
+{
+ Gia_ObjEra_t * pThis;
+ unsigned * pPlace = p->pBins + Gia_ManEraStateHash( pState->pData, p->nWordsDat, p->nBins );
+ for ( pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL; pThis;
+ pPlace = (unsigned *)&pThis->iNext, pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL )
+ if ( !memcmp( pState->pData, pThis->pData, sizeof(unsigned) * p->nWordsDat ) )
+ return NULL;
+ return pPlace;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManEraHashResize( Gia_ManEra_t * p )
+{
+ Gia_ObjEra_t * pThis;
+ unsigned * pBinsOld, * piPlace;
+ int nBinsOld, iNext, Counter, i;
+ assert( p->pBins != NULL );
+ // replace the table
+ pBinsOld = p->pBins;
+ nBinsOld = p->nBins;
+ p->nBins = Gia_PrimeCudd( 3 * p->nBins );
+ p->pBins = ABC_CALLOC( unsigned, p->nBins );
+ // rehash the entries from the old table
+ Counter = 0;
+ for ( i = 0; i < nBinsOld; i++ )
+ for ( pThis = (pBinsOld[i]? Gia_ManEraState(p, pBinsOld[i]) : NULL),
+ iNext = (pThis? pThis->iNext : 0);
+ pThis; pThis = (iNext? Gia_ManEraState(p, iNext) : NULL),
+ iNext = (pThis? pThis->iNext : 0) )
+ {
+ assert( pThis->Num );
+ pThis->iNext = 0;
+ piPlace = Gia_ManEraHashFind( p, pThis );
+ assert( *piPlace == 0 ); // should not be there
+ *piPlace = pThis->Num;
+ Counter++;
+ }
+ assert( Counter == Vec_PtrSize( p->vStates ) - 1 );
+ ABC_FREE( pBinsOld );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Initialize register output to the given state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManInsertState( Gia_ManEra_t * p, Gia_ObjEra_t * pState )
+{
+ Gia_Obj_t * pObj;
+ unsigned * pSimInfo;
+ int i;
+ Gia_ManForEachRo( p->pAig, pObj, i )
+ {
+ pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) );
+ if ( Gia_InfoHasBit(pState->pData, i) )
+ memset( pSimInfo, 0xff, sizeof(unsigned) * p->nWordsSim );
+ else
+ memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns -1 if outputs are not asserted.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManOutputAsserted( Gia_ManEra_t * p, Gia_Obj_t * pObj )
+{
+ unsigned * pInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) );
+ int w;
+ for ( w = 0; w < p->nWordsSim; w++ )
+ if ( pInfo[w] )
+ return 32*w + Gia_WordFindFirstBit( pInfo[w] );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManSimulateCo( Gia_ManEra_t * p, Gia_Obj_t * pObj )
+{
+ int Id = Gia_ObjId(p->pAig, pObj);
+ unsigned * pInfo = Gia_ManEraData( p, Id );
+ unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) );
+ int w;
+ if ( Gia_ObjFaninC0(pObj) )
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = ~pInfo0[w];
+ else
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = pInfo0[w];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManSimulateNode( Gia_ManEra_t * p, Gia_Obj_t * pObj )
+{
+ int Id = Gia_ObjId(p->pAig, pObj);
+ unsigned * pInfo = Gia_ManEraData( p, Id );
+ unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) );
+ unsigned * pInfo1 = Gia_ManEraData( p, Gia_ObjFaninId1(pObj, Id) );
+ int w;
+ if ( Gia_ObjFaninC0(pObj) )
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = ~(pInfo0[w] | pInfo1[w]);
+ else
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = ~pInfo0[w] & pInfo1[w];
+ }
+ else
+ {
+ if ( Gia_ObjFaninC1(pObj) )
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = pInfo0[w] & ~pInfo1[w];
+ else
+ for ( w = p->nWordsSim-1; w >= 0; w-- )
+ pInfo[w] = pInfo0[w] & pInfo1[w];
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one iteration of reachability analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPerformOneIter( Gia_ManEra_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObj1( p->pAig, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManSimulateNode( p, pObj );
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ManSimulateCo( p, pObj );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one iteration of reachability analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCollectBugTrace( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int iCond )
+{
+ Vec_Int_t * vTrace;
+ vTrace = Vec_IntAlloc( 10 );
+ Vec_IntPush( vTrace, iCond );
+ for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL )
+ Vec_IntPush( vTrace, pState->Cond );
+ Vec_IntReverseOrder( vTrace );
+ return vTrace;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the depth of state transitions leading ot this state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountDepth( Gia_ManEra_t * p )
+{
+ Gia_ObjEra_t * pState;
+ int Counter = 0;
+ pState = (Gia_ObjEra_t *)Vec_PtrEntryLast( p->vStates );
+ if ( pState->iPrev == 0 && Vec_PtrSize(p->vStates) > 3 )
+ pState = (Gia_ObjEra_t *)Vec_PtrEntry( p->vStates, Vec_PtrSize(p->vStates) - 2 );
+ for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL )
+ Counter++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Analized reached states.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAnalyzeResult( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int fMiter )
+{
+ Gia_Obj_t * pObj;
+ unsigned * pSimInfo, * piPlace;
+ int i, k, iCond, nMints;
+ // check if the miter is asserted
+ if ( fMiter )
+ {
+ Gia_ManForEachPo( p->pAig, pObj, i )
+ {
+ iCond = Gia_ManOutputAsserted( p, pObj );
+ if ( iCond >= 0 )
+ {
+ p->vBugTrace = Gia_ManCollectBugTrace( p, pState, iCond );
+ return 1;
+ }
+ }
+ }
+ // collect reached states
+ nMints = (1 << Gia_ManPiNum(p->pAig));
+ for ( k = 0; k < nMints; k++ )
+ {
+ if ( p->pStateNew == NULL )
+ p->pStateNew = Gia_ManEraCreateState( p );
+ p->pStateNew->pData[p->nWordsDat-1] = 0;
+ Gia_ManForEachRi( p->pAig, pObj, i )
+ {
+ pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) );
+ if ( Gia_InfoHasBit(p->pStateNew->pData, i) != Gia_InfoHasBit(pSimInfo, k) )
+ Gia_InfoXorBit( p->pStateNew->pData, i );
+ }
+ piPlace = Gia_ManEraHashFind( p, p->pStateNew );
+ if ( piPlace == NULL )
+ continue;
+//printf( "Inserting %d ", Vec_PtrSize(p->vStates) );
+//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" );
+ assert( *piPlace == 0 );
+ *piPlace = p->pStateNew->Num;
+ p->pStateNew->Cond = k;
+ p->pStateNew->iPrev = pState->Num;
+ p->pStateNew->iNext = 0;
+ p->pStateNew = NULL;
+ // expand hash table if needed
+ if ( Vec_PtrSize(p->vStates) > 2 * p->nBins )
+ Gia_ManEraHashResize( p );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCollectReachable( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose )
+{
+ Gia_ManEra_t * p;
+ Gia_ObjEra_t * pState;
+ int Hash, clk = clock();
+ int RetValue = 1;
+ assert( Gia_ManPiNum(pAig) <= 12 );
+ assert( Gia_ManRegNum(pAig) > 0 );
+ p = Gia_ManEraCreate( pAig );
+ // create init state
+ pState = Gia_ManEraCreateState( p );
+ pState->Cond = 0;
+ pState->iPrev = 0;
+ pState->iNext = 0;
+ memset( pState->pData, 0, sizeof(unsigned) * p->nWordsDat );
+ Hash = Gia_ManEraStateHash(pState->pData, p->nWordsDat, p->nBins);
+ p->pBins[ Hash ] = pState->Num;
+ // process reachable states
+ while ( p->iCurState < Vec_PtrSize( p->vStates ) - 1 )
+ {
+ if ( Vec_PtrSize(p->vStates) >= nStatesMax )
+ {
+ printf( "Reached the limit on states traversed (%d). ", nStatesMax );
+ RetValue = -1;
+ break;
+ }
+ pState = Gia_ManEraState( p, ++p->iCurState );
+ if ( p->iCurState > 1 && pState->iPrev == 0 )
+ continue;
+//printf( "Extracting %d ", p->iCurState );
+//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" );
+ Gia_ManInsertState( p, pState );
+ Gia_ManPerformOneIter( p );
+ if ( Gia_ManAnalyzeResult( p, pState, fMiter ) && fMiter )
+ {
+ RetValue = 0;
+ printf( "Miter failed in state %d after %d transitions. ",
+ p->iCurState, Vec_IntSize(p->vBugTrace)-1 );
+ break;
+ }
+ if ( fVerbose && p->iCurState % 5000 == 0 )
+ {
+ printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ",
+ p->iCurState, Vec_PtrSize(p->vStates), 1.0*p->iCurState/Vec_PtrSize(p->vStates), Gia_ManCountDepth(p),
+ (1.0/(1<<20))*(1.0*Vec_PtrSize(p->vStates)*(sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat) +
+ 1.0*p->nBins*sizeof(unsigned) + 1.0*p->vStates->nCap * sizeof(void*)) );
+ ABC_PRT( "Time", clock() - clk );
+ }
+ }
+ printf( "Reachability analysis traversed %d states with depth %d. ", p->iCurState-1, Gia_ManCountDepth(p) );
+ ABC_PRT( "Time", clock() - clk );
+ Gia_ManEraFree( p );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaEra2.c b/src/aig/gia/giaEra2.c
new file mode 100644
index 00000000..64464832
--- /dev/null
+++ b/src/aig/gia/giaEra2.c
@@ -0,0 +1,1954 @@
+/**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"
+#include "giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+/*
+ Limitations of this package:
+ - no more than (1<<31)-1 state cubes and internal nodes
+ - no more than MAX_VARS_NUM state variables
+ - no more than MAX_CALL_NUM transitions from a state
+ - cube list rebalancing happens when cube count reaches MAX_CUBE_NUM
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_CALL_NUM (1000000) // the max number of recursive calls
+#define MAX_ITEM_NUM (1<<20) // the number of items on a page
+#define MAX_PAGE_NUM (1<<11) // the max number of memory pages
+#define MAX_VARS_NUM (1<<14) // the max number of state vars allowed
+#define MAX_CUBE_NUM 63 // the max number of cubes before rebalancing
+
+// pointer to the tree node or state cube
+typedef struct Gia_PtrAre_t_ Gia_PtrAre_t;
+struct Gia_PtrAre_t_
+{
+ unsigned nItem : 20; // item number (related to MAX_ITEM_NUM)
+ unsigned nPage : 11; // page number (related to MAX_PAGE_NUM)
+ unsigned fMark : 1; // user mark
+};
+
+// tree nodes
+typedef struct Gia_ObjAre_t_ Gia_ObjAre_t;
+struct Gia_ObjAre_t_
+{
+ unsigned iVar : 14; // variable (related to MAX_VARS_NUM)
+ unsigned nStas0 : 6; // cube counter (related to MAX_CUBE_NUM)
+ unsigned nStas1 : 6; // cube counter (related to MAX_CUBE_NUM)
+ unsigned nStas2 : 6; // cube counter (related to MAX_CUBE_NUM)
+ Gia_PtrAre_t F[3]; // branches
+};
+
+// state cube
+typedef struct Gia_StaAre_t_ Gia_StaAre_t;
+struct Gia_StaAre_t_
+{
+ Gia_PtrAre_t iPrev; // previous state
+ Gia_PtrAre_t iNext; // next cube in the list
+ unsigned pData[0]; // state bits
+};
+
+// explicit state reachability manager
+typedef struct Gia_ManAre_t_ Gia_ManAre_t;
+struct Gia_ManAre_t_
+{
+ Gia_Man_t * pAig; // user's AIG manager
+ Gia_Man_t * pNew; // temporary AIG manager
+ unsigned ** ppObjs; // storage for objects (MAX_PAGE_NUM pages)
+ unsigned ** ppStas; // storage for states (MAX_PAGE_NUM pages)
+// unsigned * pfUseless; // to label useless cubes
+// int nUselessAlloc; // the number of useless alloced
+ // internal flags
+ int fMiter; // stops when a bug is discovered
+ int fStopped; // set high when reachability is stopped
+ int fTree; // working in the tree mode
+ // internal parametesr
+ int nWords; // the size of bit info in words
+ int nSize; // the size of state structure in words
+ int nObjPages; // the number of pages used for objects
+ int nStaPages; // the number of pages used for states
+ int nObjs; // the number of objects
+ int nStas; // the number of states
+ int iStaCur; // the next state to be explored
+ Gia_PtrAre_t Root; // root of the tree
+ Vec_Vec_t * vCiTfos; // storage for nodes in the CI TFOs
+ Vec_Vec_t * vCiLits; // storage for literals of these nodes
+ Vec_Int_t * vCubesA; // checked cubes
+ Vec_Int_t * vCubesB; // unchecked cubes
+ // deriving counter-example
+ void * pSat; // SAT solver
+ Vec_Int_t * vSatNumCis; // SAT variables for CIs
+ Vec_Int_t * vSatNumCos; // SAT variables for COs
+ Vec_Int_t * vCofVars; // variables used to cofactor
+ Vec_Int_t * vAssumps; // temporary storage for assumptions
+ Gia_StaAre_t * pTarget; // state that needs to be reached
+ int iOutFail; // the number of the failed output
+ // statistics
+ int nChecks; // the number of timea cube was checked
+ int nEquals; // total number of equal
+ int nCompares; // the number of compares
+ int nRecCalls; // the number of rec calls
+ int nDisjs; // the number of disjoint cube pairs
+ int nDisjs2; // the number of disjoint cube pairs
+ int nDisjs3; // the number of disjoint cube pairs
+ // time
+ int timeAig; // AIG cofactoring time
+ int timeCube; // cube checking time
+};
+
+static inline Gia_PtrAre_t Gia_Int2Ptr( unsigned n ) { return *(Gia_PtrAre_t *)(&n); }
+static inline unsigned Gia_Ptr2Int( Gia_PtrAre_t n ) { return (*(int *)(&n)) & 0x7fffffff; }
+
+static inline int Gia_ObjHasBranch0( Gia_ObjAre_t * q ) { return !q->nStas0 && (q->F[0].nPage || q->F[0].nItem); }
+static inline int Gia_ObjHasBranch1( Gia_ObjAre_t * q ) { return !q->nStas1 && (q->F[1].nPage || q->F[1].nItem); }
+static inline int Gia_ObjHasBranch2( Gia_ObjAre_t * q ) { return !q->nStas2 && (q->F[2].nPage || q->F[2].nItem); }
+
+static inline Gia_ObjAre_t * Gia_ManAreObj( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_ObjAre_t *)(p->ppObjs[n.nPage] + (n.nItem << 2)); }
+static inline Gia_StaAre_t * Gia_ManAreSta( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_StaAre_t *)(p->ppStas[n.nPage] + n.nItem * p->nSize); }
+static inline Gia_ObjAre_t * Gia_ManAreObjInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreObj( p, Gia_Int2Ptr(n) ); }
+static inline Gia_StaAre_t * Gia_ManAreStaInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreSta( p, Gia_Int2Ptr(n) ); }
+static inline Gia_ObjAre_t * Gia_ManAreObjLast( Gia_ManAre_t * p ) { return Gia_ManAreObjInt( p, p->nObjs-1 ); }
+static inline Gia_StaAre_t * Gia_ManAreStaLast( Gia_ManAre_t * p ) { return Gia_ManAreStaInt( p, p->nStas-1 ); }
+
+static inline Gia_ObjAre_t * Gia_ObjNextObj0( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[0] ); }
+static inline Gia_ObjAre_t * Gia_ObjNextObj1( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[1] ); }
+static inline Gia_ObjAre_t * Gia_ObjNextObj2( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[2] ); }
+
+static inline int Gia_StaHasValue0( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, iReg << 1 ); }
+static inline int Gia_StaHasValue1( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, (iReg << 1) + 1 ); }
+
+static inline void Gia_StaSetValue0( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, iReg << 1 ); }
+static inline void Gia_StaSetValue1( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, (iReg << 1) + 1 ); }
+
+static inline Gia_StaAre_t * Gia_StaPrev( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iPrev); }
+static inline Gia_StaAre_t * Gia_StaNext( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iNext); }
+static inline int Gia_StaIsGood( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return ((unsigned *)pS) != p->ppStas[0]; }
+
+static inline void Gia_StaSetUnused( Gia_StaAre_t * pS ) { pS->iPrev.fMark = 1; }
+static inline int Gia_StaIsUnused( Gia_StaAre_t * pS ) { return pS->iPrev.fMark; }
+static inline int Gia_StaIsUsed( Gia_StaAre_t * pS ) { return !pS->iPrev.fMark; }
+
+#define Gia_ManAreForEachCubeList( p, pList, pCube ) \
+ for ( pCube = pList; Gia_StaIsGood(p, pCube); pCube = Gia_StaNext(p, pCube) )
+#define Gia_ManAreForEachCubeList2( p, iList, pCube, iCube ) \
+ for ( iCube = Gia_Ptr2Int(iList), pCube = Gia_ManAreSta(p, iList); \
+ Gia_StaIsGood(p, pCube); \
+ iCube = Gia_Ptr2Int(pCube->iNext), pCube = Gia_StaNext(p, pCube) )
+#define Gia_ManAreForEachCubeStore( p, pCube, i ) \
+ for ( i = 1; i < p->nStas && (pCube = Gia_ManAreStaInt(p, i)); i++ )
+#define Gia_ManAreForEachCubeVec( vVec, p, pCube, i ) \
+ for ( i = 0; i < Vec_IntSize(vVec) && (pCube = Gia_ManAreStaInt(p, Vec_IntEntry(vVec,i))); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Count state minterms contained in a cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCountMintermsInCube( Gia_StaAre_t * pCube, int nVars, unsigned * pStore )
+{
+ unsigned Mint, Mask = 0;
+ int i, m, nMints, nDashes = 0, Dashes[32];
+ // count the number of dashes
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( Gia_StaHasValue0( pCube, i ) )
+ continue;
+ if ( Gia_StaHasValue1( pCube, i ) )
+ Mask |= (1 << i);
+ else
+ Dashes[nDashes++] = i;
+ }
+ // fill in the miterms
+ nMints = (1 << nDashes);
+ for ( m = 0; m < nMints; m++ )
+ {
+ Mint = Mask;
+ for ( i = 0; i < nVars; i++ )
+ if ( m & (1 << i) )
+ Mint |= (1 << Dashes[i]);
+ Gia_InfoSetBit( pStore, Mint );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count state minterms contains in the used cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountMinterms( Gia_ManAre_t * p )
+{
+ Gia_StaAre_t * pCube;
+ unsigned * pMemory;
+ int i, nMemSize, Counter = 0;
+ if ( Gia_ManRegNum(p->pAig) > 30 )
+ return -1;
+ nMemSize = Gia_BitWordNum( 1 << Gia_ManRegNum(p->pAig) );
+ pMemory = ABC_CALLOC( unsigned, nMemSize );
+ Gia_ManAreForEachCubeStore( p, pCube, i )
+ if ( Gia_StaIsUsed(pCube) )
+ Gia_ManCountMintermsInCube( pCube, Gia_ManRegNum(p->pAig), pMemory );
+ for ( i = 0; i < nMemSize; i++ )
+ Counter += Gia_WordCountOnes( pMemory[i] );
+ ABC_FREE( pMemory );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the TFO of one CI.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManDeriveCiTfo_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRes )
+{
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark0;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes );
+ Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin1(pObj), vRes );
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 | Gia_ObjFanin1(pObj)->fMark0;
+ if ( pObj->fMark0 )
+ Vec_IntPush( vRes, Gia_ObjId(p, pObj) );
+ return pObj->fMark0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the TFO of one CI.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManDeriveCiTfoOne( Gia_Man_t * p, Gia_Obj_t * pPivot )
+{
+ Vec_Int_t * vRes;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( pPivot->fMark0 == 0 );
+ pPivot->fMark0 = 1;
+ vRes = Vec_IntAlloc( 100 );
+ Vec_IntPush( vRes, Gia_ObjId(p, pPivot) );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes );
+ if ( Gia_ObjFanin0(pObj)->fMark0 )
+ Vec_IntPush( vRes, Gia_ObjId(p, pObj) );
+ }
+ pPivot->fMark0 = 0;
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the TFO of each CI.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Vec_t * Gia_ManDeriveCiTfo( Gia_Man_t * p )
+{
+ Vec_Ptr_t * vRes;
+ Gia_Obj_t * pPivot;
+ int i;
+ Gia_ManCleanMark0( p );
+ Gia_ManIncrementTravId( p );
+ vRes = Vec_PtrAlloc( Gia_ManCiNum(p) );
+ Gia_ManForEachCi( p, pPivot, i )
+ Vec_PtrPush( vRes, Gia_ManDeriveCiTfoOne(p, pPivot) );
+ Gia_ManCleanMark0( p );
+ return (Vec_Vec_t *)vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if states are equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreEqual( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( p1->pData[w] != p2->pData[w] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if states are disjoint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreDisjoint( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( ((p1->pData[w] ^ p2->pData[w]) >> 1) & (p1->pData[w] ^ p2->pData[w]) & 0x55555555 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if cube p1 contains cube p2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreContain( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( (p1->pData[w] | p2->pData[w]) != p2->pData[w] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of dashes in p1 that are non-dashes in p2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreDashNum( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ int w, Counter = 0;
+ for ( w = 0; w < nWords; w++ )
+ Counter += Gia_WordCountOnes( (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555 );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of a variable for sharping the cube.]
+
+ Description [Counts the number of variables that have dash in p1 and
+ non-dash in p2. If there is exactly one such variable, returns its index.
+ Otherwise returns -1.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreSharpVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ unsigned Word;
+ int w, iVar = -1;
+ for ( w = 0; w < nWords; w++ )
+ {
+ Word = (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555;
+ if ( Word == 0 )
+ continue;
+ if ( !Gia_WordHasOneBit(Word) )
+ return -1;
+ // has exactly one bit
+ if ( iVar >= 0 )
+ return -1;
+ // the first variable of this type
+ iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2;
+ }
+ return iVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of a variable for merging the cubes.]
+
+ Description [If there is exactly one such variable, returns its index.
+ Otherwise returns -1.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_StaAreDisjointVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords )
+{
+ unsigned Word;
+ int w, iVar = -1;
+ for ( w = 0; w < nWords; w++ )
+ {
+ Word = (p1->pData[w] ^ p2->pData[w]) & ((p1->pData[w] ^ p2->pData[w]) >> 1) & 0x55555555;
+ if ( Word == 0 )
+ continue;
+ if ( !Gia_WordHasOneBit(Word) )
+ return -1;
+ // has exactly one bit
+ if ( iVar >= 0 )
+ return -1;
+ // the first variable of this type
+ iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2;
+ }
+ return iVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates reachability manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_ManAre_t * Gia_ManAreCreate( Gia_Man_t * pAig )
+{
+ Gia_ManAre_t * p;
+ assert( sizeof(Gia_ObjAre_t) == 16 );
+ p = ABC_CALLOC( Gia_ManAre_t, 1 );
+ p->pAig = pAig;
+ p->nWords = Gia_BitWordNum( 2 * Gia_ManRegNum(pAig) );
+ p->nSize = sizeof(Gia_StaAre_t)/4 + p->nWords;
+ p->ppObjs = ABC_CALLOC( unsigned *, MAX_PAGE_NUM );
+ p->ppStas = ABC_CALLOC( unsigned *, MAX_PAGE_NUM );
+ p->vCiTfos = Gia_ManDeriveCiTfo( pAig );
+ p->vCiLits = Vec_VecDupInt( p->vCiTfos );
+ p->vCubesA = Vec_IntAlloc( 100 );
+ p->vCubesB = Vec_IntAlloc( 100 );
+ p->iOutFail = -1;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes reachability manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreFree( Gia_ManAre_t * p )
+{
+ int i;
+ Gia_ManStop( p->pAig );
+ if ( p->pNew )
+ Gia_ManStop( p->pNew );
+ Vec_IntFree( p->vCubesA );
+ Vec_IntFree( p->vCubesB );
+ Vec_VecFree( p->vCiTfos );
+ Vec_VecFree( p->vCiLits );
+ for ( i = 0; i < p->nObjPages; i++ )
+ ABC_FREE( p->ppObjs[i] );
+ ABC_FREE( p->ppObjs );
+ for ( i = 0; i < p->nStaPages; i++ )
+ ABC_FREE( p->ppStas[i] );
+ ABC_FREE( p->ppStas );
+// ABC_FREE( p->pfUseless );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns new object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_ObjAre_t * Gia_ManAreCreateObj( Gia_ManAre_t * p )
+{
+ if ( p->nObjs == p->nObjPages * MAX_ITEM_NUM )
+ {
+ if ( p->nObjPages == MAX_PAGE_NUM )
+ {
+ printf( "ERA manager has run out of memory after allocating 2B internal nodes.\n" );
+ return NULL;
+ }
+ p->ppObjs[p->nObjPages++] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * 4 );
+ if ( p->nObjs == 0 )
+ p->nObjs = 1;
+ }
+ return Gia_ManAreObjInt( p, p->nObjs++ );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns new state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_StaAre_t * Gia_ManAreCreateSta( Gia_ManAre_t * p )
+{
+ if ( p->nStas == p->nStaPages * MAX_ITEM_NUM )
+ {
+ if ( p->nStaPages == MAX_PAGE_NUM )
+ {
+ printf( "ERA manager has run out of memory after allocating 2B state cubes.\n" );
+ return NULL;
+ }
+ if ( p->ppStas[p->nStaPages] == NULL )
+ p->ppStas[p->nStaPages] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * p->nSize );
+ p->nStaPages++;
+ if ( p->nStas == 0 )
+ {
+ p->nStas = 1;
+// p->nUselessAlloc = (1 << 18);
+// p->pfUseless = ABC_CALLOC( unsigned, p->nUselessAlloc );
+ }
+// if ( p->nStas == p->nUselessAlloc * 32 )
+// {
+// p->nUselessAlloc *= 2;
+// p->pfUseless = ABC_REALLOC( unsigned, p->pfUseless, p->nUselessAlloc );
+// memset( p->pfUseless + p->nUselessAlloc/2, 0, sizeof(unsigned) * p->nUselessAlloc/2 );
+// }
+ }
+ return Gia_ManAreStaInt( p, p->nStas++ );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles new state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManAreRycycleSta( Gia_ManAre_t * p, Gia_StaAre_t * pSta )
+{
+ memset( pSta, 0, p->nSize << 2 );
+ if ( pSta == Gia_ManAreStaLast(p) )
+ {
+ p->nStas--;
+ if ( p->nStas == (p->nStaPages-1) * MAX_ITEM_NUM )
+ p->nStaPages--;
+ }
+ else
+ {
+// Gia_StaSetUnused( pSta );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates new state state from the latch values.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_StaAre_t * Gia_ManAreCreateStaNew( Gia_ManAre_t * p )
+{
+ Gia_StaAre_t * pSta;
+ Gia_Obj_t * pObj;
+ int i;
+ pSta = Gia_ManAreCreateSta( p );
+ Gia_ManForEachRi( p->pAig, pObj, i )
+ {
+ if ( pObj->Value == 0 )
+ Gia_StaSetValue0( pSta, i );
+ else if ( pObj->Value == 1 )
+ Gia_StaSetValue1( pSta, i );
+ }
+ return pSta;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates new state state with latch init values.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_StaAre_t * Gia_ManAreCreateStaInit( Gia_ManAre_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachRi( p->pAig, pObj, i )
+ pObj->Value = 0;
+ return Gia_ManAreCreateStaNew( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the state cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManArePrintCube( Gia_ManAre_t * p, Gia_StaAre_t * pSta )
+{
+ Gia_Obj_t * pObj;
+ int i, Count0 = 0, Count1 = 0, Count2 = 0;
+ printf( "%4d %4d : ", p->iStaCur, p->nStas-1 );
+ printf( "Prev %4d ", Gia_Ptr2Int(pSta->iPrev) );
+ printf( "%p ", pSta );
+ Gia_ManForEachRi( p->pAig, pObj, i )
+ {
+ if ( Gia_StaHasValue0(pSta, i) )
+ printf( "0" ), Count0++;
+ else if ( Gia_StaHasValue1(pSta, i) )
+ printf( "1" ), Count1++;
+ else
+ printf( "-" ), Count2++;
+ }
+ printf( " 0 =%3d", Count0 );
+ printf( " 1 =%3d", Count1 );
+ printf( " - =%3d", Count2 );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the depth of state transitions leading ot this state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreDepth( Gia_ManAre_t * p, int iState )
+{
+ Gia_StaAre_t * pSta;
+ int Counter = 0;
+ for ( pSta = Gia_ManAreStaInt(p, iState); Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) )
+ Counter++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of cubes in the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManAreListCountListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root )
+{
+ Gia_StaAre_t * pCube;
+ int Counter = 0;
+ Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube )
+ Counter += Gia_StaIsUsed(pCube);
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of used cubes in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreListCountUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree )
+{
+ Gia_ObjAre_t * pObj;
+ if ( !fTree )
+ return Gia_ManAreListCountListUsed( p, Root );
+ pObj = Gia_ManAreObj(p, Root);
+ return Gia_ManAreListCountUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) +
+ Gia_ManAreListCountUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) +
+ Gia_ManAreListCountUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of used cubes in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManAreListCountUsed( Gia_ManAre_t * p )
+{
+ return Gia_ManAreListCountUsed_rec( p, p->Root, p->fTree );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints used cubes in the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManArePrintListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root )
+{
+ Gia_StaAre_t * pCube;
+ Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube )
+ if ( Gia_StaIsUsed(pCube) )
+ Gia_ManArePrintCube( p, pCube );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints used cubes in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManArePrintUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree )
+{
+ Gia_ObjAre_t * pObj;
+ if ( !fTree )
+ return Gia_ManArePrintListUsed( p, Root );
+ pObj = Gia_ManAreObj(p, Root);
+ return Gia_ManArePrintUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) +
+ Gia_ManArePrintUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) +
+ Gia_ManArePrintUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints used cubes in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManArePrintUsed( Gia_ManAre_t * p )
+{
+ return Gia_ManArePrintUsed_rec( p, p->Root, p->fTree );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Best var has max weight.]
+
+ Description [Weight is defined as the number of 0/1-lits minus the
+ absolute value of the diff between the number of 0-lits and 1-lits.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreFindBestVar( Gia_ManAre_t * p, Gia_PtrAre_t List )
+{
+ Gia_StaAre_t * pCube;
+ int Count0, Count1, Count2;
+ int iVarThis, iVarBest = -1, WeightThis, WeightBest = -1;
+ for ( iVarThis = 0; iVarThis < Gia_ManRegNum(p->pAig); iVarThis++ )
+ {
+ Count0 = Count1 = Count2 = 0;
+ Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, List), pCube )
+ {
+ if ( Gia_StaIsUnused(pCube) )
+ continue;
+ if ( Gia_StaHasValue0(pCube, iVarThis) )
+ Count0++;
+ else if ( Gia_StaHasValue1(pCube, iVarThis) )
+ Count1++;
+ else
+ Count2++;
+ }
+// printf( "%4d : %5d %5d %5d Weight = %5d\n", iVarThis, Count0, Count1, Count2,
+// Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0) );
+ if ( (!Count0 && !Count1) || (!Count0 && !Count2) || (!Count1 && !Count2) )
+ continue;
+ WeightThis = Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0);
+ if ( WeightBest < WeightThis )
+ {
+ WeightBest = WeightThis;
+ iVarBest = iVarThis;
+ }
+ }
+ if ( iVarBest == -1 )
+ {
+ Gia_ManArePrintListUsed( p, List );
+ printf( "Error: Best variable not found!!!\n" );
+ }
+ assert( iVarBest != -1 );
+ return iVarBest;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Rebalances the tree when cubes exceed the limit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManAreRebalance( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot )
+{
+ Gia_ObjAre_t * pNode;
+ Gia_StaAre_t * pCube;
+ Gia_PtrAre_t iCube, iNext;
+ assert( pRoot->nItem || pRoot->nPage );
+ pNode = Gia_ManAreCreateObj( p );
+ pNode->iVar = Gia_ManAreFindBestVar( p, *pRoot );
+ for ( iCube = *pRoot, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext;
+ Gia_StaIsGood(p, pCube);
+ iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext )
+ {
+ if ( Gia_StaIsUnused(pCube) )
+ continue;
+ if ( Gia_StaHasValue0(pCube, pNode->iVar) )
+ pCube->iNext = pNode->F[0], pNode->F[0] = iCube, pNode->nStas0++;
+ else if ( Gia_StaHasValue1(pCube, pNode->iVar) )
+ pCube->iNext = pNode->F[1], pNode->F[1] = iCube, pNode->nStas1++;
+ else
+ pCube->iNext = pNode->F[2], pNode->F[2] = iCube, pNode->nStas2++;
+ }
+ *pRoot = Gia_Int2Ptr(p->nObjs - 1);
+ assert( pNode == Gia_ManAreObj(p, *pRoot) );
+ p->fTree = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compresses the list by removing unused cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManAreCompress( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot )
+{
+ Gia_StaAre_t * pCube;
+ Gia_PtrAre_t iList = *pRoot;
+ Gia_PtrAre_t iCube, iNext;
+ assert( pRoot->nItem || pRoot->nPage );
+ pRoot->nItem = 0;
+ pRoot->nPage = 0;
+ for ( iCube = iList, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext;
+ Gia_StaIsGood(p, pCube);
+ iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext )
+ {
+ if ( Gia_StaIsUnused(pCube) )
+ continue;
+ pCube->iNext = *pRoot;
+ *pRoot = iCube;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the state exists in the list.]
+
+ Description [The state may be sharped.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManAreCubeCheckList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta )
+{
+ int fVerbose = 0;
+ Gia_StaAre_t * pCube;
+ int iVar;
+if ( fVerbose )
+{
+printf( "Trying cube: " );
+Gia_ManArePrintCube( p, pSta );
+}
+ Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, *pRoot), pCube )
+ {
+ p->nChecks++;
+ if ( Gia_StaIsUnused( pCube ) )
+ continue;
+ if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) )
+ continue;
+ if ( Gia_StaAreContain( pCube, pSta, p->nWords ) )
+ {
+if ( fVerbose )
+{
+printf( "Contained in " );
+Gia_ManArePrintCube( p, pCube );
+}
+ Gia_ManAreRycycleSta( p, pSta );
+ return 0;
+ }
+ if ( Gia_StaAreContain( pSta, pCube, p->nWords ) )
+ {
+if ( fVerbose )
+{
+printf( "Contains " );
+Gia_ManArePrintCube( p, pCube );
+}
+ Gia_StaSetUnused( pCube );
+ continue;
+ }
+ iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords );
+ if ( iVar == -1 )
+ continue;
+if ( fVerbose )
+{
+printf( "Sharped by " );
+Gia_ManArePrintCube( p, pCube );
+Gia_ManArePrintCube( p, pSta );
+}
+// printf( "%d %d\n", Gia_StaAreDashNum( pSta, pCube, p->nWords ), Gia_StaAreSharpVar( pSta, pCube, p->nWords ) );
+ assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) );
+ assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) );
+ if ( Gia_StaHasValue0(pCube, iVar) )
+ Gia_StaSetValue1( pSta, iVar );
+ else
+ Gia_StaSetValue0( pSta, iVar );
+// return Gia_ManAreCubeCheckList( p, pRoot, pSta );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds new state to the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManAreCubeAddToList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta )
+{
+ int fVerbose = 0;
+ pSta->iNext = *pRoot;
+ *pRoot = Gia_Int2Ptr( p->nStas - 1 );
+ assert( pSta == Gia_ManAreSta(p, *pRoot) );
+if ( fVerbose )
+{
+printf( "Adding cube: " );
+Gia_ManArePrintCube( p, pSta );
+//printf( "\n" );
+}
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cube like this exists in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreCubeCheckTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta )
+{
+ int RetValue;
+ if ( Gia_StaHasValue0(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch0(pObj) )
+ RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta );
+ else
+ RetValue = Gia_ManAreCubeCheckList( p, pObj->F, pSta );
+ if ( RetValue == 0 )
+ return 0;
+ }
+ else if ( Gia_StaHasValue1(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch1(pObj) )
+ RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta );
+ else
+ RetValue = Gia_ManAreCubeCheckList( p, pObj->F + 1, pSta );
+ if ( RetValue == 0 )
+ return 0;
+ }
+ if ( Gia_ObjHasBranch2(pObj) )
+ return Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta );
+ return Gia_ManAreCubeCheckList( p, pObj->F + 2, pSta );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds new cube to the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreCubeAddToTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta )
+{
+ if ( Gia_StaHasValue0(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch0(pObj) )
+ Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta );
+ else
+ {
+ Gia_ManAreCubeAddToList( p, pObj->F, pSta );
+ if ( ++pObj->nStas0 == MAX_CUBE_NUM )
+ {
+ pObj->nStas0 = Gia_ManAreListCountListUsed( p, pObj->F[0] );
+ if ( pObj->nStas0 < MAX_CUBE_NUM/2 )
+ Gia_ManAreCompress( p, pObj->F );
+ else
+ {
+ Gia_ManAreRebalance( p, pObj->F );
+ pObj->nStas0 = 0;
+ }
+ }
+ }
+ }
+ else if ( Gia_StaHasValue1(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch1(pObj) )
+ Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta );
+ else
+ {
+ Gia_ManAreCubeAddToList( p, pObj->F+1, pSta );
+ if ( ++pObj->nStas1 == MAX_CUBE_NUM )
+ {
+ pObj->nStas1 = Gia_ManAreListCountListUsed( p, pObj->F[1] );
+ if ( pObj->nStas1 < MAX_CUBE_NUM/2 )
+ Gia_ManAreCompress( p, pObj->F+1 );
+ else
+ {
+ Gia_ManAreRebalance( p, pObj->F+1 );
+ pObj->nStas1 = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( Gia_ObjHasBranch2(pObj) )
+ Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta );
+ else
+ {
+ Gia_ManAreCubeAddToList( p, pObj->F+2, pSta );
+ if ( ++pObj->nStas2 == MAX_CUBE_NUM )
+ {
+ pObj->nStas2 = Gia_ManAreListCountListUsed( p, pObj->F[2] );
+ if ( pObj->nStas2 < MAX_CUBE_NUM/2 )
+ Gia_ManAreCompress( p, pObj->F+2 );
+ else
+ {
+ Gia_ManAreRebalance( p, pObj->F+2 );
+ pObj->nStas2 = 0;
+ }
+ }
+ }
+ }
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects overlapping cubes in the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManAreCubeCollectList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta )
+{
+ Gia_StaAre_t * pCube;
+ int iCube;
+ Gia_ManAreForEachCubeList2( p, *pRoot, pCube, iCube )
+ {
+ if ( Gia_StaIsUnused( pCube ) )
+ continue;
+ if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) )
+ {
+/*
+ int iVar;
+ p->nDisjs++;
+ iVar = Gia_StaAreDisjointVar( pSta, pCube, p->nWords );
+ if ( iVar >= 0 )
+ {
+ p->nDisjs2++;
+ if ( iCube > p->iStaCur )
+ p->nDisjs3++;
+ }
+*/
+ continue;
+ }
+// p->nCompares++;
+// p->nEquals += Gia_StaAreEqual( pSta, pCube, p->nWords );
+ if ( iCube <= p->iStaCur )
+ Vec_IntPush( p->vCubesA, iCube );
+ else
+ Vec_IntPush( p->vCubesB, iCube );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects overlapping cubes in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreCubeCollectTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta )
+{
+ int RetValue;
+ if ( Gia_StaHasValue0(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch0(pObj) )
+ RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta );
+ else
+ RetValue = Gia_ManAreCubeCollectList( p, pObj->F, pSta );
+ if ( RetValue == 0 )
+ return 0;
+ }
+ else if ( Gia_StaHasValue1(pSta, pObj->iVar) )
+ {
+ if ( Gia_ObjHasBranch1(pObj) )
+ RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta );
+ else
+ RetValue = Gia_ManAreCubeCollectList( p, pObj->F + 1, pSta );
+ if ( RetValue == 0 )
+ return 0;
+ }
+ if ( Gia_ObjHasBranch2(pObj) )
+ return Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta );
+ return Gia_ManAreCubeCollectList( p, pObj->F + 2, pSta );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cube like this exists in the tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreCubeCheckTree( Gia_ManAre_t * p, Gia_StaAre_t * pSta )
+{
+ Gia_StaAre_t * pCube;
+ int i, iVar;
+ assert( p->fTree );
+ Vec_IntClear( p->vCubesA );
+ Vec_IntClear( p->vCubesB );
+ Gia_ManAreCubeCollectTree_rec( p, Gia_ManAreObj(p, p->Root), pSta );
+// if ( p->nStas > 3000 )
+// printf( "%d %d \n", Vec_IntSize(p->vCubesA), Vec_IntSize(p->vCubesB) );
+// Vec_IntSort( p->vCubesA, 0 );
+// Vec_IntSort( p->vCubesB, 0 );
+ Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i )
+ {
+ if ( Gia_StaIsUnused( pCube ) )
+ continue;
+ if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) )
+ continue;
+ if ( Gia_StaAreContain( pCube, pSta, p->nWords ) )
+ {
+ Gia_ManAreRycycleSta( p, pSta );
+ return 0;
+ }
+ if ( Gia_StaAreContain( pSta, pCube, p->nWords ) )
+ {
+ Gia_StaSetUnused( pCube );
+ continue;
+ }
+ iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords );
+ if ( iVar == -1 )
+ continue;
+ assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) );
+ assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) );
+ if ( Gia_StaHasValue0(pCube, iVar) )
+ Gia_StaSetValue1( pSta, iVar );
+ else
+ Gia_StaSetValue0( pSta, iVar );
+ return Gia_ManAreCubeCheckTree( p, pSta );
+ }
+ Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i )
+ {
+ if ( Gia_StaIsUnused( pCube ) )
+ continue;
+ if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) )
+ continue;
+ if ( Gia_StaAreContain( pCube, pSta, p->nWords ) )
+ {
+ Gia_ManAreRycycleSta( p, pSta );
+ return 0;
+ }
+ if ( Gia_StaAreContain( pSta, pCube, p->nWords ) )
+ {
+ Gia_StaSetUnused( pCube );
+ continue;
+ }
+ iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords );
+ if ( iVar == -1 )
+ continue;
+ assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) );
+ assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) );
+ if ( Gia_StaHasValue0(pCube, iVar) )
+ Gia_StaSetValue1( pSta, iVar );
+ else
+ Gia_StaSetValue0( pSta, iVar );
+ return Gia_ManAreCubeCheckTree( p, pSta );
+ }
+/*
+ if ( p->nStas > 3000 )
+ {
+printf( "Trying cube: " );
+Gia_ManArePrintCube( p, pSta );
+ Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i )
+ {
+printf( "aaaaaaaaaaaa %5d ", Vec_IntEntry(p->vCubesA,i) );
+Gia_ManArePrintCube( p, pCube );
+ }
+ Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i )
+ {
+printf( "bbbbbbbbbbbb %5d ", Vec_IntEntry(p->vCubesB,i) );
+Gia_ManArePrintCube( p, pCube );
+ }
+ }
+*/
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Processes the new cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManAreCubeProcess( Gia_ManAre_t * p, Gia_StaAre_t * pSta )
+{
+ int RetValue;
+ p->nChecks = 0;
+ if ( !p->fTree && p->nStas == MAX_CUBE_NUM )
+ Gia_ManAreRebalance( p, &p->Root );
+ if ( p->fTree )
+ {
+// RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ManAreObj(p, p->Root), pSta );
+ RetValue = Gia_ManAreCubeCheckTree( p, pSta );
+ if ( RetValue )
+ Gia_ManAreCubeAddToTree_rec( p, Gia_ManAreObj(p, p->Root), pSta );
+ }
+ else
+ {
+ RetValue = Gia_ManAreCubeCheckList( p, &p->Root, pSta );
+ if ( RetValue )
+ Gia_ManAreCubeAddToList( p, &p->Root, pSta );
+ }
+// printf( "%d ", p->nChecks );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the most used CI, or NULL if condition is met.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreMostUsedPi_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pObj->Value++;
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the most used CI, or NULL if condition is met.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Gia_Obj_t * Gia_ManAreMostUsedPi( Gia_ManAre_t * p )
+{
+ Gia_Obj_t * pObj, * pObjMax = NULL;
+ int i;
+ // clean CI counters
+ Gia_ManForEachCi( p->pNew, pObj, i )
+ pObj->Value = 0;
+ // traverse from each register output
+ Gia_ManForEachRi( p->pAig, pObj, i )
+ {
+ if ( pObj->Value <= 1 )
+ continue;
+ Gia_ManIncrementTravId( p->pNew );
+ Gia_ManAreMostUsedPi_rec( p->pNew, Gia_ManObj(p->pNew, Gia_Lit2Var(pObj->Value)) );
+ }
+ // check the CI counters
+ Gia_ManForEachCi( p->pNew, pObj, i )
+ if ( pObjMax == NULL || pObjMax->Value < pObj->Value )
+ pObjMax = pObj;
+ // return the result
+ return pObjMax->Value > 1 ? pObjMax : NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts maximum support of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCheckPOs_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return 1;
+ assert( Gia_ObjIsAnd(pObj) );
+ return Gia_ManCheckPOs_rec( p, Gia_ObjFanin0(pObj) ) +
+ Gia_ManCheckPOs_rec( p, Gia_ObjFanin1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts maximum support of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManCheckPOs( Gia_ManAre_t * p )
+{
+ Gia_Obj_t * pObj, * pObjNew;
+ int i, CountCur, CountMax = 0;
+ Gia_ManForEachPo( p->pAig, pObj, i )
+ {
+ pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) );
+ if ( Gia_ObjIsConst0(pObjNew) )
+ CountCur = 0;
+ else
+ {
+ Gia_ManIncrementTravId( p->pNew );
+ CountCur = Gia_ManCheckPOs_rec( p->pNew, pObjNew );
+ }
+ CountMax = ABC_MAX( CountMax, CountCur );
+ }
+ return CountMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the status of the primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ManCheckPOstatus( Gia_ManAre_t * p )
+{
+ Gia_Obj_t * pObj, * pObjNew;
+ int i;
+ Gia_ManForEachPo( p->pAig, pObj, i )
+ {
+ pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) );
+ if ( Gia_ObjIsConst0(pObjNew) )
+ {
+ if ( Gia_LitIsCompl(pObj->Value) )
+ {
+ p->iOutFail = i;
+ return 1;
+ }
+ }
+ else
+ {
+ p->iOutFail = i;
+// printf( "To fix later: PO may be assertable.\n" );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives next state cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreDeriveNexts_rec( Gia_ManAre_t * p, Gia_PtrAre_t Sta )
+{
+ Gia_Obj_t * pPivot;
+ Vec_Int_t * vLits, * vTfos;
+ Gia_Obj_t * pObj;
+ int i, clk;
+ if ( ++p->nRecCalls == MAX_CALL_NUM )
+ return 0;
+ if ( (pPivot = Gia_ManAreMostUsedPi(p)) == NULL )
+ {
+ Gia_StaAre_t * pNew;
+ clk = clock();
+ pNew = Gia_ManAreCreateStaNew( p );
+ pNew->iPrev = Sta;
+ p->fStopped = (p->fMiter && (Gia_ManCheckPOstatus(p) & 1));
+ if ( p->fStopped )
+ {
+ assert( p->pTarget == NULL );
+ p->pTarget = pNew;
+ return 1;
+ }
+ Gia_ManAreCubeProcess( p, pNew );
+ p->timeCube += clock() - clk;
+ return p->fStopped;
+ }
+ // remember values in the cone and perform update
+ vTfos = (Vec_Int_t *)Vec_VecEntry( p->vCiTfos, Gia_ObjCioId(pPivot) );
+ vLits = (Vec_Int_t *)Vec_VecEntry( p->vCiLits, Gia_ObjCioId(pPivot) );
+ assert( Vec_IntSize(vTfos) == Vec_IntSize(vLits) );
+ Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i )
+ {
+ Vec_IntWriteEntry( vLits, i, pObj->Value );
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ else
+ {
+ assert( Gia_ObjIsCi(pObj) );
+ pObj->Value = 0;
+ }
+ }
+ if ( Gia_ManAreDeriveNexts_rec( p, Sta ) )
+ return 1;
+ // compute different values
+ Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ else
+ {
+ assert( Gia_ObjIsCi(pObj) );
+ pObj->Value = 1;
+ }
+ }
+ if ( Gia_ManAreDeriveNexts_rec( p, Sta ) )
+ return 1;
+ // reset the original values
+ Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i )
+ pObj->Value = Vec_IntEntry( vLits, i );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives next state cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManAreDeriveNexts( Gia_ManAre_t * p, Gia_PtrAre_t Sta )
+{
+ Gia_StaAre_t * pSta;
+ Gia_Obj_t * pObj;
+ int i, RetValue, clk = clock();
+ pSta = Gia_ManAreSta( p, Sta );
+ if ( Gia_StaIsUnused(pSta) )
+ return 0;
+ // recycle the manager
+ if ( p->pNew && Gia_ManObjNum(p->pNew) > 1000000 )
+ {
+ Gia_ManStop( p->pNew );
+ p->pNew = NULL;
+ }
+ // allocate the manager
+ if ( p->pNew == NULL )
+ {
+ p->pNew = Gia_ManStart( 10 * Gia_ManObjNum(p->pAig) );
+ Gia_ManIncrementTravId( p->pNew );
+ Gia_ManHashAlloc( p->pNew );
+ Gia_ManConst0(p->pAig)->Value = 0;
+ Gia_ManForEachCi( p->pAig, pObj, i )
+ pObj->Value = Gia_ManAppendCi(p->pNew);
+ }
+ Gia_ManForEachRo( p->pAig, pObj, i )
+ {
+ if ( Gia_StaHasValue0( pSta, i ) )
+ pObj->Value = 0;
+ else if ( Gia_StaHasValue1( pSta, i ) )
+ pObj->Value = 1;
+ else // don't-care literal
+ pObj->Value = Gia_Var2Lit( Gia_ObjId( p->pNew, Gia_ManCi(p->pNew, Gia_ObjCioId(pObj)) ), 0 );
+ }
+ Gia_ManForEachAnd( p->pAig, pObj, i )
+ pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p->pAig, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+
+ // perform case-splitting
+ p->nRecCalls = 0;
+ RetValue = Gia_ManAreDeriveNexts_rec( p, Sta );
+ if ( p->nRecCalls >= MAX_CALL_NUM )
+ {
+ printf( "Exceeded the limit on the number of transitions from a state cube (%d).\n", MAX_CALL_NUM );
+ p->fStopped = 1;
+ }
+// printf( "%d ", p->nRecCalls );
+//printf( "%d ", Gia_ManObjNum(p->pNew) );
+ p->timeAig += clock() - clk;
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the report]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManArePrintReport( Gia_ManAre_t * p, int Time, int fFinal )
+{
+ printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ",
+ p->iStaCur, p->nStas, 1.0*p->iStaCur/p->nStas, Gia_ManAreDepth(p, p->iStaCur),
+ (sizeof(Gia_ManAre_t) + 4.0*Gia_ManRegNum(p->pAig) + 8.0*MAX_PAGE_NUM +
+ 4.0*p->nStaPages*p->nSize*MAX_ITEM_NUM + 16.0*p->nObjPages*MAX_ITEM_NUM)/(1<<20) );
+ if ( fFinal )
+ {
+ ABC_PRT( "Time", clock() - Time );
+ }
+ else
+ {
+ ABC_PRTr( "Time", clock() - Time );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs explicit reachability.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManArePerform( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose )
+{
+// extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose );
+ extern Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast );
+ Gia_ManAre_t * p;
+ int clk = clock();
+ int RetValue = 1;
+ if ( Gia_ManRegNum(pAig) > MAX_VARS_NUM )
+ {
+ printf( "Currently can only handle circuit with up to %d registers.\n", MAX_VARS_NUM );
+ return -1;
+ }
+ ABC_FREE( pAig->pCexSeq );
+ p = Gia_ManAreCreate( Gia_ManCompress2(pAig, 0, 0) );
+ p->fMiter = fMiter;
+ Gia_ManAreCubeProcess( p, Gia_ManAreCreateStaInit(p) );
+ for ( p->iStaCur = 1; p->iStaCur < p->nStas; p->iStaCur++ )
+ {
+// printf( "Explored state %d. Total cubes %d.\n", p->iStaCur, p->nStas-1 );
+ if ( Gia_ManAreDeriveNexts( p, Gia_Int2Ptr(p->iStaCur) ) || p->nStas > nStatesMax )
+ pAig->pCexSeq = Gia_ManAreDeriveCex( p, p->pTarget );
+ if ( p->fStopped )
+ {
+ RetValue = -1;
+ break;
+ }
+ if ( fVerbose && p->iStaCur % 5000 == 0 )
+ Gia_ManArePrintReport( p, clk, 0 );
+ }
+ Gia_ManArePrintReport( p, clk, 1 );
+ printf( "%s after finding %d state cubes (%d not contained) with depth %d. ",
+ p->fStopped ? "Stopped" : "Completed",
+ p->nStas, Gia_ManAreListCountUsed(p),
+ Gia_ManAreDepth(p, p->iStaCur-1) );
+ ABC_PRT( "Time", clock() - clk );
+ if ( pAig->pCexSeq != NULL )
+// printf( "Miter FAILED in state %d at frame %d (use \"&write_counter\" to dump a witness)\n",
+ printf( "Miter FAILED in state %d at frame %d (the cex is available for refinement)\n",
+ p->iStaCur, Gia_ManAreDepth(p, p->iStaCur)-1 );
+ if ( fVerbose )
+ {
+ ABC_PRTP( "Cofactoring", p->timeAig - p->timeCube, clock() - clk );
+ ABC_PRTP( "Containment", p->timeCube, clock() - clk );
+ ABC_PRTP( "Other ", clock() - clk - p->timeAig, clock() - clk );
+ ABC_PRTP( "TOTAL ", clock() - clk, clock() - clk );
+ }
+ if ( Gia_ManRegNum(pAig) <= 30 )
+ {
+ clk = clock();
+ printf( "The number of unique state minterms in computed state cubes is %d. ", Gia_ManCountMinterms(p) );
+ ABC_PRT( "Time", clock() - clk );
+ }
+// printf( "Compares = %d. Equals = %d. Disj = %d. Disj2 = %d. Disj3 = %d.\n",
+// p->nCompares, p->nEquals, p->nDisjs, p->nDisjs2, p->nDisjs3 );
+// Gia_ManAreFindBestVar( p, Gia_ManAreSta(p, p->Root) );
+// Gia_ManArePrintUsed( p );
+ Gia_ManAreFree( p );
+ // verify
+ if ( pAig->pCexSeq )
+ {
+ if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) )
+ printf( "Generated counter-example is INVALID. \n" );
+ else
+ printf( "Generated counter-example verified correctly. \n" );
+ return 0;
+ }
+ return RetValue;
+}
+
+ABC_NAMESPACE_IMPL_END
+
+#include "giaAig.h"
+#include "cnf.h"
+#include "satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreDeriveCexSatStart( Gia_ManAre_t * p )
+{
+ Aig_Man_t * pAig2;
+ Cnf_Dat_t * pCnf;
+ assert( p->pSat == NULL );
+ pAig2 = Gia_ManToAig( p->pAig, 0 );
+ Aig_ManSetRegNum( pAig2, 0 );
+ pCnf = Cnf_Derive( pAig2, Gia_ManCoNum(p->pAig) );
+ p->pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ p->vSatNumCis = Cnf_DataCollectCiSatNums( pCnf, pAig2 );
+ p->vSatNumCos = Cnf_DataCollectCoSatNums( pCnf, pAig2 );
+ Cnf_DataFree( pCnf );
+ Aig_ManStop( pAig2 );
+ p->vAssumps = Vec_IntAlloc( 100 );
+ p->vCofVars = Vec_IntAlloc( 100 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreDeriveCexSatStop( Gia_ManAre_t * p )
+{
+ assert( p->pSat != NULL );
+ assert( p->pTarget != NULL );
+ sat_solver_delete( (sat_solver *)p->pSat );
+ Vec_IntFree( p->vSatNumCis );
+ Vec_IntFree( p->vSatNumCos );
+ Vec_IntFree( p->vAssumps );
+ Vec_IntFree( p->vCofVars );
+ p->pTarget = NULL;
+ p->pSat = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes satisfying assignment in one timeframe.]
+
+ Description [Returns the vector of integers represeting PIO ids
+ of the primary inputs that should be 1 in the counter-example.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManAreDeriveCexSat( Gia_ManAre_t * p, Gia_StaAre_t * pCur, Gia_StaAre_t * pNext, int iOutFailed )
+{
+ int i, status;
+ // make assuptions
+ Vec_IntClear( p->vAssumps );
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ if ( Gia_StaHasValue0(pCur, i) )
+ Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 1 ) );
+ else if ( Gia_StaHasValue1(pCur, i) )
+ Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 0 ) );
+ }
+ if ( pNext )
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ if ( Gia_StaHasValue0(pNext, i) )
+ Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 1 ) );
+ else if ( Gia_StaHasValue1(pNext, i) )
+ Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 0 ) );
+ }
+ if ( iOutFailed >= 0 )
+ {
+ assert( iOutFailed < Gia_ManPoNum(p->pAig) );
+ Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, iOutFailed), 0 ) );
+ }
+ // solve SAT
+ status = sat_solver_solve( (sat_solver *)p->pSat, (int *)Vec_IntArray(p->vAssumps), (int *)Vec_IntArray(p->vAssumps) + Vec_IntSize(p->vAssumps),
+ (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( status != l_True )
+ {
+ printf( "SAT problem is not satisfiable. Failure...\n" );
+ return;
+ }
+ assert( status == l_True );
+ // check the model
+ Vec_IntClear( p->vCofVars );
+ for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
+ {
+ if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, i) ) )
+ Vec_IntPush( p->vCofVars, i );
+ }
+ // write the current state
+ for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
+ {
+ if ( Gia_StaHasValue0(pCur, i) )
+ assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 );
+ else if ( Gia_StaHasValue1(pCur, i) )
+ assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 1 );
+ // set don't-care value
+ if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 )
+ Gia_StaSetValue0( pCur, i );
+ else
+ Gia_StaSetValue1( pCur, i );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the status of the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast )
+{
+ Abc_Cex_t * pCex;
+ Vec_Ptr_t * vStates;
+ Gia_StaAre_t * pSta, * pPrev;
+ int Var, i, v;
+ assert( p->iOutFail >= 0 );
+ Gia_ManAreDeriveCexSatStart( p );
+ // compute the trace
+ vStates = Vec_PtrAlloc( 1000 );
+ for ( pSta = pLast; Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) )
+ if ( pSta != pLast )
+ Vec_PtrPush( vStates, pSta );
+ assert( Vec_PtrSize(vStates) >= 1 );
+ // start the counter-example
+ pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(p->pAig), Gia_ManPiNum(p->pAig), Vec_PtrSize(vStates) );
+ pCex->iFrame = Vec_PtrSize(vStates)-1;
+ pCex->iPo = p->iOutFail;
+ // compute states
+ pPrev = NULL;
+ Vec_PtrForEachEntry( Gia_StaAre_t *, vStates, pSta, i )
+ {
+ Gia_ManAreDeriveCexSat( p, pSta, pPrev, (i == 0) ? p->iOutFail : -1 );
+ pPrev = pSta;
+ // create the counter-example
+ Vec_IntForEachEntry( p->vCofVars, Var, v )
+ {
+ assert( Var < Gia_ManPiNum(p->pAig) );
+ Gia_InfoSetBit( pCex->pData, Gia_ManRegNum(p->pAig) + (Vec_PtrSize(vStates)-1-i) * Gia_ManPiNum(p->pAig) + Var );
+ }
+ }
+ // free temporary things
+ Vec_PtrFree( vStates );
+ Gia_ManAreDeriveCexSatStop( p );
+ return pCex;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c
index b32484af..c3e39405 100644
--- a/src/aig/gia/giaFanout.c
+++ b/src/aig/gia/giaFanout.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -195,3 +198,5 @@ void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c
index 04c8f2e7..b9135404 100644
--- a/src/aig/gia/giaForce.c
+++ b/src/aig/gia/giaForce.c
@@ -20,9 +20,12 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
/*
The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah.
- "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
+ "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI�03.
http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
*/
@@ -1096,4 +1099,7 @@ Write = 1.81 sec
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
-//////////////////////////////////////////////////////////////////////// \ No newline at end of file
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaFrames.c b/src/aig/gia/giaFrames.c
index c0ea6680..75b17361 100644
--- a/src/aig/gia/giaFrames.c
+++ b/src/aig/gia/giaFrames.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -116,7 +119,7 @@ void Gia_ManFraSupports( Gia_ManFra_t * p )
p->vIns = Vec_PtrStart( p->pPars->nFrames );
p->vAnds = Vec_PtrStart( p->pPars->nFrames );
p->vOuts = Vec_PtrStart( p->pPars->nFrames );
- Gia_ManResetTravId( p->pAig );
+ Gia_ManIncrementTravId( p->pAig );
for ( f = p->pPars->nFrames - 1; f >= 0; f-- )
{
vOuts = Gia_ManCollectPoIds( p->pAig );
@@ -185,9 +188,9 @@ Gia_Man_t * Gia_ManFramesInit( Gia_Man_t * pAig, Gia_ParFra_t * pPars )
Gia_ManConst0(pAig)->Value = 0;
for ( f = 0; f < pPars->nFrames; f++ )
{
- vIns = Vec_PtrEntry( p->vIns, f );
- vAnds = Vec_PtrEntry( p->vAnds, f );
- vOuts = Vec_PtrEntry( p->vOuts, f );
+ vIns = (Vec_Int_t *)Vec_PtrEntry( p->vIns, f );
+ vAnds = (Vec_Int_t *)Vec_PtrEntry( p->vAnds, f );
+ vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vOuts, f );
if ( pPars->fVerbose )
printf( "Frame %3d : CI = %6d. AND = %6d. CO = %6d.\n",
f, Vec_IntSize(vIns), Vec_IntSize(vAnds), Vec_IntSize(vOuts) );
@@ -344,3 +347,5 @@ Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaFront.c b/src/aig/gia/giaFront.c
index b3a3c2d0..6f1ce5a7 100644
--- a/src/aig/gia/giaFront.c
+++ b/src/aig/gia/giaFront.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -193,7 +196,7 @@ Gia_Man_t * Gia_ManFront( Gia_Man_t * p )
pFront[iFront] = 0;
}
assert( pNew->nObjs == p->nObjs );
- assert( nCrossCut == 0 && nCrossCutMax == nCrossCutMaxInit );
+ assert( nCrossCut == 0 || nCrossCutMax == nCrossCutMaxInit );
for ( i = 0; i < pNew->nFront; i++ )
assert( pFront[i] == 0 );
ABC_FREE( pFront );
@@ -246,3 +249,5 @@ void Gia_ManFrontTest( Gia_Man_t * p )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
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
+
diff --git a/src/aig/gia/giaGlitch.c b/src/aig/gia/giaGlitch.c
index ed636540..a6e5315a 100644
--- a/src/aig/gia/giaGlitch.c
+++ b/src/aig/gia/giaGlitch.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -779,3 +782,5 @@ void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c
index 97326c92..6561ca13 100644
--- a/src/aig/gia/giaHash.c
+++ b/src/aig/gia/giaHash.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -66,7 +69,7 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 )
Gia_Obj_t * pThis;
int * pPlace = p->pHTable + Gia_ManHashOne( iLit0, iLit1, p->nHTable );
for ( pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL; pThis;
- pPlace = &pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL )
+ pPlace = (int *)&pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL )
if ( Gia_ObjFaninLit0p(p, pThis) == iLit0 && Gia_ObjFaninLit1p(p, pThis) == iLit1 )
break;
return pPlace;
@@ -74,6 +77,26 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 )
+{
+ int iLit0 = Gia_ObjToLit( p, p0 );
+ int iLit1 = Gia_ObjToLit( p, p1 );
+ if ( iLit0 > iLit1 )
+ iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1;
+ return *Gia_ManHashFind( p, iLit0, iLit1 );
+}
+
+/**Function*************************************************************
+
Synopsis [Starts the hash table.]
Description []
@@ -594,3 +617,5 @@ Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaHcd.c b/src/aig/gia/giaHcd.c
new file mode 100644
index 00000000..454785b9
--- /dev/null
+++ b/src/aig/gia/giaHcd.c
@@ -0,0 +1,686 @@
+/**CFile****************************************************************
+
+ FileName [giaHcd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [New choice computation package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaHcd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "aig.h"
+#include "dar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// choicing parameters
+typedef struct Hcd_Pars_t_ Hcd_Pars_t;
+struct Hcd_Pars_t_
+{
+ int nWords; // the number of simulation words
+ int nBTLimit; // conflict limit at a node
+ int nSatVarMax; // the max number of SAT variables
+ int fSynthesis; // set to 1 to perform synthesis
+ int fPolarFlip; // uses polarity adjustment
+ int fSimulateTfo; // uses simulation of TFO classes
+ int fPower; // uses power-aware rewriting
+ int fUseGia; // uses GIA package
+ int fUseCSat; // uses circuit-based solver
+ int fVerbose; // verbose stats
+ int timeSynth; // synthesis runtime
+ int nNodesAhead; // the lookahead in terms of nodes
+ int nCallsRecycle; // calls to perform before recycling SAT solver
+};
+
+extern void Gia_ComputeEquivalences( Gia_Man_t * pMiter, int nBTLimit, int fUseMiniSat, int fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Hcd_ManSetDefaultParams( Hcd_Pars_t * p )
+{
+ memset( p, 0, sizeof(Hcd_Pars_t) );
+ p->nWords = 8; // the number of simulation words
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->nSatVarMax = 5000; // the max number of SAT variables
+ p->fSynthesis = 1; // derives three snapshots
+ p->fPolarFlip = 1; // uses polarity adjustment
+ p->fSimulateTfo = 1; // simulate TFO
+ p->fPower = 0; // power-aware rewriting
+ p->fVerbose = 0; // verbose stats
+ p->nNodesAhead = 1000; // the lookahead in terms of nodes
+ p->nCallsRecycle = 100; // calls to perform before recycling SAT solver
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Reproduces script "compress".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Hcd_Compress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose )
+//alias compress2 "b -l; rw -l; rwz -l; b -l; rwz -l; b -l"
+{
+ Aig_Man_t * pTemp;
+
+ Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr;
+ Dar_RefPar_t ParsRef, * pParsRef = &ParsRef;
+
+ Dar_ManDefaultRwrParams( pParsRwr );
+ Dar_ManDefaultRefParams( pParsRef );
+
+ pParsRwr->fUpdateLevel = fUpdateLevel;
+ pParsRef->fUpdateLevel = fUpdateLevel;
+
+ pParsRwr->fPower = fPower;
+
+ pParsRwr->fVerbose = 0;//fVerbose;
+ pParsRef->fVerbose = 0;//fVerbose;
+
+// pAig = Aig_ManDupDfs( pAig );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // refactor
+ Dar_ManRefactor( pAig, pParsRef );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // balance
+ if ( fBalance )
+ {
+ pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+ }
+
+ pParsRwr->fUseZeros = 1;
+ pParsRef->fUseZeros = 1;
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ return pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reproduces script "compress2".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Hcd_Compress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose )
+//alias compress2 "b -l; rw -l; rf -l; b -l; rw -l; rwz -l; b -l; rfz -l; rwz -l; b -l"
+{
+ Aig_Man_t * pTemp;
+
+ Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr;
+ Dar_RefPar_t ParsRef, * pParsRef = &ParsRef;
+
+ Dar_ManDefaultRwrParams( pParsRwr );
+ Dar_ManDefaultRefParams( pParsRef );
+
+ pParsRwr->fUpdateLevel = fUpdateLevel;
+ pParsRef->fUpdateLevel = fUpdateLevel;
+ pParsRwr->fFanout = fFanout;
+ pParsRwr->fPower = fPower;
+
+ pParsRwr->fVerbose = 0;//fVerbose;
+ pParsRef->fVerbose = 0;//fVerbose;
+
+// pAig = Aig_ManDupDfs( pAig );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // refactor
+ Dar_ManRefactor( pAig, pParsRef );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // balance
+// if ( fBalance )
+ {
+ pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+ }
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ pParsRwr->fUseZeros = 1;
+ pParsRef->fUseZeros = 1;
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // balance
+ if ( fBalance )
+ {
+ pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+ }
+
+ // refactor
+ Dar_ManRefactor( pAig, pParsRef );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // rewrite
+ Dar_ManRewrite( pAig, pParsRwr );
+ pAig = Aig_ManDupDfs( pTemp = pAig );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+
+ // balance
+ if ( fBalance )
+ {
+ pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel );
+ Aig_ManStop( pTemp );
+ if ( fVerbose ) Aig_ManPrintStats( pAig );
+ }
+ return pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reproduces script "compress2".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Hcd_ChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose )
+//alias resyn "b; rw; rwz; b; rwz; b"
+//alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; rwz; b"
+{
+ Vec_Ptr_t * vGias;
+ Gia_Man_t * pGia;
+
+ vGias = Vec_PtrAlloc( 3 );
+ pGia = Gia_ManFromAig(pAig);
+ Vec_PtrPush( vGias, pGia );
+
+ pAig = Hcd_Compress( pAig, fBalance, fUpdateLevel, fPower, fVerbose );
+ pGia = Gia_ManFromAig(pAig);
+ Vec_PtrPush( vGias, pGia );
+//Aig_ManPrintStats( pAig );
+
+ pAig = Hcd_Compress2( pAig, fBalance, fUpdateLevel, 1, fPower, fVerbose );
+ pGia = Gia_ManFromAig(pAig);
+ Vec_PtrPush( vGias, pGia );
+//Aig_ManPrintStats( pAig );
+
+ Aig_ManStop( pAig );
+ return vGias;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Hcd_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ if ( Gia_ObjIsCo(pObj) )
+ return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of several AIGs for choice computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Hcd_ManChoiceMiter( Vec_Ptr_t * vGias )
+{
+ Gia_Man_t * pNew, * pGia, * pGia0;
+ int i, k, iNode, nNodes;
+ // make sure they have equal parameters
+ assert( Vec_PtrSize(vGias) > 0 );
+ pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 );
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ {
+ assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) );
+ assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) );
+ assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) );
+ Gia_ManFillValue( pGia );
+ Gia_ManConst0(pGia)->Value = 0;
+ }
+ // start the new manager
+ pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) );
+ pNew->pName = Gia_UtilStrsav( pGia0->pName );
+ // create new CIs and assign them to the old manager CIs
+ for ( k = 0; k < Gia_ManCiNum(pGia0); k++ )
+ {
+ iNode = Gia_ManAppendCi(pNew);
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ Gia_ManCi( pGia, k )->Value = iNode;
+ }
+ // create internal nodes
+ Gia_ManHashAlloc( pNew );
+ for ( k = 0; k < Gia_ManCoNum(pGia0); k++ )
+ {
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ Hcd_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) );
+ }
+ Gia_ManHashStop( pNew );
+ // check the presence of dangling nodes
+ nNodes = Gia_ManHasDangling( pNew );
+ assert( nNodes == 0 );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if pOld is in the TFI of pNode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Hcd_ObjCheckTfi_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode, Vec_Ptr_t * vVisited )
+{
+ // check the trivial cases
+ if ( pNode == NULL )
+ return 0;
+ if ( Gia_ObjIsCi(pNode) )
+ return 0;
+// if ( pNode->Id < pOld->Id ) // cannot use because of choices of pNode
+// return 0;
+ if ( pNode == pOld )
+ return 1;
+ // skip the visited node
+ if ( pNode->fMark0 )
+ return 0;
+ pNode->fMark0 = 1;
+ Vec_PtrPush( vVisited, pNode );
+ // check the children
+ if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin0(pNode), vVisited ) )
+ return 1;
+ if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin1(pNode), vVisited ) )
+ return 1;
+ // check equivalent nodes
+ return Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjNextObj(p, Gia_ObjId(p, pNode)), vVisited );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if pOld is in the TFI of pNode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Hcd_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode )
+{
+ Vec_Ptr_t * vVisited;
+ Gia_Obj_t * pObj;
+ int RetValue, i;
+ assert( !Gia_IsComplement(pOld) );
+ assert( !Gia_IsComplement(pNode) );
+ vVisited = Vec_PtrAlloc( 100 );
+ RetValue = Hcd_ObjCheckTfi_rec( p, pOld, pNode, vVisited );
+ Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i )
+ pObj->fMark0 = 0;
+ Vec_PtrFree( vVisited );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the next entry while making choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Hcd_ManAddNextEntry_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode )
+{
+ if ( Gia_ObjNext(p, Gia_ObjId(p, pOld)) == 0 )
+ {
+ Gia_ObjSetNext( p, Gia_ObjId(p, pOld), Gia_ObjId(p, pNode) );
+ return;
+ }
+ Hcd_ManAddNextEntry_rec( p, Gia_ObjNextObj(p, Gia_ObjId(p, pOld)), pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Hcd_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pRepr, * pReprNew, * pObjNew;
+ if ( ~pObj->Value )
+ return;
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ if ( Gia_ObjIsConst0(pRepr) )
+ {
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ Hcd_ManEquivToChoices_rec( pNew, p, pRepr );
+ assert( Gia_ObjIsAnd(pObj) );
+ Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( Gia_LitRegular(pObj->Value) == Gia_LitRegular(pRepr->Value) )
+ {
+ assert( (int)pObj->Value == Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ) );
+ return;
+ }
+ if ( pRepr->Value > pObj->Value ) // should never happen with high resource limit
+ return;
+ assert( pRepr->Value < pObj->Value );
+ pReprNew = Gia_ManObj( pNew, Gia_Lit2Var(pRepr->Value) );
+ pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) );
+ if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) )
+ {
+ assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew );
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ if ( !Hcd_ObjCheckTfi( pNew, pReprNew, pObjNew ) )
+ {
+ assert( Gia_ObjNext(pNew, Gia_ObjId(pNew, pObjNew)) == 0 );
+ Gia_ObjSetRepr( pNew, Gia_ObjId(pNew, pObjNew), Gia_ObjId(pNew, pReprNew) );
+ Hcd_ManAddNextEntry_rec( pNew, pReprNew, pObjNew );
+ }
+ pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes choices, which contain fanouts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Hcd_ManRemoveBadChoices( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, iObj, iPrev, Counter = 0;
+ // mark nodes with fanout
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pObj->fMark0 = 0;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ }
+ // go through the classes and remove
+ Gia_ManForEachClass( p, i )
+ {
+ for ( iPrev = i, iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iPrev) )
+ {
+ if ( !Gia_ManObj(p, iObj)->fMark0 )
+ {
+ iPrev = iObj;
+ continue;
+ }
+ Gia_ObjSetRepr( p, iObj, GIA_VOID );
+ Gia_ObjSetNext( p, iPrev, Gia_ObjNext(p, iObj) );
+ Gia_ObjSetNext( p, iObj, 0 );
+ Counter++;
+ }
+ }
+ // remove the marks
+ Gia_ManCleanMark0( p );
+// printf( "Removed %d bad choices.\n", Counter );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces AIG using equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Hcd_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pRepr;
+ int i;
+ assert( (Gia_ManCoNum(p) % nSnapshots) == 0 );
+ Gia_ManSetPhase( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
+ pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ Gia_ObjSetRepr( pNew, i, GIA_VOID );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachRo( p, pObj, i )
+ if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
+ {
+ assert( Gia_ObjIsConst0(pRepr) || Gia_ObjIsRo(p, pRepr) );
+ pObj->Value = pRepr->Value;
+ }
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ if ( i % nSnapshots == 0 )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Hcd_ManRemoveBadChoices( pNew );
+// Gia_ManEquivPrintClasses( pNew, 0, 0 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+// Gia_ManEquivPrintClasses( pNew, 0, 0 );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of AIGs with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Hcd_ComputeChoices( Aig_Man_t * pAig, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose )
+{
+ Vec_Ptr_t * vGias;
+ Gia_Man_t * pGia, * pMiter;
+ Aig_Man_t * pAigNew;
+ int i, clk = clock();
+ // perform synthesis
+ if ( fSynthesis )
+ {
+ vGias = Hcd_ChoiceSynthesis( Aig_ManDupDfs(pAig), 1, 1, 0, 0 );
+ if ( fVerbose )
+ ABC_PRT( "Synthesis time", clock() - clk );
+ // create choices
+ clk = clock();
+ pMiter = Hcd_ManChoiceMiter( vGias );
+ Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
+ Gia_ManStop( pGia );
+
+ Gia_WriteAiger( pMiter, "m3.aig", 0, 0 );
+ }
+ else
+ {
+ vGias = Vec_PtrStart( 3 );
+ pMiter = Gia_ManFromAig(pAig);
+ }
+ // perform choicing
+ Gia_ComputeEquivalences( pMiter, nBTLimit, fUseMiniSat, fVerbose );
+ // derive AIG with choices
+ pGia = Hcd_ManEquivToChoices( pMiter, Vec_PtrSize(vGias) );
+ Gia_ManSetRegNum( pGia, Aig_ManRegNum(pAig) );
+ Gia_ManStop( pMiter );
+ Vec_PtrFree( vGias );
+ if ( fVerbose )
+ ABC_PRT( "Choicing time", clock() - clk );
+ Gia_ManHasChoices( pGia );
+ // transform back
+ pAigNew = Gia_ManToAig( pGia, 1 );
+ Gia_ManStop( pGia );
+
+ if ( fVerbose )
+ {
+ extern int Dch_DeriveChoiceCountReprs( Aig_Man_t * pAig );
+ extern int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig );
+ printf( "Choices : Reprs = %5d. Equivs = %5d. Choices = %5d.\n",
+ Dch_DeriveChoiceCountReprs( pAigNew ),
+ Dch_DeriveChoiceCountEquivs( pAigNew ),
+ Aig_ManChoiceNum( pAigNew ) );
+ }
+
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of AIGs with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Hcd_ComputeChoicesTest( Gia_Man_t * pGia, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose )
+{
+ Aig_Man_t * pAig, * pAigNew;
+ pAig = Gia_ManToAig( pGia, 0 );
+ pAigNew = Hcd_ComputeChoices( pAig, nBTLimit, fSynthesis, fUseMiniSat, fVerbose );
+ Aig_ManStop( pAigNew );
+ Aig_ManStop( pAig );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaIf.c
index 72bdb001..a06a6024 100644
--- a/src/aig/gia/giaMap.c
+++ b/src/aig/gia/giaIf.c
@@ -19,7 +19,12 @@
***********************************************************************/
#include "gia.h"
+#include "aig.h"
#include "if.h"
+#include "dar.h"
+
+ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -95,6 +100,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
Gia_Obj_t * pNode;
int i, clk = clock();
Gia_ManLevelNum( p );
+// assert( p->pReprs == NULL );
/*
// set the number of registers (switch activity will be combinational)
Gia_ManSetRegNum( p, 0 );
@@ -114,24 +120,25 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
pIfMan = If_ManStart( pPars );
// pIfMan->vSwitching = vSwitching2;
// load the AIG into the mapper
+ Gia_ManCreateRefs( p );
Gia_ManForEachObj( p, pNode, i )
{
if ( Gia_ObjIsAnd(pNode) )
pIfObj = If_ManCreateAnd( pIfMan,
- If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ),
- If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) );
+ If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ),
+ If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) );
else if ( Gia_ObjIsCi(pNode) )
{
pIfObj = If_ManCreateCi( pIfMan );
If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) );
-// printf( "pi=%d ", pIfObj->Level );
+// Abc_Print( 1, "pi=%d ", pIfObj->Level );
if ( pIfMan->nLevelMax < (int)pIfObj->Level )
pIfMan->nLevelMax = (int)pIfObj->Level;
}
else if ( Gia_ObjIsCo(pNode) )
{
- pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) );
-// printf( "po=%d ", pIfObj->Level );
+ pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) );
+// Abc_Print( 1, "po=%d ", pIfObj->Level );
}
else if ( Gia_ObjIsConst0(pNode) )
pIfObj = If_Not(If_ManConst1( pIfMan ));
@@ -142,6 +149,18 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
// if ( vSwitching2 )
// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];
+ // set up the choice node
+/*
+// if ( p->pReprs && p->pNexts && Gia_ObjIsHead( p, i ) )
+ if ( p->pNexts && Gia_ObjNext(p, i) && Gia_ObjRefsId(p, i) )
+ {
+ int iPrev, iFanin;
+ pIfMan->nChoices++;
+ for ( iPrev = i, iFanin = Gia_ObjNext(p, i); iFanin; iPrev = iFanin, iFanin = Gia_ObjNext(p, iFanin) )
+ If_ObjSetChoice( Vec_PtrEntry(vAigToIf,iPrev), Vec_PtrEntry(vAigToIf,iFanin) );
+ If_ManCreateChoice( pIfMan, Vec_PtrEntry(vAigToIf,i) );
+ }
+*/
/* // set up the choice node
if ( Gia_ObjIsChoice( p, pNode ) )
{
@@ -186,7 +205,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) );
Gia_ManForEachObj( p, pObj, i )
{
- pIfObj = Vec_PtrEntry( vAigToIf, i );
+ pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj );
if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
continue;
@@ -197,7 +216,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
iOffset = Gia_ManObjNum(p);
Gia_ManForEachObj( p, pObj, i )
{
- pIfObj = Vec_PtrEntry( vAigToIf, i );
+ pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
continue;
pCutBest = If_ObjCutBest( pIfObj );
@@ -208,7 +227,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
pMapping[k++] = nLeaves;
for ( j = 0; j < nLeaves; j++ )
{
- pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] );
+ pObjRepr = (Gia_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[j] );
pMapping[k++] = Gia_ObjId( p, pObjRepr );
}
pMapping[k++] = i;
@@ -279,23 +298,226 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p )
if ( !p->pMapping )
return;
pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
- Gia_ManForEachGate( p, i )
+ Gia_ManForEachLut( p, i )
{
nLuts++;
- nFanins += Gia_ObjGateSize(p, i);
- nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) );
- Gia_GateForEachFanin( p, i, iFan, k )
+ nFanins += Gia_ObjLutSize(p, i);
+ nLutSize = ABC_MAX( nLutSize, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFanin( p, i, iFan, k )
pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] );
pLevels[i]++;
LevelMax = ABC_MAX( LevelMax, pLevels[i] );
}
ABC_FREE( pLevels );
- printf( "mapping : " );
- printf( "%d=lut =%7d ", nLutSize, nLuts );
- printf( "edge =%8d ", nFanins );
- printf( "lev =%5d ", LevelMax );
- printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
- printf( "\n" );
+ Abc_Print( 1, "mapping (K=%d) : ", nLutSize );
+ Abc_Print( 1, "lut =%7d ", nLuts );
+ Abc_Print( 1, "edge =%8d ", nFanins );
+ Abc_Print( 1, "lev =%5d ", LevelMax );
+ Abc_Print( 1, "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
+ Abc_Print( 1, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints mapping statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManLutFaninCount( Gia_Man_t * p )
+{
+ int i, Counter = 0;
+ Gia_ManForEachLut( p, i )
+ Counter += Gia_ObjLutSize(p, i);
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints mapping statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManLutSizeMax( Gia_Man_t * p )
+{
+ int i, nSizeMax = -1;
+ Gia_ManForEachLut( p, i )
+ nSizeMax = ABC_MAX( nSizeMax, Gia_ObjLutSize(p, i) );
+ return nSizeMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints mapping statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManLutNum( Gia_Man_t * p )
+{
+ int i, Counter = 0;
+ Gia_ManForEachLut( p, i )
+ Counter ++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints mapping statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManLutLevel( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, k, iFan, Level;
+ int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachLut( p, i )
+ {
+ Level = 0;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ if ( Level < pLevels[iFan] )
+ Level = pLevels[iFan];
+ pLevels[i] = Level + 1;
+ }
+ Level = 0;
+ Gia_ManForEachCo( p, pObj, k )
+ if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] )
+ Level = pLevels[Gia_ObjFaninId0p(p, pObj)];
+ ABC_FREE( pLevels );
+ return Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSetRefsMapped( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, k, iFan;
+ ABC_FREE( p->pRefs );
+ p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachLut( p, i )
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Gia_ObjRefInc( p, Gia_ManObj(p, iFan) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints NPN class statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintNpnClasses( Gia_Man_t * p )
+{
+ extern char ** Kit_DsdNpn4ClassNames();
+ char ** pNames = Kit_DsdNpn4ClassNames();
+ Vec_Int_t * vLeaves, * vTruth, * vVisited;
+ int * pLutClass, ClassCounts[222] = {0};
+ int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2;
+ unsigned * pTruth;
+ assert( p->pMapping != NULL );
+ assert( Gia_ManLutSizeMax( p ) <= 4 );
+ vLeaves = Vec_IntAlloc( 100 );
+ vVisited = Vec_IntAlloc( 100 );
+ vTruth = Vec_IntAlloc( (1<<16) );
+ pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManCleanTruth( p );
+ Gia_ManForEachLut( p, i )
+ {
+ if ( Gia_ObjLutSize(p,i) > 4 )
+ continue;
+ Vec_IntClear( vLeaves );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Vec_IntPush( vLeaves, iFan );
+ for ( ; k < 4; k++ )
+ Vec_IntPush( vLeaves, 0 );
+ pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited );
+ Class = Dar_LibReturnClass( *pTruth );
+ ClassCounts[ Class ]++;
+ pLutClass[i] = Class;
+ }
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vTruth );
+ Vec_IntFree( vVisited );
+ Vec_IntFreeP( &p->vTruths );
+ nTotal = 0;
+ for ( i = 0; i < 222; i++ )
+ nTotal += ClassCounts[i];
+ Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal );
+ OtherClasses = 0;
+ for ( i = 0; i < 222; i++ )
+ {
+ if ( ClassCounts[i] == 0 )
+ continue;
+ if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent
+ continue;
+ OtherClasses += ClassCounts[i];
+ Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n",
+ i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] );
+ }
+ OtherClasses = nTotal - OtherClasses;
+ Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n",
+ OtherClasses, 100.0 * OtherClasses / (nTotal+1) );
+ // count the number of LUTs that have MUX function and two fanins with MUX functions
+ OtherClasses = OtherClasses2 = 0;
+ ABC_FREE( p->pRefs );
+ Gia_ManSetRefsMapped( p );
+ Gia_ManForEachLut( p, i )
+ {
+ if ( pLutClass[i] != 109 )
+ continue;
+ Counter = Counter2 = 0;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ Counter += (pLutClass[iFan] == 109);
+ Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefsId(p, iFan) == 1);
+ }
+ OtherClasses += (Counter > 1);
+ OtherClasses2 += (Counter2 > 1);
+// Abc_Print( 1, "%d -- ", pLutClass[i] );
+// Gia_LutForEachFanin( p, i, iFan, k )
+// Abc_Print( 1, "%d ", pLutClass[iFan] );
+// Abc_Print( 1, "\n" );
+ }
+ ABC_FREE( p->pRefs );
+ Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n",
+ OtherClasses, 100.0 * OtherClasses / (nTotal+1),
+ OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) );
+ ABC_FREE( pLutClass );
}
////////////////////////////////////////////////////////////////////////
@@ -303,3 +525,5 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index 4547e61c..ed6a5c95 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -19,6 +19,10 @@
***********************************************************************/
#include "gia.h"
+#include "tim.h"
+
+ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -66,10 +70,18 @@ Gia_Man_t * Gia_ManStart( int nObjsMax )
***********************************************************************/
void Gia_ManStop( Gia_Man_t * p )
{
+ Tim_ManStopP( (Tim_Man_t **)&p->pManTime );
+ assert( p->pManTime == NULL );
Vec_PtrFreeFree( p->vNamesIn );
Vec_PtrFreeFree( p->vNamesOut );
- if ( p->vFlopClasses )
- Vec_IntFree( p->vFlopClasses );
+ Vec_FltFreeP( &p->vTiming );
+ Vec_VecFreeP( &p->vClockDoms );
+ Vec_IntFreeP( &p->vLutConfigs );
+ Vec_IntFreeP( &p->vCiNumsOrig );
+ Vec_IntFreeP( &p->vCoNumsOrig );
+ Vec_IntFreeP( &p->vFlopClasses );
+ Vec_IntFreeP( &p->vLevels );
+ Vec_IntFreeP( &p->vTruths );
Vec_IntFree( p->vCis );
Vec_IntFree( p->vCos );
ABC_FREE( p->pTravIds );
@@ -85,7 +97,7 @@ void Gia_ManStop( Gia_Man_t * p )
ABC_FREE( p->pNexts );
ABC_FREE( p->pName );
ABC_FREE( p->pRefs );
- ABC_FREE( p->pLevels );
+ ABC_FREE( p->pNodeRefs );
ABC_FREE( p->pHTable );
ABC_FREE( p->pObjs );
ABC_FREE( p );
@@ -93,6 +105,25 @@ void Gia_ManStop( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManStopP( Gia_Man_t ** p )
+{
+ if ( *p == NULL )
+ return;
+ Gia_ManStop( *p );
+ *p = NULL;
+}
+
+/**Function*************************************************************
+
Synopsis [Prints stats for the AIG.]
Description []
@@ -102,7 +133,7 @@ void Gia_ManStop( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-void Gia_ManPrintClasses( Gia_Man_t * p )
+void Gia_ManPrintClasses_old( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i;
@@ -134,6 +165,44 @@ void Gia_ManPrintClasses( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+void Gia_ManPrintClasses( Gia_Man_t * p )
+{
+ int i, Class, Counter0, Counter1;
+ if ( p->vFlopClasses == NULL )
+ return;
+ if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) )
+ {
+ printf( "Gia_ManPrintClasses(): The number of flop map entries differs from the number of flops.\n" );
+ return;
+ }
+ printf( "Register classes: " );
+ // count zero entries
+ Counter0 = 0;
+ Vec_IntForEachEntry( p->vFlopClasses, Class, i )
+ Counter0 += (Class == 0);
+ printf( "0=%d ", Counter0 );
+ // count one entries
+ Counter1 = 0;
+ Vec_IntForEachEntry( p->vFlopClasses, Class, i )
+ Counter1 += (Class == 1);
+ printf( "1=%d ", Counter1 );
+ // add comment
+ if ( Counter0 + Counter1 < Gia_ManRegNum(p) )
+ printf( "there are other classes..." );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats for the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Gia_ManPrintPlacement( Gia_Man_t * p )
{
int i, nFixed = 0, nUndef = 0;
@@ -163,13 +232,15 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch )
if ( p->pName )
printf( "%-8s : ", p->pName );
printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) );
+ if ( Gia_ManConstrNum(p) )
+ printf( "(c=%d)", Gia_ManConstrNum(p) );
if ( Gia_ManRegNum(p) )
printf( " ff =%7d", Gia_ManRegNum(p) );
printf( " and =%8d", Gia_ManAndNum(p) );
printf( " lev =%5d", Gia_ManLevelNum(p) );
printf( " cut =%5d", Gia_ManCrossCut(p) );
printf( " mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) );
- if ( Gia_ManHasDandling(p) )
+ if ( Gia_ManHasDangling(p) )
printf( " ch =%5d", Gia_ManEquivCountClasses(p) );
if ( fSwitch )
{
@@ -189,7 +260,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch )
if ( p->pPlacement )
Gia_ManPrintPlacement( p );
// print register classes
-// Gia_ManPrintClasses( p );
+ Gia_ManPrintClasses( p );
}
/**Function*************************************************************
@@ -309,3 +380,5 @@ void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMem.c b/src/aig/gia/giaMem.c
new file mode 100644
index 00000000..d77ddfd5
--- /dev/null
+++ b/src/aig/gia/giaMem.c
@@ -0,0 +1,598 @@
+/**CFile****************************************************************
+
+ FileName [giaMem.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [AIG package.]
+
+ Synopsis [Memory managers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - April 28, 2007.]
+
+ Revision [$Id: giaMem.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Gia_MmFixed_t_
+{
+ // information about individual entries
+ int nEntrySize; // the size of one entry
+ int nEntriesAlloc; // the total number of entries allocated
+ int nEntriesUsed; // the number of entries in use
+ int nEntriesMax; // the max number of entries in use
+ char * pEntriesFree; // the linked list of free entries
+
+ // this is where the memory is stored
+ int nChunkSize; // the size of one chunk
+ int nChunksAlloc; // the maximum number of memory chunks
+ int nChunks; // the current number of memory chunks
+ char ** pChunks; // the allocated memory
+
+ // statistics
+ int nMemoryUsed; // memory used in the allocated entries
+ int nMemoryAlloc; // memory allocated
+};
+
+struct Gia_MmFlex_t_
+{
+ // information about individual entries
+ int nEntriesUsed; // the number of entries allocated
+ char * pCurrent; // the current pointer to free memory
+ char * pEnd; // the first entry outside the free memory
+
+ // this is where the memory is stored
+ int nChunkSize; // the size of one chunk
+ int nChunksAlloc; // the maximum number of memory chunks
+ int nChunks; // the current number of memory chunks
+ char ** pChunks; // the allocated memory
+
+ // statistics
+ int nMemoryUsed; // memory used in the allocated entries
+ int nMemoryAlloc; // memory allocated
+};
+
+struct Gia_MmStep_t_
+{
+ int nMems; // the number of fixed memory managers employed
+ Gia_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
+ int nMapSize; // the size of the memory array
+ Gia_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
+ // additional memory chunks
+ int nChunksAlloc; // the maximum number of memory chunks
+ int nChunks; // the current number of memory chunks
+ char ** pChunks; // the allocated memory
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates memory pieces of fixed size.]
+
+ Description [The size of the chunk is computed as the minimum of
+ 1024 entries and 64K. Can only work with entry size at least 4 byte long.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax )
+{
+ Gia_MmFixed_t * p;
+
+ p = ABC_ALLOC( Gia_MmFixed_t, 1 );
+ memset( p, 0, sizeof(Gia_MmFixed_t) );
+
+ p->nEntrySize = nEntrySize;
+ p->nEntriesAlloc = 0;
+ p->nEntriesUsed = 0;
+ p->pEntriesFree = NULL;
+
+ p->nChunkSize = nEntriesMax / 8;
+ if ( p->nChunkSize < 8 )
+ p->nChunkSize = 8;
+
+ p->nChunksAlloc = 64;
+ p->nChunks = 0;
+ p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc );
+
+ p->nMemoryUsed = 0;
+ p->nMemoryAlloc = 0;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose )
+{
+ int i;
+ if ( p == NULL )
+ return;
+ if ( fVerbose )
+ {
+ printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
+ p->nEntrySize, p->nChunkSize, p->nChunks );
+ printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
+ p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
+ }
+ for ( i = 0; i < p->nChunks; i++ )
+ ABC_FREE( p->pChunks[i] );
+ ABC_FREE( p->pChunks );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p )
+{
+ char * pTemp;
+ int i;
+
+ // check if there are still free entries
+ if ( p->nEntriesUsed == p->nEntriesAlloc )
+ { // need to allocate more entries
+ assert( p->pEntriesFree == NULL );
+ if ( p->nChunks == p->nChunksAlloc )
+ {
+ p->nChunksAlloc *= 2;
+ p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc );
+ }
+ p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize );
+ p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
+ // transform these entries into a linked list
+ pTemp = p->pEntriesFree;
+ for ( i = 1; i < p->nChunkSize; i++ )
+ {
+ *((char **)pTemp) = pTemp + p->nEntrySize;
+ pTemp += p->nEntrySize;
+ }
+ // set the last link
+ *((char **)pTemp) = NULL;
+ // add the chunk to the chunk storage
+ p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
+ // add to the number of entries allocated
+ p->nEntriesAlloc += p->nChunkSize;
+ }
+ // incrememt the counter of used entries
+ p->nEntriesUsed++;
+ if ( p->nEntriesMax < p->nEntriesUsed )
+ p->nEntriesMax = p->nEntriesUsed;
+ // return the first entry in the free entry list
+ pTemp = p->pEntriesFree;
+ p->pEntriesFree = *((char **)pTemp);
+ return pTemp;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry )
+{
+ // decrement the counter of used entries
+ p->nEntriesUsed--;
+ // add the entry to the linked list of free entries
+ *((char **)pEntry) = p->pEntriesFree;
+ p->pEntriesFree = pEntry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description [Relocates all the memory except the first chunk.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmFixedRestart( Gia_MmFixed_t * p )
+{
+ int i;
+ char * pTemp;
+ if ( p->nChunks == 0 )
+ return;
+ // deallocate all chunks except the first one
+ for ( i = 1; i < p->nChunks; i++ )
+ ABC_FREE( p->pChunks[i] );
+ p->nChunks = 1;
+ // transform these entries into a linked list
+ pTemp = p->pChunks[0];
+ for ( i = 1; i < p->nChunkSize; i++ )
+ {
+ *((char **)pTemp) = pTemp + p->nEntrySize;
+ pTemp += p->nEntrySize;
+ }
+ // set the last link
+ *((char **)pTemp) = NULL;
+ // set the free entry list
+ p->pEntriesFree = p->pChunks[0];
+ // set the correct statistics
+ p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
+ p->nMemoryUsed = 0;
+ p->nEntriesAlloc = p->nChunkSize;
+ p->nEntriesUsed = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p )
+{
+ return p->nMemoryAlloc;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p )
+{
+ return p->nEntriesMax;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates entries of flexible size.]
+
+ Description [Can only work with entry size at least 4 byte long.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_MmFlex_t * Gia_MmFlexStart()
+{
+ Gia_MmFlex_t * p;
+
+ p = ABC_ALLOC( Gia_MmFlex_t, 1 );
+ memset( p, 0, sizeof(Gia_MmFlex_t) );
+
+ p->nEntriesUsed = 0;
+ p->pCurrent = NULL;
+ p->pEnd = NULL;
+
+ p->nChunkSize = (1 << 18);
+ p->nChunksAlloc = 64;
+ p->nChunks = 0;
+ p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc );
+
+ p->nMemoryUsed = 0;
+ p->nMemoryAlloc = 0;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose )
+{
+ int i;
+ if ( p == NULL )
+ return;
+ if ( fVerbose )
+ {
+ printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
+ p->nChunkSize, p->nChunks );
+ printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
+ p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
+ }
+ for ( i = 0; i < p->nChunks; i++ )
+ ABC_FREE( p->pChunks[i] );
+ ABC_FREE( p->pChunks );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes )
+{
+ char * pTemp;
+ // check if there are still free entries
+ if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
+ { // need to allocate more entries
+ if ( p->nChunks == p->nChunksAlloc )
+ {
+ p->nChunksAlloc *= 2;
+ p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc );
+ }
+ if ( nBytes > p->nChunkSize )
+ {
+ // resize the chunk size if more memory is requested than it can give
+ // (ideally, this should never happen)
+ p->nChunkSize = 2 * nBytes;
+ }
+ p->pCurrent = ABC_ALLOC( char, p->nChunkSize );
+ p->pEnd = p->pCurrent + p->nChunkSize;
+ p->nMemoryAlloc += p->nChunkSize;
+ // add the chunk to the chunk storage
+ p->pChunks[ p->nChunks++ ] = p->pCurrent;
+ }
+ assert( p->pCurrent + nBytes <= p->pEnd );
+ // increment the counter of used entries
+ p->nEntriesUsed++;
+ // keep track of the memory used
+ p->nMemoryUsed += nBytes;
+ // return the next entry
+ pTemp = p->pCurrent;
+ p->pCurrent += nBytes;
+ return pTemp;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description [Relocates all the memory except the first chunk.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmFlexRestart( Gia_MmFlex_t * p )
+{
+ int i;
+ if ( p->nChunks == 0 )
+ return;
+ // deallocate all chunks except the first one
+ for ( i = 1; i < p->nChunks; i++ )
+ ABC_FREE( p->pChunks[i] );
+ p->nChunks = 1;
+ p->nMemoryAlloc = p->nChunkSize;
+ // transform these entries into a linked list
+ p->pCurrent = p->pChunks[0];
+ p->pEnd = p->pCurrent + p->nChunkSize;
+ p->nEntriesUsed = 0;
+ p->nMemoryUsed = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p )
+{
+ return p->nMemoryUsed;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Starts the hierarchical memory manager.]
+
+ Description [This manager can allocate entries of any size.
+ Iternally they are mapped into the entries with the number of bytes
+ equal to the power of 2. The smallest entry size is 8 bytes. The
+ next one is 16 bytes etc. So, if the user requests 6 bytes, he gets
+ 8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc.
+ The input parameters "nSteps" says how many fixed memory managers
+ are employed internally. Calling this procedure with nSteps equal
+ to 10 results in 10 hierarchically arranged internal memory managers,
+ which can allocate up to 4096 (1Kb) entries. Requests for larger
+ entries are handed over to malloc() and then ABC_FREE()ed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_MmStep_t * Gia_MmStepStart( int nSteps )
+{
+ Gia_MmStep_t * p;
+ int i, k;
+ p = ABC_ALLOC( Gia_MmStep_t, 1 );
+ memset( p, 0, sizeof(Gia_MmStep_t) );
+ p->nMems = nSteps;
+ // start the fixed memory managers
+ p->pMems = ABC_ALLOC( Gia_MmFixed_t *, p->nMems );
+ for ( i = 0; i < p->nMems; i++ )
+ p->pMems[i] = Gia_MmFixedStart( (8<<i), (1<<13) );
+ // set up the mapping of the required memory size into the corresponding manager
+ p->nMapSize = (4<<p->nMems);
+ p->pMap = ABC_ALLOC( Gia_MmFixed_t *, p->nMapSize+1 );
+ p->pMap[0] = NULL;
+ for ( k = 1; k <= 4; k++ )
+ p->pMap[k] = p->pMems[0];
+ for ( i = 0; i < p->nMems; i++ )
+ for ( k = (4<<i)+1; k <= (8<<i); k++ )
+ p->pMap[k] = p->pMems[i];
+//for ( i = 1; i < 100; i ++ )
+//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
+ p->nChunksAlloc = 64;
+ p->nChunks = 0;
+ p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the memory manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose )
+{
+ int i;
+ for ( i = 0; i < p->nMems; i++ )
+ Gia_MmFixedStop( p->pMems[i], fVerbose );
+ if ( p->nChunksAlloc )
+ {
+ for ( i = 0; i < p->nChunks; i++ )
+ ABC_FREE( p->pChunks[i] );
+ ABC_FREE( p->pChunks );
+ }
+ ABC_FREE( p->pMems );
+ ABC_FREE( p->pMap );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes )
+{
+ if ( nBytes == 0 )
+ return NULL;
+ if ( nBytes > p->nMapSize )
+ {
+ if ( p->nChunks == p->nChunksAlloc )
+ {
+ p->nChunksAlloc *= 2;
+ p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc );
+ }
+ p->pChunks[ p->nChunks++ ] = ABC_ALLOC( char, nBytes );
+ return p->pChunks[p->nChunks-1];
+ }
+ return Gia_MmFixedEntryFetch( p->pMap[nBytes] );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes )
+{
+ if ( nBytes == 0 )
+ return;
+ if ( nBytes > p->nMapSize )
+ {
+// ABC_FREE( pEntry );
+ return;
+ }
+ Gia_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_MmStepReadMemUsage( Gia_MmStep_t * p )
+{
+ int i, nMemTotal = 0;
+ for ( i = 0; i < p->nMems; i++ )
+ nMemTotal += p->pMems[i]->nMemoryAlloc;
+ return nMemTotal;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaPat.c b/src/aig/gia/giaPat.c
index 7968932c..bd43380f 100644
--- a/src/aig/gia/giaPat.c
+++ b/src/aig/gia/giaPat.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -127,3 +130,5 @@ void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, V
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaProp.c b/src/aig/gia/giaProp.c
index 1d9ed8cf..fee9aa40 100644
--- a/src/aig/gia/giaProp.c
+++ b/src/aig/gia/giaProp.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -169,3 +172,5 @@ int Gia_SatPathStart( Gia_Obj_t * p )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaReparam.c b/src/aig/gia/giaReparam.c
new file mode 100644
index 00000000..e33c1b7e
--- /dev/null
+++ b/src/aig/gia/giaReparam.c
@@ -0,0 +1,201 @@
+/**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"
+#include "giaAig.h"
+#include "saig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Specialized duplication.]
+
+ Description [Replaces registers by PIs/POs and PIs by registers.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupIn2Ff( Gia_Man_t * p )
+{
+ Vec_Int_t * vPiOuts;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ vPiOuts = Vec_IntAlloc( Gia_ManPiNum(p) );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) + 2 * Gia_ManPiNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ Vec_IntPush( vPiOuts, Gia_ManAppendCi(pNew) );
+ Gia_ManForEachRo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManForEachRi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManForEachPi( p, pObj, i )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vPiOuts, i) );
+ Gia_ManSetRegNum( pNew, Gia_ManPiNum(p) );
+ Vec_IntFree( vPiOuts );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reverses the above step.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManDupFf2In_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj )
+{
+ if ( pObj->Value != ~0 )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reverses the above step.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupFf2In( Gia_Man_t * p, int nFlopsOld )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachRo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ for ( i = Gia_ManPiNum(p) - nFlopsOld; i < Gia_ManPiNum(p); i++ )
+ Gia_ManPi(p, i)->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, nFlopsOld );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reparameterized to get rid of useless primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose )
+{
+// extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose );
+ Aig_Man_t * pMan, * pTemp;
+ Gia_Man_t * pNew, * pTmp;
+ int nFlopsOld = Gia_ManRegNum(p);
+ if ( fVerbose )
+ {
+ printf( "Original AIG:\n" );
+ Gia_ManPrintStats( p, 0 );
+ }
+
+ // perform input trimming
+ pNew = Gia_ManDupTrimmed( p, 1, 0 );
+ if ( fVerbose )
+ {
+ printf( "After PI trimming:\n" );
+ Gia_ManPrintStats( pNew, 0 );
+ }
+ // transform GIA
+ pNew = Gia_ManDupIn2Ff( pTmp = pNew );
+ Gia_ManStop( pTmp );
+ if ( fVerbose )
+ {
+ printf( "After PI-2-FF transformation:\n" );
+ Gia_ManPrintStats( pNew, 0 );
+ }
+
+ // derive AIG
+ pMan = Gia_ManToAigSimple( pNew );
+ Gia_ManStop( pNew );
+ // perform min-reg retiming
+ pMan = Saig_ManRetimeMinArea( pTemp = pMan, 10, 0, 0, 1, 0 );
+ Aig_ManStop( pTemp );
+ // derive GIA
+ pNew = Gia_ManFromAigSimple( pMan );
+ Aig_ManStop( pMan );
+ if ( fVerbose )
+ {
+ printf( "After min-area retiming:\n" );
+ Gia_ManPrintStats( pNew, 0 );
+ }
+
+ // transform back
+ pNew = Gia_ManDupFf2In( pTmp = pNew, nFlopsOld );
+ Gia_ManStop( pTmp );
+ if ( fVerbose )
+ {
+ printf( "After FF-2-PI tranformation:\n" );
+ Gia_ManPrintStats( pNew, 0 );
+ }
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaRetime.c b/src/aig/gia/giaRetime.c
index 967b6d01..58029b66 100644
--- a/src/aig/gia/giaRetime.c
+++ b/src/aig/gia/giaRetime.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -131,7 +134,7 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut )
Gia_ManForEachPi( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
// create the registers
- Vec_PtrForEachEntry( vCut, pObj, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i )
pObj->Value = Gia_LitNotCond( Gia_ManAppendCi(pNew), pObj->fPhase );
// duplicate logic above the cut
Gia_ManForEachCo( p, pObj, i )
@@ -146,11 +149,11 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut )
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
pObjRo->Value = pObjRi->Value;
// erase the data values on the internal nodes of the cut
- Vec_PtrForEachEntry( vCut, pObj, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i )
if ( Gia_ObjIsAnd(pObj) )
pObj->Value = ~0;
// duplicate logic below the cut
- Vec_PtrForEachEntry( vCut, pObj, i )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i )
{
Gia_ManRetimeDup_rec( pNew, pObj );
Gia_ManAppendCo( pNew, Gia_LitNotCond( pObj->Value, pObj->fPhase ) );
@@ -192,7 +195,7 @@ Gia_Man_t * Gia_ManRetimeForwardOne( Gia_Man_t * p, int * pnRegFixed, int * pnRe
vFlopClasses = Vec_IntAlloc( Gia_ManRegNum(p) );
}
// mark the retimable nodes
- Gia_ManResetTravId( p );
+ Gia_ManIncrementTravId( p );
Gia_ManMarkAutonomous( p );
// mark the retimable registers with the fresh trav ID
Gia_ManIncrementTravId( p );
@@ -295,3 +298,5 @@ Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSat.c b/src/aig/gia/giaSat.c
index 29ade5c6..c2d70795 100644
--- a/src/aig/gia/giaSat.c
+++ b/src/aig/gia/giaSat.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -419,3 +422,5 @@ void Gia_ManSatExperiment( Gia_Man_t * p )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c
index 5ac8e04a..a482d024 100644
--- a/src/aig/gia/giaScl.c
+++ b/src/aig/gia/giaScl.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -187,7 +190,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose )
if ( Gia_ObjFanin0(pObjRi)->Value == 0 )
Gia_ObjFanin0(pObjRi)->Value = 2*nFanins++;
pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p) );
- pMaps = ABC_FALLOC( unsigned, 2 * nFanins );
+ pMaps = ABC_FALLOC( unsigned, 2 * nFanins );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
{
iLit = Gia_ObjFanin0Copy( pObjRi );
@@ -215,7 +218,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose )
// printf( "ReduceEquiv detected %d constant regs and %d equivalent regs.\n", Counter0, Counter );
ABC_FREE( pMaps );
if ( Counter0 || Counter )
- pNew = Gia_ManDupDfsCiMap( p, pCi2Lit, NULL );
+ pNew = Gia_ManDupDfsCiMap( p, (int *)pCi2Lit, NULL );
else
pNew = p;
ABC_FREE( pCi2Lit );
@@ -274,3 +277,5 @@ Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fV
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaShrink.c b/src/aig/gia/giaShrink.c
new file mode 100644
index 00000000..fc9e80d6
--- /dev/null
+++ b/src/aig/gia/giaShrink.c
@@ -0,0 +1,151 @@
+/**CFile****************************************************************
+
+ FileName [giaShrink.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Implementation of mapShrink based on ideas of Niklas Een.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaShrink.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "aig.h"
+#include "dar.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern int Dar_LibEvalBuild( Gia_Man_t * p, Vec_Int_t * vCut, unsigned uTruth, int fKeepLevel, Vec_Int_t * vLeavesBest );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs AIG shrinking using the current mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose )
+{
+ Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pFanin;
+ unsigned * pTruth;
+ int i, k, iFan, clk = clock();
+ int ClassCounts[222] = {0};
+ int * pLutClass, Counter = 0;
+ assert( p->pMapping != NULL );
+ if ( Gia_ManLutSizeMax( p ) > 4 )
+ {
+ printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" );
+ return NULL;
+ }
+ pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ vLeaves = Vec_IntAlloc( 0 );
+ vTruth = Vec_IntAlloc( (1<<16) );
+ vVisited = Vec_IntAlloc( 0 );
+ vLeavesBest = Vec_IntAlloc( 4 );
+ // prepare the library
+ Dar_LibPrepare( 5 );
+ // clean the old manager
+ Gia_ManCleanTruth( p );
+ Gia_ManSetPhase( p );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ // start the new manager
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Gia_UtilStrsav( p->pName );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ else if ( Gia_ObjIsLut(p, i) )
+ {
+ Counter++;
+ // collect leaves of this gate
+ Vec_IntClear( vLeaves );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Vec_IntPush( vLeaves, iFan );
+ for ( ; k < 4; k++ )
+ Vec_IntPush( vLeaves, 0 );
+ //.compute the truth table
+ pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited );
+ // change from node IDs to their literals
+ Gia_ManForEachObjVec( vLeaves, p, pFanin, k )
+ {
+ assert( Gia_ObjValue(pFanin) != ~0 );
+ Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) );
+ }
+ // derive new structre
+ if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) )
+ pObj->Value = 0;
+ else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) )
+ pObj->Value = 1;
+ else
+ {
+ pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest );
+ pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase );
+ }
+ }
+ }
+ // cleanup the AIG
+ Gia_ManHashStop( pNew );
+ // check the presence of dangling nodes
+ if ( Gia_ManHasDangling(pNew) )
+ {
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) )
+ printf( "Gia_ManPerformMapShrink() node reduction after sweep %6d -> %6d.\n", Gia_ManAndNum(pTemp), Gia_ManAndNum(pNew) );
+ Gia_ManStop( pTemp );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vTruth );
+ Vec_IntFree( vVisited );
+ Vec_IntFree( vLeavesBest );
+ if ( fVerbose )
+ {
+ printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) );
+ ABC_PRT( "Total runtime", clock() - clk );
+ }
+ ABC_FREE( pLutClass );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c
index ae9e304c..68b50fb6 100644
--- a/src/aig/gia/giaSim.c
+++ b/src/aig/gia/giaSim.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -65,6 +68,28 @@ void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p )
p->TimeLimit = 60; // time limit in seconds
p->fCheckMiter = 0; // check if miter outputs are non-zero
p->fVerbose = 0; // enables verbose output
+ p->iOutFail = -1; // index of the failed output
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimDelete( Gia_ManSim_t * p )
+{
+ Vec_IntFreeP( &p->vCis2Ids );
+ Gia_ManStopP( &p->pAig );
+ ABC_FREE( p->pDataSim );
+ ABC_FREE( p->pDataSimCis );
+ ABC_FREE( p->pDataSimCos );
+ ABC_FREE( p );
}
/**Function*************************************************************
@@ -90,10 +115,18 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars )
p->pDataSim = ABC_ALLOC( unsigned, p->nWords * p->pAig->nFront );
p->pDataSimCis = ABC_ALLOC( unsigned, p->nWords * Gia_ManCiNum(p->pAig) );
p->pDataSimCos = ABC_ALLOC( unsigned, p->nWords * Gia_ManCoNum(p->pAig) );
+ if ( !p->pDataSim || !p->pDataSimCis || !p->pDataSimCos )
+ {
+ Abc_Print( 1, "Simulator could not allocate %.2f Gb for simulation info.\n",
+ 4.0 * p->nWords * (p->pAig->nFront + Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig)) / (1<<30) );
+ Gia_ManSimDelete( p );
+ return NULL;
+ }
p->vCis2Ids = Vec_IntAlloc( Gia_ManCiNum(p->pAig) );
Vec_IntForEachEntry( pAig->vCis, Entry, i )
Vec_IntPush( p->vCis2Ids, i ); // do we need p->vCis2Ids?
- printf( "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n",
+ if ( pPars->fVerbose )
+ Abc_Print( 1, "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n",
12.0*Gia_ManObjNum(p->pAig)/(1<<20),
4.0*p->nWords*p->pAig->nFront/(1<<20),
4.0*p->nWords*(Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig))/(1<<20) );
@@ -111,27 +144,6 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars )
SeeAlso []
***********************************************************************/
-void Gia_ManSimDelete( Gia_ManSim_t * p )
-{
- Vec_IntFree( p->vCis2Ids );
- Gia_ManStop( p->pAig );
- ABC_FREE( p->pDataSim );
- ABC_FREE( p->pDataSimCis );
- ABC_FREE( p->pDataSimCos );
- ABC_FREE( p );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
static inline void Gia_ManSimInfoRandom( Gia_ManSim_t * p, unsigned * pInfo )
{
int w;
@@ -171,9 +183,9 @@ static inline void Gia_ManSimInfoZero( Gia_ManSim_t * p, unsigned * pInfo )
static inline int Gia_ManSimInfoIsZero( Gia_ManSim_t * p, unsigned * pInfo )
{
int w;
- for ( w = p->nWords-1; w >= 0; w-- )
+ for ( w = 0; w < p->nWords; w++ )
if ( pInfo[w] )
- return 32*(w-1) + Gia_WordFindFirstBit( pInfo[w] );
+ return 32*w + Gia_WordFindFirstBit( pInfo[w] );
return -1;
}
@@ -418,9 +430,9 @@ static inline int Gia_ManCheckPos( Gia_ManSim_t * p, int * piPo, int * piPat )
SeeAlso []
***********************************************************************/
-Gia_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids )
+Abc_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids )
{
- Gia_Cex_t * p;
+ Abc_Cex_t * p;
unsigned * pData;
int f, i, w, iPioId, Counter;
p = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 );
@@ -468,43 +480,44 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars )
for ( i = 0; i < pPars->nIters; i++ )
{
Gia_ManSimulateRound( p );
-
if ( pPars->fVerbose )
{
- printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit );
- printf( "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC );
+ Abc_Print( 1, "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit );
+ Abc_Print( 1, "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC );
}
if ( pPars->fCheckMiter && Gia_ManCheckPos( p, &iOut, &iPat ) )
{
+ pPars->iOutFail = iOut;
pAig->pCexSeq = Gia_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids );
- printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", iOut, i );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d was asserted in frame %d. ", iOut, i );
if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) )
{
- printf( "\n" );
- printf( "Generated counter-example is INVALID \n" );
- printf( "\n" );
+// Abc_Print( 1, "\n" );
+ Abc_Print( 1, "\nGenerated counter-example is INVALID. " );
+// Abc_Print( 1, "\n" );
}
else
{
- printf( "\n" );
- printf( "Generated counter-example is fine \n" );
- printf( "\n" );
+// Abc_Print( 1, "\n" );
+// if ( pPars->fVerbose )
+// Abc_Print( 1, "\nGenerated counter-example is verified correctly. " );
+// Abc_Print( 1, "\n" );
}
RetValue = 1;
break;
}
if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit )
{
- printf( "No bug detected after %d frames with time limit %d seconds. \n", i+1, pPars->TimeLimit );
+ i++;
break;
}
-
if ( i < pPars->nIters - 1 )
Gia_ManSimInfoTransfer( p );
}
Gia_ManSimDelete( p );
- printf( "Simulated %d frames with %d words. ", i, pPars->nWords );
- ABC_PRT( "Time", clock() - clkTotal );
+ if ( pAig->pCexSeq == NULL )
+ Abc_Print( 1, "No bug detected after simulating %d frames with %d words. ", i, pPars->nWords );
+ Abc_PrintTime( 1, "Time", clock() - clkTotal );
return RetValue;
}
@@ -513,3 +526,5 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c
index 8574297d..f73e92bb 100644
--- a/src/aig/gia/giaSort.c
+++ b/src/aig/gia/giaSort.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -266,3 +269,5 @@ int * Gia_SortFloats( float * pArray, int * pPerm, int nSize )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c
new file mode 100644
index 00000000..cce0b68d
--- /dev/null
+++ b/src/aig/gia/giaSpeedup.c
@@ -0,0 +1,810 @@
+/**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"
+#include "if.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the pins in the decreasing order of delays.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_LutDelayTraceSortPins( Gia_Man_t * p, int iObj, int * pPinPerm, float * pPinDelays )
+{
+ int iFanin, i, j, best_i, temp;
+ assert( Gia_ObjIsLut(p, iObj) );
+ // start the trivial permutation and collect pin delays
+ Gia_LutForEachFanin( p, iObj, iFanin, i )
+ {
+ pPinPerm[i] = i;
+ pPinDelays[i] = Gia_ObjTimeArrival(p, iFanin);
+ }
+ // selection sort the pins in the decreasible order of delays
+ // this order will match the increasing order of LUT input pins
+ for ( i = 0; i < Gia_ObjLutSize(p, iObj)-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < Gia_ObjLutSize(p, iObj); j++ )
+ if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] )
+ best_i = j;
+ if ( best_i == i )
+ continue;
+ temp = pPinPerm[i];
+ pPinPerm[i] = pPinPerm[best_i];
+ pPinPerm[best_i] = temp;
+ }
+ // verify
+ assert( Gia_ObjLutSize(p, iObj) == 0 || pPinPerm[0] < Gia_ObjLutSize(p, iObj) );
+ for ( i = 1; i < Gia_ObjLutSize(p, iObj); i++ )
+ {
+ assert( pPinPerm[i] < Gia_ObjLutSize(p, iObj) );
+ assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the pins in the decreasing order of delays.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm )
+{
+ int i;
+ for ( i = 0; i < Gia_ObjLutSize(p, iFanout); i++ )
+ if ( Gia_ObjLutFanin(p, iFanout, pPinPerm[i]) == iFanin )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the arrival times for the given object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
+{
+ If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ int k, iFanin, pPinPerm[32];
+ float pPinDelays[32];
+ float tArrival, * pDelays;
+ if ( Gia_ObjIsCi(pObj) )
+ return Gia_ObjTimeArrival(p, iObj);
+ if ( Gia_ObjIsCo(pObj) )
+ return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) );
+ assert( Gia_ObjIsLut(p, iObj) );
+ tArrival = -TIM_ETERNITY;
+ if ( pLutLib == NULL )
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 )
+ tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0;
+ }
+ else if ( !pLutLib->fVarPinDelays )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] )
+ tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[0];
+ }
+ else
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ if ( fUseSorting )
+ {
+ Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays );
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tArrival < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k] )
+ tArrival = Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k];
+ }
+ else
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[k] )
+ tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[k];
+ }
+ }
+ if ( Gia_ObjLutSize(p, iObj) == 0 )
+ tArrival = 0.0;
+ return tArrival;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Propagates the required times through the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
+{
+ If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib;
+ int k, iFanin, pPinPerm[32];
+ float pPinDelays[32];
+ float tRequired = 0.0; // Suppress "might be used uninitialized"
+ float * pDelays;
+ assert( Gia_ObjIsLut(p, iObj) );
+ if ( pLutLib == NULL )
+ {
+ tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0;
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
+ Gia_ObjSetTimeRequired( p, iFanin, tRequired );
+ }
+ else if ( !pLutLib->fVarPinDelays )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[0];
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
+ Gia_ObjSetTimeRequired( p, iFanin, tRequired );
+ }
+ else
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ if ( fUseSorting )
+ {
+ Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays );
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ {
+ tRequired = Gia_ObjTimeRequired( p, iObj) - pDelays[k];
+ if ( Gia_ObjTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) > tRequired )
+ Gia_ObjSetTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k]), tRequired );
+ }
+ }
+ else
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ {
+ tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[k];
+ if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
+ Gia_ObjSetTimeRequired( p, iFanin, tRequired );
+ }
+ }
+ }
+ return tRequired;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the delay trace of the given network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Gia_ManDelayTraceLut( Gia_Man_t * p )
+{
+ int fUseSorting = 1;
+ If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib;
+ Vec_Int_t * vObjs;
+ Gia_Obj_t * pObj;
+ float tArrival, tArrivalCur, tRequired, tSlack;
+ int i, iObj;
+
+ // get the library
+ if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) )
+ {
+ printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
+ pLutLib->LutMax, Gia_ManLutSizeMax(p) );
+ return -TIM_ETERNITY;
+ }
+
+ // initialize the arrival times
+ Gia_ManTimeStart( p );
+
+ // propagate arrival times
+ if ( p->pManTime )
+ Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( !Gia_ObjIsCi(pObj) && !Gia_ObjIsCo(pObj) && !Gia_ObjIsLut(p, i) )
+ continue;
+ tArrival = Gia_ObjComputeArrival( p, i, fUseSorting );
+ if ( Gia_ObjIsCi(pObj) && p->pManTime )
+ {
+ tArrival = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) );
+//printf( "%.3f ", tArrival );
+ }
+ if ( Gia_ObjIsCo(pObj) && p->pManTime )
+ Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), tArrival );
+ Gia_ObjSetTimeArrival( p, i, tArrival );
+ }
+
+ // get the latest arrival times
+ tArrival = -TIM_ETERNITY;
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ tArrivalCur = Gia_ObjTimeArrivalObj( p, Gia_ObjFanin0(pObj) );
+ Gia_ObjSetTimeArrival( p, Gia_ObjId(p,pObj), tArrivalCur );
+ if ( tArrival < tArrivalCur )
+ tArrival = tArrivalCur;
+ }
+
+ // initialize the required times
+ if ( p->pManTime )
+ {
+ Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime );
+ Tim_ManSetCoRequiredAll( (Tim_Man_t *)p->pManTime, tArrival );
+ }
+ else
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjSetTimeRequiredObj( p, pObj, tArrival );
+ }
+
+ // propagate the required times
+ vObjs = Gia_ManOrderReverse( p );
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ {
+ if ( i == 1137 )
+ {
+ int s = 0;
+ }
+ pObj = Gia_ManObj(p, iObj);
+//printf( "%d ", Gia_ObjLevel(p, pObj) );
+ if ( Gia_ObjIsLut(p, iObj) )
+ {
+ Gia_ObjPropagateRequired( p, iObj, fUseSorting );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ {
+ if ( p->pManTime )
+ Tim_ManSetCiRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), Gia_ObjTimeRequired(p, iObj) );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ if ( p->pManTime )
+ {
+ tRequired = Tim_ManGetCoRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) );
+ Gia_ObjSetTimeRequired( p, iObj, tRequired );
+ }
+ if ( Gia_ObjTimeRequired(p, Gia_ObjFaninId0p(p, pObj)) > Gia_ObjTimeRequired(p, iObj) )
+ Gia_ObjSetTimeRequired(p, Gia_ObjFaninId0p(p, pObj), Gia_ObjTimeRequired(p, iObj) );
+ }
+
+ // set slack for this object
+ tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj);
+ assert( tSlack + 0.01 > 0.0 );
+ Gia_ObjSetTimeSlack( p, iObj, tSlack < 0.0 ? 0.0 : tSlack );
+ }
+ Vec_IntFree( vObjs );
+ return tArrival;
+}
+
+#if 0
+
+/**Function*************************************************************
+
+ Synopsis [Computes the required times for the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Gia_ObjComputeRequired( Gia_Man_t * p, int iObj, int fUseSorting )
+{
+ If_Lib_t * pLutLib = p->pLutLib;
+ int pPinPerm[32];
+ float pPinDelays[32];
+ Gia_Obj_t * pFanout;
+ float tRequired, tDelay, * pDelays;
+ int k, iFanin;
+ if ( Gia_ObjIsCo(iObj) )
+ return Gia_ObjTimeRequired( p, iObj);
+ tRequired = TIM_ETERNITY;
+ if ( pLutLib == NULL )
+ {
+ Gia_ObjForEachFanout( iObj, pFanout, k )
+ {
+ tDelay = Gia_ObjIsCo(pFanout)? 0.0 : 1.0;
+ if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay )
+ tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay;
+ }
+ }
+ else if ( !pLutLib->fVarPinDelays )
+ {
+ Gia_ObjForEachFanout( iObj, pFanout, k )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)];
+ tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[0];
+ if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay )
+ tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay;
+ }
+ }
+ else
+ {
+ if ( fUseSorting )
+ {
+ Gia_ObjForEachFanout( iObj, pFanout, k )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)];
+ Gia_LutDelayTraceSortPins( p, pFanout, pPinPerm, pPinDelays );
+ iFanin = Gia_LutWhereIsPin( p, pFanout, iObj, pPinPerm );
+ assert( Gia_ObjLutFanin( p, pFanout, pPinPerm[iFanin]) == iObj );
+ tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin];
+ if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay )
+ tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay;
+ }
+ }
+ else
+ {
+ Gia_ObjForEachFanout( iObj, pFanout, k )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)];
+ iFanin = Gia_ObjFindFanin( p, pFanout, iObj );
+ assert( Gia_ObjLutFanin(p, pFanout, iFanin) == iObj );
+ tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin];
+ if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay )
+ tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay;
+ }
+ }
+ }
+ return tRequired;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the arrival times for the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_LutVerifyTiming( Gia_Man_t * p )
+{
+ int iObj;
+ float tArrival, tRequired;
+ int i;
+ Gia_LutForEachObj( p, iObj, i )
+ {
+ if ( Gia_ObjIsCi(iObj) && Gia_ObjFanoutNum(iObj) == 0 )
+ continue;
+ tArrival = Gia_ObjComputeArrival( p, iObj, 1 );
+ tRequired = Gia_ObjComputeRequired( p, iObj, 1 );
+ if ( !Gia_LutTimeEqual( tArrival, Gia_ObjTimeArrival( p, iObj), (float)0.01 ) )
+ printf( "Gia_LutVerifyTiming(): Object %d has different arrival time (%.2f) from computed (%.2f).\n",
+ iObj->Id, Gia_ObjTimeArrival( p, iObj), tArrival );
+ if ( !Gia_LutTimeEqual( tRequired, Gia_ObjTimeRequired( p, iObj), (float)0.01 ) )
+ printf( "Gia_LutVerifyTiming(): Object %d has different required time (%.2f) from computed (%.2f).\n",
+ iObj->Id, Gia_ObjTimeRequired( p, iObj), tRequired );
+ }
+ return 1;
+}
+
+#endif
+
+/**Function*************************************************************
+
+ Synopsis [Prints the delay trace for the given network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
+{
+ If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib;
+ int i, Nodes, * pCounters;
+ float tArrival, tDelta, nSteps, Num;
+ // get the library
+ if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) )
+ {
+ printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
+ pLutLib->LutMax, Gia_ManLutSizeMax(p) );
+ return -ABC_INFINITY;
+ }
+ // decide how many steps
+ nSteps = pLutLib ? 20 : Gia_ManLutLevel(p);
+ pCounters = ABC_ALLOC( int, nSteps + 1 );
+ memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
+ // perform delay trace
+ tArrival = Gia_ManDelayTraceLut( p );
+ tDelta = tArrival / nSteps;
+ // count how many nodes have slack in the corresponding intervals
+ Gia_ManForEachLut( p, i )
+ {
+ if ( Gia_ObjLutSize(p, i) == 0 )
+ continue;
+ Num = Gia_ObjTimeSlack(p, i) / tDelta;
+ if ( Num > nSteps )
+ continue;
+ assert( Num >=0 && Num <= nSteps );
+ pCounters[(int)Num]++;
+ }
+ // print the results
+ if ( fVerbose )
+ {
+ printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
+ Nodes = 0;
+ for ( i = 0; i < nSteps; i++ )
+ {
+ Nodes += pCounters[i];
+ printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
+ pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
+ }
+ }
+ ABC_FREE( pCounters );
+ Gia_ManTimeStop( p );
+ return tArrival;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Determines timing-critical edges of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Gia_LutDelayTraceTCEdges( Gia_Man_t * p, int iObj, float tDelta )
+{
+ If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib;
+ int pPinPerm[32];
+ float pPinDelays[32];
+ float tRequired, * pDelays;
+ unsigned uResult = 0;
+ int k, iFanin;
+ tRequired = Gia_ObjTimeRequired( p, iObj );
+ if ( pLutLib == NULL )
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + 1.0 + tDelta )
+ uResult |= (1 << k);
+ }
+ else if ( !pLutLib->fVarPinDelays )
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] + tDelta )
+ uResult |= (1 << k);
+ }
+ else
+ {
+ pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
+ Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays );
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( tRequired < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) + pDelays[k] + tDelta )
+ uResult |= (1 << pPinPerm[k]);
+ }
+ return uResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds strashed nodes for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSpeedupObj_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return 1;
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin0(pObj), vNodes ) )
+ return 0;
+ if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin1(pObj), vNodes ) )
+ return 0;
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds strashed nodes for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSpeedupObj( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vTimes )
+{
+ Vec_Int_t * vNodes;
+ Gia_Obj_t * pTemp = NULL;
+ int pCofs[32], nCofs, nSkip, i, k, iResult, iObj;
+ // mark the leaves
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ Gia_ManForEachObjVec( vLeaves, p, pTemp, i )
+ Gia_ObjSetTravIdCurrent( p, pTemp );
+ // collect the AIG nodes
+ vNodes = Vec_IntAlloc( 100 );
+ if ( !Gia_ManSpeedupObj_rec( p, pObj, vNodes ) )
+ {
+ printf( "Bad node!!!\n" );
+ Vec_IntFree( vNodes );
+ return;
+ }
+ // derive cofactors
+ nCofs = (1 << Vec_IntSize(vTimes));
+ for ( i = 0; i < nCofs; i++ )
+ {
+ Gia_ManForEachObjVec( vLeaves, p, pTemp, k )
+ pTemp->Value = Gia_Var2Lit( Gia_ObjId(p, pTemp), 0 );
+ Gia_ManForEachObjVec( vTimes, p, pTemp, k )
+ pTemp->Value = ((i & (1<<k)) != 0);
+ Gia_ManForEachObjVec( vNodes, p, pTemp, k )
+ pTemp->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pTemp), Gia_ObjFanin1Copy(pTemp) );
+ pCofs[i] = pTemp->Value;
+ }
+ Vec_IntFree( vNodes );
+ // collect the resulting tree
+ Gia_ManForEachObjVec( vTimes, p, pTemp, k )
+ for ( nSkip = (1<<k), i = 0; i < nCofs; i += 2*nSkip )
+ pCofs[i] = Gia_ManHashMux( pNew, Gia_ObjToLit(p,pTemp), pCofs[i+nSkip], pCofs[i] );
+ // create choice node (pObj is repr and ppCofs[0] is new)
+ iObj = Gia_ObjId( p, pObj );
+ iResult = Gia_Lit2Var( pCofs[0] );
+ if ( iResult <= iObj )
+ return;
+ Gia_ObjSetRepr( pNew, iResult, iObj );
+ Gia_ObjSetNext( pNew, iResult, Gia_ObjNext(pNew, iObj) );
+ Gia_ObjSetNext( pNew, iObj, iResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds choices to speed up the network by the given percentage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Vec_Int_t * vTimeCries, * vTimeFanins;
+ int iObj, iFanin, iFanin2, nNodesNew;
+ float tDelta, tArrival;
+ int i, k, k2, Counter, CounterRes, nTimeCris;
+ int fUseLutLib = (p->pLutLib != NULL);
+ void * pTempTim = NULL;
+ unsigned * puTCEdges;
+ assert( p->pMapping != NULL );
+ if ( !fUseLutLib && p->pManTime )
+ {
+ pTempTim = p->pManTime;
+ p->pManTime = Tim_ManDup( (Tim_Man_t *)pTempTim, 1 );
+ }
+ // perform delay trace
+ tArrival = Gia_ManDelayTraceLut( p );
+ tDelta = fUseLutLib ? tArrival*Percentage/100.0 : 1.0;
+ if ( fVerbose )
+ {
+ printf( "Max delay = %.2f. Delta = %.2f. ", tArrival, tDelta );
+ printf( "Using %s model. ", fUseLutLib ? "LUT library" : "unit-delay" );
+ if ( fUseLutLib )
+ printf( "Percentage = %d. ", Percentage );
+ printf( "\n" );
+ }
+ // mark the timing critical nodes and edges
+ puTCEdges = ABC_CALLOC( unsigned, Gia_ManObjNum(p) );
+ Gia_ManForEachLut( p, iObj )
+ {
+ if ( Gia_ObjTimeSlack(p, iObj) >= tDelta )
+ continue;
+ puTCEdges[iObj] = Gia_LutDelayTraceTCEdges( p, iObj, tDelta );
+ }
+ if ( fVerbose )
+ {
+ Counter = CounterRes = 0;
+ Gia_ManForEachLut( p, iObj )
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && Gia_ObjTimeSlack(p, iFanin) < tDelta )
+ Counter++;
+ CounterRes += Gia_WordCountOnes( puTCEdges[iObj] );
+ }
+ printf( "Edges: Total = %7d. 0-slack = %7d. Critical = %7d. Ratio = %4.2f\n",
+ Gia_ManLutFaninCount(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 );
+ }
+
+ // start the resulting network
+ pNew = Gia_ManDup( p );
+ Gia_ManHashStart( pNew );
+ nNodesNew = 1000 + 3 * Gia_ManObjNum(pNew);
+ pNew->pNexts = ABC_CALLOC( int, nNodesNew );
+ pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, nNodesNew );
+ for ( i = 0; i < nNodesNew; i++ )
+ Gia_ObjSetRepr( pNew, i, GIA_VOID );
+
+ // collect nodes to be used for resynthesis
+ Counter = CounterRes = 0;
+ vTimeCries = Vec_IntAlloc( 16 );
+ vTimeFanins = Vec_IntAlloc( 16 );
+ Gia_ManForEachLut( p, iObj )
+ {
+ if ( Gia_ObjTimeSlack(p, iObj) >= tDelta )
+ continue;
+ // count the number of non-PI timing-critical nodes
+ nTimeCris = 0;
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) )
+ nTimeCris++;
+ if ( !fVeryVerbose && nTimeCris == 0 )
+ continue;
+ Counter++;
+ // count the total number of timing critical second-generation nodes
+ Vec_IntClear( vTimeCries );
+ if ( nTimeCris )
+ {
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) )
+ Gia_LutForEachFanin( p, iFanin, iFanin2, k2 )
+ if ( puTCEdges[iFanin] & (1<<k2) )
+ Vec_IntPushUnique( vTimeCries, iFanin2 );
+ }
+// if ( !fVeryVerbose && (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) )
+ if ( (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) )
+ continue;
+ CounterRes++;
+ // collect second generation nodes
+ Vec_IntClear( vTimeFanins );
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ {
+ if ( Gia_ObjIsCi(Gia_ManObj(p, iFanin)) )
+ Vec_IntPushUnique( vTimeFanins, iFanin );
+ else
+ Gia_LutForEachFanin( p, iFanin, iFanin2, k2 )
+ Vec_IntPushUnique( vTimeFanins, iFanin2 );
+ }
+ // print the results
+ if ( fVeryVerbose )
+ {
+ printf( "%5d Node %5d : %d %2d %2d ", Counter, iObj,
+ nTimeCris, Vec_IntSize(vTimeCries), Vec_IntSize(vTimeFanins) );
+ Gia_LutForEachFanin( p, iObj, iFanin, k )
+ printf( "%d(%.2f)%s ", iFanin, Gia_ObjTimeSlack(p, iFanin), (puTCEdges[iObj] & (1<<k))? "*":"" );
+ printf( "\n" );
+ }
+ // add the node to choices
+ if ( Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree )
+ continue;
+ // order the fanins in the increasing order of criticalily
+ if ( Vec_IntSize(vTimeCries) > 1 )
+ {
+ iFanin = Vec_IntEntry( vTimeCries, 0 );
+ iFanin2 = Vec_IntEntry( vTimeCries, 1 );
+ if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) )
+ {
+ Vec_IntWriteEntry( vTimeCries, 0, iFanin2 );
+ Vec_IntWriteEntry( vTimeCries, 1, iFanin );
+ }
+ }
+ if ( Vec_IntSize(vTimeCries) > 2 )
+ {
+ iFanin = Vec_IntEntry( vTimeCries, 1 );
+ iFanin2 = Vec_IntEntry( vTimeCries, 2 );
+ if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) )
+ {
+ Vec_IntWriteEntry( vTimeCries, 1, iFanin2 );
+ Vec_IntWriteEntry( vTimeCries, 2, iFanin );
+ }
+ iFanin = Vec_IntEntry( vTimeCries, 0 );
+ iFanin2 = Vec_IntEntry( vTimeCries, 1 );
+ if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) )
+ {
+ Vec_IntWriteEntry( vTimeCries, 0, iFanin2 );
+ Vec_IntWriteEntry( vTimeCries, 1, iFanin );
+ }
+ }
+ // add choice
+ Gia_ManSpeedupObj( pNew, p, Gia_ManObj(p,iObj), vTimeFanins, vTimeCries );
+ // quit if the number of nodes is large
+ if ( Gia_ManObjNum(pNew) > nNodesNew - 100 )
+ {
+ printf( "Speedup stopped adding choices because there was too many to add.\n" );
+ break;
+ }
+ }
+ Gia_ManTimeStop( p );
+ Vec_IntFree( vTimeCries );
+ Vec_IntFree( vTimeFanins );
+ ABC_FREE( puTCEdges );
+ if ( fVerbose )
+ printf( "Nodes: Total = %7d. 0-slack = %7d. Workable = %7d. Ratio = %4.2f\n",
+ Gia_ManLutNum(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 );
+ if ( pTempTim )
+ {
+ Tim_ManStop( (Tim_Man_t *)p->pManTime );
+ p->pManTime = pTempTim;
+ }
+ // derive AIG with choices
+//Gia_ManPrintStats( pNew, 0 );
+ pTemp = Gia_ManEquivToChoices( pNew, 1 );
+ Gia_ManStop( pNew );
+//Gia_ManPrintStats( pTemp, 0 );
+// pNew = Gia_ManDupOrderDfsChoices( pTemp );
+// Gia_ManStop( pTemp );
+//Gia_ManPrintStats( pNew, 0 );
+// return pNew;
+ return pTemp;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSupMin.c b/src/aig/gia/giaSupMin.c
new file mode 100644
index 00000000..4abaab0f
--- /dev/null
+++ b/src/aig/gia/giaSupMin.c
@@ -0,0 +1,165 @@
+/**CFile****************************************************************
+
+ FileName [giaSupMin.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Support minimization for AIGs with don't-cares.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaSupMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "kit.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// decomposition manager
+typedef struct Gia_ManSup_t_ Gia_ManSup_t;
+struct Gia_ManSup_t_
+{
+ int nVarsMax; // the max number of variables
+ int nWordsMax; // the max number of words
+ Vec_Ptr_t * vTruthVars; // elementary truth tables
+ Vec_Ptr_t * vTruthNodes; // internal truth tables
+ // current problem
+ Gia_Man_t * pGia;
+ int iData;
+ int iCare;
+ Vec_Int_t * vConeCare;
+ Vec_Int_t * vConeData;
+ unsigned * pTruthIn;
+ unsigned * pTruthOut;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts Decmetry manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_ManSup_t * Gia_ManSupStart( int nVarsMax )
+{
+ Gia_ManSup_t * p;
+ assert( nVarsMax <= 20 );
+ p = ABC_CALLOC( Gia_ManSup_t, 1 );
+ p->nVarsMax = nVarsMax;
+ p->nWordsMax = Kit_TruthWordNum( p->nVarsMax );
+ p->vTruthVars = Vec_PtrAllocTruthTables( p->nVarsMax );
+ p->vTruthNodes = Vec_PtrAllocSimInfo( 512, p->nWordsMax );
+ p->vConeCare = Vec_IntAlloc( 512 );
+ p->vConeData = Vec_IntAlloc( 512 );
+ p->pTruthIn = ABC_ALLOC( unsigned, p->nWordsMax );
+ p->pTruthOut = ABC_ALLOC( unsigned, p->nWordsMax );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops Decmetry manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSupStop( Gia_ManSup_t * p )
+{
+ ABC_FREE( p->pTruthIn );
+ ABC_FREE( p->pTruthOut );
+ Vec_IntFreeP( &p->vConeCare );
+ Vec_IntFreeP( &p->vConeData );
+ Vec_PtrFreeP( &p->vTruthVars );
+ Vec_PtrFreeP( &p->vTruthNodes );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSupExperimentOne( Gia_ManSup_t * p, Gia_Obj_t * pData, Gia_Obj_t * pCare )
+{
+ int iData = Gia_ObjId( p->pGia, Gia_Regular(pData) );
+ int iCare = Gia_ObjId( p->pGia, Gia_Regular(pCare) );
+ if ( !Gia_ObjIsAnd(Gia_Regular(pCare)) )
+ {
+ Abc_Print( 1, "Enable is not an AND.\n" );
+ return;
+ }
+ Abc_Print( 1, "DataSupp = %6d. DataCone = %6d. CareSupp = %6d. CareCone = %6d.",
+ Gia_ManSuppSize( p->pGia, &iData, 1 ),
+ Gia_ManConeSize( p->pGia, &iData, 1 ),
+ Gia_ManSuppSize( p->pGia, &iCare, 1 ),
+ Gia_ManConeSize( p->pGia, &iCare, 1 ) );
+ Abc_Print( 1, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSupExperiment( Gia_Man_t * pGia, Vec_Int_t * vPairs )
+{
+ Gia_ManSup_t * p;
+ Gia_Obj_t * pData, * pCare;
+ int i;
+ p = Gia_ManSupStart( 16 );
+ p->pGia = pGia;
+ assert( Vec_IntSize(vPairs) % 2 == 0 );
+ for ( i = 0; i < Vec_IntSize(vPairs)/2; i++ )
+ {
+ Abc_Print( 1, "%6d : ", i );
+ pData = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+0) );
+ pCare = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+1) );
+ Gia_ManSupExperimentOne( p, Gia_ObjChild0(pData), Gia_ObjChild0(pCare) );
+ }
+ Gia_ManSupStop( p );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c
index 5dac1fbc..bc2f0f67 100644
--- a/src/aig/gia/giaSwitch.c
+++ b/src/aig/gia/giaSwitch.c
@@ -19,6 +19,10 @@
***********************************************************************/
#include "giaAig.h"
+#include "main.h"
+
+ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -597,6 +601,13 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
{
Gia_ManForEachObj( pAig, pObj, i )
pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
+ Gia_ManForEachCo( pAig, pObj, i )
+ {
+ if ( Gia_ObjFaninC0(pObj) )
+ pSwitching[Gia_ObjId(pAig,pObj)] = (float)1.0-pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))];
+ else
+ pSwitching[Gia_ObjId(pAig,pObj)] = pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))];
+ }
}
else if ( pPars->fProbTrans )
{
@@ -608,6 +619,27 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
Gia_ManForEachObj( pAig, pObj, i )
pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
}
+/*
+ printf( "PI: " );
+ Gia_ManForEachPi( pAig, pObj, i )
+ printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] );
+ printf( "\n" );
+
+ printf( "LO: " );
+ Gia_ManForEachRo( pAig, pObj, i )
+ printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] );
+ printf( "\n" );
+
+ printf( "PO: " );
+ Gia_ManForEachPo( pAig, pObj, i )
+ printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] );
+ printf( "\n" );
+
+ printf( "LI: " );
+ Gia_ManForEachRi( pAig, pObj, i )
+ printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] );
+ printf( "\n" );
+*/
Gia_ManSwiDelete( p );
return vSwitching;
@@ -625,7 +657,6 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
***********************************************************************/
Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne )
{
- extern char * Abc_FrameReadFlag( char * pFlag );
Gia_ParSwi_t Pars, * pPars = &Pars;
Vec_Int_t * vSwitching, * vResult;
Gia_Man_t * p;
@@ -658,7 +689,11 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref
// transfer the computed result to the original AIG
vResult = Vec_IntStart( Aig_ManObjNumMax(pAig) );
Aig_ManForEachObj( pAig, pObj, i )
+ {
+// if ( Aig_ObjIsPo(pObj) )
+// printf( "%d=%f\n", i, Aig_Int2Float( Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ) );
Vec_IntWriteEntry( vResult, i, Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) );
+ }
// delete intermediate results
Vec_IntFree( vSwitching );
Gia_ManStop( p );
@@ -757,3 +792,5 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaTsim.c b/src/aig/gia/giaTsim.c
index a4cdf88a..e829ff5b 100644
--- a/src/aig/gia/giaTsim.c
+++ b/src/aig/gia/giaTsim.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -111,7 +114,7 @@ void Gia_ManTerStatesFree( Vec_Ptr_t * vStates )
{
unsigned * pTemp;
int i;
- Vec_PtrForEachEntry( vStates, pTemp, i )
+ Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i )
ABC_FREE( pTemp );
Vec_PtrFree( vStates );
}
@@ -505,12 +508,12 @@ void Gia_ManTerStatePrint( unsigned * pState, int nRegs, int iNum )
***********************************************************************/
void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs )
{
- unsigned * pTemp, * pStates = Vec_PtrPop( vStates );
+ unsigned * pTemp, * pStates = (unsigned *)Vec_PtrPop( vStates );
int i, w, nZeros, nConsts, nStateWords;
// detect constant zero registers
nStateWords = Gia_BitWordNum( 2*nRegs );
memset( pStates, 0, sizeof(int) * nStateWords );
- Vec_PtrForEachEntry( vStates, pTemp, i )
+ Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i )
for ( w = 0; w < nStateWords; w++ )
pStates[w] |= pTemp[w];
// count the number of zeros
@@ -521,7 +524,7 @@ void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs )
printf( "Found %d constant registers.\n", nZeros );
// detect non-ternary registers
memset( pStates, 0, sizeof(int) * nStateWords );
- Vec_PtrForEachEntry( vStates, pTemp, i )
+ Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i )
for ( w = 0; w < nStateWords; w++ )
pStates[w] |= (~(pTemp[w] ^ (pTemp[w] >> 1)) & 0x55555555);
// count the nonternary registers
@@ -585,7 +588,7 @@ Vec_Ptr_t * Gia_ManTerTranspose( Gia_ManTer_t * p )
continue;
pFlop = Gia_ManTerStateAlloc( nFlopWords );
Vec_PtrPush( vFlops, pFlop );
- Vec_PtrForEachEntry( p->vStates, pState, k )
+ Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k )
Gia_ManTerSimInfoSet( pFlop, k, Gia_ManTerSimInfoGet(pState, i) );
//Gia_ManTerStatePrint( pFlop, Vec_PtrSize(p->vStates), i );
}
@@ -607,8 +610,8 @@ int Gia_ManFindEqualFlop( Vec_Ptr_t * vFlops, int iFlop, int nFlopWords )
{
unsigned * pFlop, * pTemp;
int i;
- pFlop = Vec_PtrEntry( vFlops, iFlop );
- Vec_PtrForEachEntryStop( vFlops, pTemp, i, iFlop )
+ pFlop = (unsigned *)Vec_PtrEntry( vFlops, iFlop );
+ Vec_PtrForEachEntryStop( unsigned *, vFlops, pTemp, i, iFlop )
if ( !memcmp( pTemp, pFlop, sizeof(unsigned) * nFlopWords ) )
return i;
return -1;
@@ -633,7 +636,7 @@ int * Gia_ManTerCreateMap( Gia_ManTer_t * p, int fVerbose )
int i, iRepr, nFlopWords, Counter0 = 0, CounterE = 0;
nFlopWords = Gia_BitWordNum( 2*Vec_PtrSize(p->vStates) );
p->vFlops = Gia_ManTerTranspose( p );
- pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p->pAig) );
+ pCi2Lit = ABC_FALLOC( int, Gia_ManCiNum(p->pAig) );
vMapKtoI = Vec_IntAlloc( 100 );
for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
if ( p->pCount0[i] == Vec_PtrSize(p->vStates) )
@@ -678,8 +681,7 @@ Gia_ManTer_t * Gia_ManTerSimulate( Gia_Man_t * pAig, int fVerbose )
if ( 0 )
{
printf( "Obj = %8d (%8d). F = %6d. ",
- pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront,
- 4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20) );
+ pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront );
printf( "AIG = %7.2f Mb. F-mem = %7.2f Mb. Other = %7.2f Mb. ",
12.0*Gia_ManObjNum(p->pAig)/(1<<20),
4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20),
@@ -754,3 +756,5 @@ Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose )
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index 938c6363..002e766d 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -20,6 +20,9 @@
#include "gia.h"
+ABC_NAMESPACE_IMPL_START
+
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -72,7 +75,7 @@ void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int
{
unsigned * pInfo;
int i, w;
- Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart )
+ Vec_PtrForEachEntryStart( unsigned *, vInfo, pInfo, i, iInputStart )
for ( w = iWordStart; w < iWordStop; w++ )
pInfo[w] = Gia_ManRandom(0);
}
@@ -116,6 +119,30 @@ unsigned int Gia_PrimeCudd( unsigned int p )
/**Function*************************************************************
+ Synopsis [Returns the time stamp.]
+
+ Description [The file should be closed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Gia_TimeStamp()
+{
+ static char Buffer[100];
+ char * TimeStamp;
+ time_t ltime;
+ // get the current time
+ time( &ltime );
+ TimeStamp = asctime( localtime( &ltime ) );
+ TimeStamp[ strlen(TimeStamp) - 1 ] = 0;
+ strcpy( Buffer, TimeStamp );
+ return Buffer;
+}
+
+/**Function*************************************************************
+
Synopsis [Returns the composite name of the file.]
Description []
@@ -140,6 +167,34 @@ char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManIncrementTravId( Gia_Man_t * p )
+{
+ if ( p->pTravIds == NULL )
+ {
+ p->nTravIdsAlloc = Gia_ManObjNum(p) + 100;
+ p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc );
+ p->nTravIds = 0;
+ }
+ while ( p->nTravIdsAlloc < Gia_ManObjNum(p) )
+ {
+ p->nTravIdsAlloc *= 2;
+ p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc );
+ memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 );
+ }
+ p->nTravIds++;
+}
+
+/**Function*************************************************************
+
Synopsis [Sets phases of the internal nodes.]
Description []
@@ -290,6 +345,28 @@ void Gia_ManFillValue( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Sets the phase of one object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ObjSetPhase( Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsAnd(pObj) )
+ pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj));
+ else if ( Gia_ObjIsCo(pObj) )
+ pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj));
+ else
+ pObj->fPhase = 0;
+}
+
+/**Function*************************************************************
+
Synopsis [Sets phases of the internal nodes.]
Description []
@@ -304,15 +381,29 @@ void Gia_ManSetPhase( Gia_Man_t * p )
Gia_Obj_t * pObj;
int i;
Gia_ManForEachObj( p, pObj, i )
- {
- if ( Gia_ObjIsAnd(pObj) )
- pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) &
- (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj));
- else if ( Gia_ObjIsCo(pObj) )
- pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj));
- else
- pObj->fPhase = 0;
- }
+ Gia_ObjSetPhase( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets phases of the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSetPhase1( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->fPhase = 1;
+ Gia_ManForEachObj( p, pObj, i )
+ if ( !Gia_ObjIsCi(pObj) )
+ Gia_ObjSetPhase( pObj );
}
/**Function*************************************************************
@@ -336,6 +427,41 @@ void Gia_ManCleanPhase( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Prepares copies for the model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCleanLevels( Gia_Man_t * p, int Size )
+{
+ if ( p->vLevels == NULL )
+ p->vLevels = Vec_IntAlloc( Size );
+ Vec_IntFill( p->vLevels, Size, 0 );
+}
+/**Function*************************************************************
+
+ Synopsis [Prepares copies for the model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCleanTruth( Gia_Man_t * p )
+{
+ if ( p->vTruths == NULL )
+ p->vTruths = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Vec_IntFill( p->vTruths, Gia_ManObjNum(p), -1 );
+}
+
+/**Function*************************************************************
+
Synopsis [Assigns levels.]
Description []
@@ -349,24 +475,18 @@ int Gia_ManLevelNum( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i;
- if ( p->pLevels )
- return p->nLevels;
+ Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
p->nLevels = 0;
- p->pLevels = ABC_ALLOC( int, p->nObjsAlloc );
Gia_ManForEachObj( p, pObj, i )
if ( Gia_ObjIsAnd(pObj) )
+ Gia_ObjSetAndLevel( p, pObj );
+ else if ( Gia_ObjIsCo(pObj) )
{
- if ( p->pLevels[Gia_ObjFaninId0(pObj, i)] > p->pLevels[Gia_ObjFaninId1(pObj, i)] )
- p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId0(pObj, i)];
- else
- p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId1(pObj, i)];
- if ( p->nLevels < p->pLevels[i] )
- p->nLevels = p->pLevels[i];
+ Gia_ObjSetCoLevel( p, pObj );
+ p->nLevels = ABC_MAX( p->nLevels, Gia_ObjLevel(p, pObj) );
}
- else if ( Gia_ObjIsCo(pObj) )
- p->pLevels[i] = p->pLevels[Gia_ObjFaninId0(pObj, i)];
else
- p->pLevels[i] = 0;
+ Gia_ObjSetLevel( p, pObj, 0 );
return p->nLevels;
}
@@ -718,18 +838,93 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob
SeeAlso []
***********************************************************************/
-Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames )
+Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames )
{
- Gia_Cex_t * pCex;
+ Abc_Cex_t * pCex;
int nWords = Gia_BitWordNum( nRegs + nRealPis * nFrames );
- pCex = (Gia_Cex_t *)ABC_ALLOC( char, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords );
- memset( pCex, 0, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords );
+ pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords );
+ memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords );
pCex->nRegs = nRegs;
pCex->nPis = nRealPis;
pCex->nBits = nRegs + nRealPis * nFrames;
return pCex;
}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintCex( Abc_Cex_t * p )
+{
+ int i, f, k;
+ for ( k = 0; k < p->nRegs; k++ )
+ printf( "%d", Gia_InfoHasBit(p->pData, k) );
+ printf( "\n" );
+ for ( f = 0; f <= p->iFrame; f++ )
+ {
+ for ( i = 0; i < p->nPis; i++ )
+ printf( "%d", Gia_InfoHasBit(p->pData, k++) );
+ printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame )
+{
+ Abc_Cex_t * pCex;
+ int i;
+ pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 );
+ assert( Vec_IntSize(vValues) == nSkip + pCex->nBits );
+ pCex->iPo = 0;
+ pCex->iFrame = iFrame;
+ for ( i = 0; i < pCex->nBits; i++ )
+ if ( Vec_IntEntry(vValues, nSkip + i) )
+ Gia_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel )
+{
+ Abc_Cex_t * pCex;
+ int i;
+ pCex = Gia_ManAllocCounterExample( nRegs, nRealPis, 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = 0;
+ for ( i = pCex->nRegs; i < pCex->nBits; i++ )
+ if ( pModel[i-pCex->nRegs] )
+ Gia_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+
/**Function*************************************************************
Synopsis [Resimulates the counter-example.]
@@ -741,10 +936,11 @@ Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames )
SeeAlso []
***********************************************************************/
-int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut )
+int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut )
{
Gia_Obj_t * pObj, * pObjRi, * pObjRo;
int RetValue, i, k, iBit = 0;
+ Gia_ManCleanMark0(pAig);
Gia_ManForEachRo( pAig, pObj, i )
pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++);
for ( i = 0; i <= p->iFrame; i++ )
@@ -770,6 +966,73 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut )
/**Function*************************************************************
+ Synopsis [Resimulates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManVerifyCounterExampleAllOuts( Gia_Man_t * pAig, Abc_Cex_t * p )
+{
+ Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+ int RetValue, i, k, iBit = 0;
+ Gia_ManCleanMark0(pAig);
+ Gia_ManForEachRo( pAig, pObj, i )
+ pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++);
+ for ( i = 0; i <= p->iFrame; i++ )
+ {
+ Gia_ManForEachPi( pAig, pObj, k )
+ pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++);
+ Gia_ManForEachAnd( pAig, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) &
+ (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( pAig, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+ Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k )
+ pObjRo->fMark0 = pObjRi->fMark0;
+ }
+ assert( iBit == p->nBits );
+ // remember the number of failed output
+ RetValue = -1;
+ Gia_ManForEachPo( pAig, pObj, i )
+ if ( Gia_ManPo(pAig, i)->fMark0 )
+ {
+ RetValue = i;
+ break;
+ }
+ Gia_ManCleanMark0(pAig);
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Make the trivial counter-example for the trivially asserted output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew )
+{
+ Abc_Cex_t * pCex;
+ int i;
+ pCex = Gia_ManAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 );
+ pCex->iPo = p->iPo;
+ pCex->iFrame = p->iFrame;
+ for ( i = p->nRegs; i < p->nBits; i++ )
+ if ( Gia_InfoHasBit(p->pData, i) )
+ Gia_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs );
+ return pCex;
+}
+
+/**Function*************************************************************
+
Synopsis [Prints out the counter-example.]
Description []
@@ -779,7 +1042,7 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut )
SeeAlso []
***********************************************************************/
-void Gia_ManPrintCounterExample( Gia_Cex_t * p )
+void Gia_ManPrintCounterExample( Abc_Cex_t * p )
{
int i, f, k;
printf( "Counter-example: iPo = %d iFrame = %d nRegs = %d nPis = %d nBits = %d\n",
@@ -979,7 +1242,7 @@ int Gia_ManHasChoices( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManHasDandling( Gia_Man_t * p )
+int Gia_ManHasDangling( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i, Counter = 0;
@@ -1000,8 +1263,115 @@ int Gia_ManHasDandling( Gia_Man_t * p )
return Counter;
}
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if AIG has dangling nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p )
+{
+ Vec_Int_t * vDangles;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ pObj->fMark0 = 0;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ }
+ vDangles = Vec_IntAlloc( 100 );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( !pObj->fMark0 )
+ Vec_IntPush( vDangles, i );
+ Gia_ManCleanMark0( p );
+ return vDangles;
+}
+/**Function*************************************************************
+
+ Synopsis [Verbose printing of the AIG node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( pObj == NULL )
+ {
+ printf( "Object is NULL." );
+ return;
+ }
+ if ( Gia_IsComplement(pObj) )
+ {
+ printf( "Compl " );
+ pObj = Gia_Not(pObj);
+ }
+ assert( !Gia_IsComplement(pObj) );
+ printf( "Node %4d : ", Gia_ObjId(p, pObj) );
+ if ( Gia_ObjIsConst0(pObj) )
+ printf( "constant 0" );
+ else if ( Gia_ObjIsPi(p, pObj) )
+ printf( "PI" );
+ else if ( Gia_ObjIsPo(p, pObj) )
+ printf( "PO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") );
+ else if ( Gia_ObjIsCi(pObj) )
+ printf( "RI" );
+ else if ( Gia_ObjIsCo(pObj) )
+ printf( "RO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") );
+// else if ( Gia_ObjIsBuf(pObj) )
+// printf( "BUF( %d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") );
+ else
+ printf( "AND( %4d%s, %4d%s )",
+ Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " "),
+ Gia_ObjFaninId1p(p, pObj), (Gia_ObjFaninC1(pObj)? "\'" : " ") );
+ if ( p->pRefs )
+ printf( " (refs = %3d)", Gia_ObjRefs(p, pObj) );
+ printf( "\n" );
+/*
+ if ( p->pRefs )
+ {
+ Gia_Obj_t * pFanout;
+ int i;
+ int iFan = -1; // Suppress "might be used uninitialized"
+ printf( "\nFanouts:\n" );
+ Gia_ObjForEachFanout( p, pObj, pFanout, iFan, i )
+ {
+ printf( " " );
+ printf( "Node %4d : ", Gia_ObjId(pFanout) );
+ if ( Gia_ObjIsPo(pFanout) )
+ printf( "PO( %4d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") );
+ else if ( Gia_ObjIsBuf(pFanout) )
+ printf( "BUF( %d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") );
+ else
+ printf( "AND( %4d%s, %4d%s )",
+ Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " "),
+ Gia_ObjFanin1(pFanout)->Id, (Gia_ObjFaninC1(pFanout)? "\'" : " ") );
+ printf( "\n" );
+ }
+ return;
+ }
+*/
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 0245b0f1..fc1c5c73 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -2,6 +2,7 @@ SRC += src/aig/gia/gia.c \
src/aig/gia/giaAbs.c \
src/aig/gia/giaAig.c \
src/aig/gia/giaAiger.c \
+ src/aig/gia/giaBidec.c \
src/aig/gia/giaCof.c \
src/aig/gia/giaCSatOld.c \
src/aig/gia/giaCSat.c \
@@ -19,13 +20,18 @@ SRC += src/aig/gia/gia.c \
src/aig/gia/giaFront.c \
src/aig/gia/giaGlitch.c \
src/aig/gia/giaHash.c \
+ src/aig/gia/giaIf.c \
src/aig/gia/giaMan.c \
- src/aig/gia/giaMap.c \
+ src/aig/gia/giaMem.c \
src/aig/gia/giaPat.c \
+ src/aig/gia/giaReparam.c \
src/aig/gia/giaRetime.c \
src/aig/gia/giaScl.c \
+ src/aig/gia/giaShrink.c \
src/aig/gia/giaSim.c \
src/aig/gia/giaSort.c \
+ src/aig/gia/giaSpeedup.c \
+ src/aig/gia/giaSupMin.c \
src/aig/gia/giaSwitch.c \
src/aig/gia/giaTsim.c \
src/aig/gia/giaUtil.c