summaryrefslogtreecommitdiffstats
path: root/src/aig/gia/giaEra2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia/giaEra2.c')
-rw-r--r--src/aig/gia/giaEra2.c1954
1 files changed, 1954 insertions, 0 deletions
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
+